diff --git a/Modules/Bundles/org.mitk.diffusionimaging/src/internal/mitkDiffusionImagingActivator.cpp b/Modules/Bundles/org.mitk.diffusionimaging/src/internal/mitkDiffusionImagingActivator.cpp index 46cc665a87..c07be3af1f 100644 --- a/Modules/Bundles/org.mitk.diffusionimaging/src/internal/mitkDiffusionImagingActivator.cpp +++ b/Modules/Bundles/org.mitk.diffusionimaging/src/internal/mitkDiffusionImagingActivator.cpp @@ -1,57 +1,60 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2009-07-14 19:11:20 +0200 (Tue, 14 Jul 2009) $ Version: $Revision: 18127 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkDiffusionImagingActivator.h" #include "mitkDiffusionImagingObjectFactory.h" #include "QmitkNodeDescriptorManager.h" #include "mitkNodePredicateDataType.h" #include void mitk::DiffusionImagingActivator::start(ctkPluginContext* context) { Q_UNUSED(context) RegisterDiffusionImagingObjectFactory(); QmitkNodeDescriptorManager* manager = QmitkNodeDescriptorManager::GetInstance(); mitk::NodePredicateDataType::Pointer isDiffusionImage = mitk::NodePredicateDataType::New("DiffusionImage"); QmitkNodeDescriptor* desc = new QmitkNodeDescriptor(QObject::tr("DiffusionImage"), QString(":/QmitkDiffusionImaging/QBallData24.png"), isDiffusionImage, manager); manager->AddDescriptor(desc); mitk::NodePredicateDataType::Pointer isTensorImage = mitk::NodePredicateDataType::New("TensorImage"); manager->AddDescriptor(new QmitkNodeDescriptor(QObject::tr("TensorImage"), QString(":/QmitkDiffusionImaging/recontensor.png"), isTensorImage, manager)); mitk::NodePredicateDataType::Pointer isQBallImage = mitk::NodePredicateDataType::New("QBallImage"); manager->AddDescriptor(new QmitkNodeDescriptor(QObject::tr("QBallImage"), QString(":/QmitkDiffusionImaging/reconodf.png"), isQBallImage, manager)); mitk::NodePredicateDataType::Pointer isFiberBundle = mitk::NodePredicateDataType::New("FiberBundle"); manager->AddDescriptor(new QmitkNodeDescriptor(QObject::tr("FiberBundle"), QString(":/QmitkDiffusionImaging/FiberBundle.png"), isFiberBundle, manager)); + + mitk::NodePredicateDataType::Pointer isFiberBundleX = mitk::NodePredicateDataType::New("FiberBundleX"); + manager->AddDescriptor(new QmitkNodeDescriptor(QObject::tr("FiberBundleX"), QString(":/QmitkDiffusionImaging/FiberBundleX.png"), isFiberBundleX, manager)); } void mitk::DiffusionImagingActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) } Q_EXPORT_PLUGIN2(org_mitk_diffusionimaging, mitk::DiffusionImagingActivator) diff --git a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/resources/FiberBundleX.png b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/resources/FiberBundleX.png new file mode 100644 index 0000000000..378292a1a0 Binary files /dev/null and b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/resources/FiberBundleX.png differ diff --git a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberBundleDeveloperView.cpp b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberBundleDeveloperView.cpp index b6dc8c13b4..1120296166 100644 --- a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberBundleDeveloperView.cpp +++ b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberBundleDeveloperView.cpp @@ -1,1239 +1,1277 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2010-03-31 16:40:27 +0200 (Mi, 31 Mrz 2010) $ Version: $Revision: 21975 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ //=========FOR TESTING========== //random generation, number of points equal requested points // Blueberry application and interaction service #include #include // Qmitk #include "QmitkFiberBundleDeveloperView.h" #include // Qt #include // MITK //===needed when timeSlicedGeometry is null to invoke rendering mechansims ==== #include #include // VTK #include //for randomized FiberStructure #include //for fiberStructure #include //for fiberStructure #include //for geometry //ITK #include //============================================== //======== W O R K E R S ____ S T A R T ======== //============================================== /*=================================================================================== * THIS METHOD IMPLEMENTS THE ACTIONS WHICH SHALL BE EXECUTED by the according THREAD * --generate FiberIDs--*/ QmitkFiberIDWorker::QmitkFiberIDWorker(QThread* hostingThread, Package4WorkingThread itemPackage) : m_itemPackage(itemPackage), m_hostingThread(hostingThread) { } void QmitkFiberIDWorker::run() { if(m_itemPackage.st_Controls->checkBoxMonitorFiberThreads->isChecked()) m_itemPackage.st_fiberThreadMonitorWorker->setThreadStatus(FBX_STATUS_RUNNING); /* MEASUREMENTS AND FANCY GUI EFFECTS * accurate time measurement using ITK timeProbe*/ itk::TimeProbe clock; clock.Start(); //set GUI representation of timer to 0, is essential for correct timer incrementation m_itemPackage.st_Controls->infoTimerGenerateFiberIds->setText(QString::number(0)); m_itemPackage.st_FancyGUITimer1->start(); //do processing m_itemPackage.st_FBX->DoGenerateFiberIds(); /* MEASUREMENTS AND FANCY GUI EFFECTS CLEANUP */ clock.Stop(); m_itemPackage.st_FancyGUITimer1->stop(); m_itemPackage.st_Controls->infoTimerGenerateFiberIds->setText( QString::number(clock.GetTotal()) ); delete m_itemPackage.st_FancyGUITimer1; // fancy timer is not needed anymore m_hostingThread->quit(); } /*=================================================================================== * THIS METHOD IMPLEMENTS THE ACTIONS WHICH SHALL BE EXECUTED by the according THREAD * --generate random fibers--*/ QmitkFiberGenerateRandomWorker::QmitkFiberGenerateRandomWorker(QThread* hostingThread, Package4WorkingThread itemPackage) : m_itemPackage(itemPackage), m_hostingThread(hostingThread) { } void QmitkFiberGenerateRandomWorker::run() { if(m_itemPackage.st_Controls->checkBoxMonitorFiberThreads->isChecked()) m_itemPackage.st_fiberThreadMonitorWorker->setThreadStatus(FBX_STATUS_RUNNING); /* MEASUREMENTS AND FANCY GUI EFFECTS */ m_itemPackage.st_Controls->infoTimerGenerateFiberBundle->setText(QString::number(0)); m_itemPackage.st_FancyGUITimer1->start(); //do processing, generateRandomFibers int numOfFibers = m_itemPackage.st_Controls->boxFiberNumbers->value(); int distrRadius = m_itemPackage.st_Controls->boxDistributionRadius->value(); int numOfPoints = numOfFibers * distrRadius; std::vector< std::vector > fiberStorage; for (int i=0; i a; fiberStorage.push_back( a ); } /* Generate Point Cloud */ vtkSmartPointer randomPoints = vtkSmartPointer::New(); randomPoints->SetCenter(0.0, 0.0, 0.0); randomPoints->SetNumberOfPoints(numOfPoints); randomPoints->SetRadius(distrRadius); randomPoints->Update(); vtkPoints* pnts = randomPoints->GetOutput()->GetPoints(); /* ASSIGN EACH POINT TO A RANDOM FIBER */ srand((unsigned)time(0)); // init randomizer for (int i=0; iGetNumberOfPoints(); ++i) { //generate random number between 0 and numOfFibers-1 int random_integer; random_integer = (rand()%numOfFibers); //add current point to random fiber fiberStorage.at(random_integer).push_back(i); // MITK_INFO << "point" << i << " |" << pnts->GetPoint(random_integer)[0] << "|" << pnts->GetPoint(random_integer)[1]<< "|" << pnts->GetPoint(random_integer)[2] << "| into fiber" << random_integer; } // initialize accurate time measurement itk::TimeProbe clock; clock.Start(); /* GENERATE VTK POLYLINES OUT OF FIBERSTORAGE */ vtkSmartPointer linesCell = vtkSmartPointer::New(); // Host vtkPolyLines linesCell->Allocate(pnts->GetNumberOfPoints()*2); //allocate for each cellindex also space for the pointId, e.g. [idx | pntID] for (unsigned long i=0; i singleFiber = fiberStorage.at(i); vtkSmartPointer fiber = vtkSmartPointer::New(); fiber->GetPointIds()->SetNumberOfIds((int)singleFiber.size()); for (unsigned long si=0; siGetPointIds()->SetId( si, singleFiber.at(si) ); } linesCell->InsertNextCell(fiber); } /* checkpoint for cellarray allocation */ if ( (linesCell->GetSize()/pnts->GetNumberOfPoints()) != 2 ) //e.g. size: 12, number of points:6 .... each cell hosts point ids (6 ids) + cell index for each idPoint. 6 * 2 = 12 { MITK_INFO << "RANDOM FIBER ALLOCATION CAN NOT BE TRUSTED ANYMORE! Correct leak or remove command: linesCell->Allocate(pnts->GetNumberOfPoints()*2) but be aware of possible loss in performance."; } /* HOSTING POLYDATA FOR RANDOM FIBERSTRUCTURE */ vtkPolyData* PDRandom = vtkPolyData::New(); //no need to delete because data is needed in datastorage. PDRandom->SetPoints(pnts); PDRandom->SetLines(linesCell); // accurate timer measurement stop clock.Stop(); //MITK_INFO << "=====Assambling random Fibers to Polydata======\nMean: " << clock.GetMean() << " Total: " << clock.GetTotal() << std::endl; // call function to convert fiberstructure into fiberbundleX and pass it to datastorage (m_itemPackage.st_host->*m_itemPackage.st_pntr_to_Method_PutFibersToDataStorage)(PDRandom); /* MEASUREMENTS AND FANCY GUI EFFECTS CLEANUP */ m_itemPackage.st_FancyGUITimer1->stop(); m_itemPackage.st_Controls->infoTimerGenerateFiberBundle->setText( QString::number(clock.GetTotal()) ); delete m_itemPackage.st_FancyGUITimer1; // fancy timer is not needed anymore m_hostingThread->quit(); } /*=================================================================================== * THIS METHOD IMPLEMENTS THE ACTIONS WHICH SHALL BE EXECUTED by the according THREAD * --update GUI elements of thread monitor-- * implementation not thread safe, not needed so far because * there exists only 1 thread for fiberprocessing * for threadsafety, you need to implement checking mechanisms in methods "::threadFor...." */ QmitkFiberThreadMonitorWorker::QmitkFiberThreadMonitorWorker( QThread* hostingThread, Package4WorkingThread itemPackage ) : m_itemPackage(itemPackage) , m_hostingThread(hostingThread) , m_pixelstepper(10) //for next rendering call, move object 10px , m_steppingDistance(220) //use only a multiple value of pixelstepper, x-axis border for fancy stuff { //set timers m_thtimer_initMonitor = new QTimer; m_thtimer_initMonitor->setInterval(10); m_thtimer_initMonitorSetFinalPosition = new QTimer; m_thtimer_initMonitorSetFinalPosition->setInterval(10); m_thtimer_initMonitorSetMasks = new QTimer; m_thtimer_initMonitorSetFinalPosition->setInterval(10); m_thtimer_threadStarted = new QTimer; m_thtimer_threadStarted->setInterval(50); m_thtimer_threadFinished = new QTimer; m_thtimer_threadFinished->setInterval(50); m_thtimer_threadTerminated = new QTimer; m_thtimer_threadTerminated->setInterval(50); connect (m_thtimer_initMonitor, SIGNAL( timeout()), this, SLOT( fancyMonitorInitialization() ) ); connect ( m_thtimer_initMonitorSetFinalPosition, SIGNAL( timeout() ), this, SLOT( fancyMonitorInitializationFinalPos() ) ); connect ( m_thtimer_initMonitorSetMasks, SIGNAL( timeout() ), this, SLOT( fancyMonitorInitializationMask() ) ); connect (m_thtimer_threadStarted, SIGNAL( timeout()), this, SLOT( fancyTextFading_threadStarted() ) ); connect (m_thtimer_threadFinished, SIGNAL( timeout()), this, SLOT( fancyTextFading_threadFinished() ) ); connect (m_thtimer_threadTerminated, SIGNAL( timeout()), this, SLOT( fancyTextFading_threadTerminated() ) ); //first, the current text shall turn transparent m_decreaseOpacity_threadStarted = true; m_decreaseOpacity_threadFinished = true; m_decreaseOpacity_threadTerminated = true; } void QmitkFiberThreadMonitorWorker::run() { } void QmitkFiberThreadMonitorWorker::initializeMonitor() { //fancy configuration of animation start mitk::Point2D pntOpen; pntOpen[0] = 118; pntOpen[1] = 10; mitk::Point2D headPos; headPos[0] = 19; headPos[1] = 10; mitk::Point2D statusPos; statusPos[0] = 105; statusPos[1] = 23; mitk::Point2D startedPos; startedPos[0] = 68; startedPos[1] = 10; mitk::Point2D finishedPos; finishedPos[0] = 143; finishedPos[1] = 10; mitk::Point2D terminatedPos; terminatedPos[0] = 240; terminatedPos[1] = 10; m_itemPackage.st_FBX_Monitor->setBracketClosePosition(pntOpen); m_itemPackage.st_FBX_Monitor->setBracketOpenPosition(pntOpen); m_itemPackage.st_FBX_Monitor->setHeadingPosition(headPos); m_itemPackage.st_FBX_Monitor->setMaskPosition(headPos); m_itemPackage.st_FBX_Monitor->setStatusPosition(statusPos); m_itemPackage.st_FBX_Monitor->setStartedPosition(startedPos); m_itemPackage.st_FBX_Monitor->setFinishedPosition(finishedPos); m_itemPackage.st_FBX_Monitor->setTerminatedPosition(terminatedPos); m_thtimer_initMonitor->start(); } void QmitkFiberThreadMonitorWorker::setThreadStatus(QString status) { m_itemPackage.st_FBX_Monitor->setStatus(status); m_itemPackage.st_ThreadMonitorDataNode->Modified(); m_itemPackage.st_MultiWidget->RequestUpdate(); } void QmitkFiberThreadMonitorWorker::threadForFiberProcessingStarted() { if(!m_thtimer_threadStarted->isActive()) { m_thtimer_threadStarted->start(); } else { - //fast change without fancy stuff + //fast change without fancy stuff, needed to keep threaddebugger info up to date int counter = m_itemPackage.st_FBX_Monitor->getStarted(); m_itemPackage.st_FBX_Monitor->setStarted(++counter); } } void QmitkFiberThreadMonitorWorker::threadForFiberProcessingFinished() { if(!m_thtimer_threadFinished->isActive()) { m_thtimer_threadFinished->start(); } else { //fast change without fancy stuff int counter = m_itemPackage.st_FBX_Monitor->getFinished(); m_itemPackage.st_FBX_Monitor->setFinished(++counter); } } void QmitkFiberThreadMonitorWorker::threadForFiberProcessingTerminated() { if(!m_thtimer_threadTerminated->isActive()) { m_thtimer_threadTerminated->start(); } else { //fast change without fancy stuff int counter = m_itemPackage.st_FBX_Monitor->getTerminated(); m_itemPackage.st_FBX_Monitor->setTerminated(++counter); } } void QmitkFiberThreadMonitorWorker::fancyTextFading_threadStarted() { if (m_decreaseOpacity_threadStarted) { int startedOpacity = m_itemPackage.st_FBX_Monitor->getStartedOpacity(); m_itemPackage.st_FBX_Monitor->setStartedOpacity( --startedOpacity ); if (startedOpacity == 0) { int counter = m_itemPackage.st_FBX_Monitor->getStarted(); m_itemPackage.st_FBX_Monitor->setStarted(++counter); m_decreaseOpacity_threadStarted = false; } m_itemPackage.st_ThreadMonitorDataNode->Modified(); m_itemPackage.st_MultiWidget->RequestUpdate(); } else { int startedOpacity = m_itemPackage.st_FBX_Monitor->getStartedOpacity(); m_itemPackage.st_FBX_Monitor->setStartedOpacity( ++startedOpacity ); if (startedOpacity >= 10) { m_thtimer_threadStarted->stop(); m_decreaseOpacity_threadStarted = true; //set back to true, cuz next iteration shall decrease opacity as well } m_itemPackage.st_ThreadMonitorDataNode->Modified(); m_itemPackage.st_MultiWidget->RequestUpdate(); } } void QmitkFiberThreadMonitorWorker::fancyTextFading_threadFinished() { if (m_decreaseOpacity_threadFinished) { int finishedOpacity = m_itemPackage.st_FBX_Monitor->getFinishedOpacity(); m_itemPackage.st_FBX_Monitor->setFinishedOpacity( --finishedOpacity ); if (finishedOpacity == 0) { int counter = m_itemPackage.st_FBX_Monitor->getFinished(); m_itemPackage.st_FBX_Monitor->setFinished(++counter); m_decreaseOpacity_threadFinished = false; } m_itemPackage.st_ThreadMonitorDataNode->Modified(); m_itemPackage.st_MultiWidget->RequestUpdate(); } else { int finishedOpacity = m_itemPackage.st_FBX_Monitor->getFinishedOpacity(); m_itemPackage.st_FBX_Monitor->setFinishedOpacity( ++finishedOpacity ); if (finishedOpacity >= 10) { m_thtimer_threadFinished->stop(); m_decreaseOpacity_threadFinished = true; //set back to true, cuz next iteration shall decrease opacity as well } m_itemPackage.st_ThreadMonitorDataNode->Modified(); m_itemPackage.st_MultiWidget->RequestUpdate(); } } void QmitkFiberThreadMonitorWorker::fancyTextFading_threadTerminated() { if (m_decreaseOpacity_threadTerminated) { int terminatedOpacity = m_itemPackage.st_FBX_Monitor->getTerminatedOpacity(); m_itemPackage.st_FBX_Monitor->setTerminatedOpacity( --terminatedOpacity ); if (terminatedOpacity == 0) { int counter = m_itemPackage.st_FBX_Monitor->getTerminated(); m_itemPackage.st_FBX_Monitor->setTerminated(++counter); m_decreaseOpacity_threadTerminated = false; } m_itemPackage.st_ThreadMonitorDataNode->Modified(); m_itemPackage.st_MultiWidget->RequestUpdate(); } else { int terminatedOpacity = m_itemPackage.st_FBX_Monitor->getTerminatedOpacity(); m_itemPackage.st_FBX_Monitor->setTerminatedOpacity( ++terminatedOpacity ); if (terminatedOpacity >= 10) { m_thtimer_threadTerminated->stop(); m_decreaseOpacity_threadTerminated = true; //set back to true, cuz next iteration shall decrease opacity as well } m_itemPackage.st_ThreadMonitorDataNode->Modified(); m_itemPackage.st_MultiWidget->RequestUpdate(); } } void QmitkFiberThreadMonitorWorker::fancyMonitorInitialization() { mitk::Point2D pntClose = m_itemPackage.st_FBX_Monitor->getBracketClosePosition(); //possible bottleneck, set pntClose to member mitk::Point2D pntOpen = m_itemPackage.st_FBX_Monitor->getBracketOpenPosition(); //possible bottleneck, set pntClose to member pntClose[0] += m_pixelstepper; pntOpen[0] -= m_pixelstepper; //MITK_INFO << pntClose[0] << " " << pntOpen[0]; m_itemPackage.st_FBX_Monitor->setBracketClosePosition(pntClose); m_itemPackage.st_FBX_Monitor->setBracketOpenPosition(pntOpen); int opacity = m_itemPackage.st_FBX_Monitor->getHeadingOpacity() + 1; if (opacity > 10) opacity = 10; m_itemPackage.st_FBX_Monitor->setHeadingOpacity(opacity); if (pntClose[0] >= m_steppingDistance) { if (m_itemPackage.st_FBX_Monitor->getHeadingOpacity() != 10 ) { m_itemPackage.st_FBX_Monitor->setHeadingOpacity(10); m_itemPackage.st_ThreadMonitorDataNode->Modified(); m_itemPackage.st_MultiWidget->RequestUpdate(); } m_thtimer_initMonitor->stop(); //position them to obt y=25 m_thtimer_initMonitorSetFinalPosition->start(); } m_itemPackage.st_ThreadMonitorDataNode->Modified(); m_itemPackage.st_MultiWidget->RequestUpdate(); } void QmitkFiberThreadMonitorWorker::fancyMonitorInitializationFinalPos() { //get y pos of mitk::Point2D pntClose = m_itemPackage.st_FBX_Monitor->getBracketClosePosition(); mitk::Point2D pntOpen = m_itemPackage.st_FBX_Monitor->getBracketOpenPosition(); mitk::Point2D pntHead = m_itemPackage.st_FBX_Monitor->getHeadingPosition(); pntClose[1] += 5; pntOpen[1] += 5; pntHead[1] += 5; m_itemPackage.st_FBX_Monitor->setBracketClosePosition(pntClose); m_itemPackage.st_FBX_Monitor->setBracketOpenPosition(pntOpen); m_itemPackage.st_FBX_Monitor->setHeadingPosition(pntHead); if (pntClose[1] >= 35) { //35 = y position m_thtimer_initMonitorSetFinalPosition->stop(); //now init mask of labels m_thtimer_initMonitorSetMasks->start(); } m_itemPackage.st_ThreadMonitorDataNode->Modified(); m_itemPackage.st_MultiWidget->RequestUpdate(); } void QmitkFiberThreadMonitorWorker::fancyMonitorInitializationMask() { //increase opacity int opacity = m_itemPackage.st_FBX_Monitor->getMaskOpacity(); opacity++; m_itemPackage.st_FBX_Monitor->setMaskOpacity(opacity); m_itemPackage.st_FBX_Monitor->setStartedOpacity(opacity); m_itemPackage.st_FBX_Monitor->setFinishedOpacity(opacity); m_itemPackage.st_FBX_Monitor->setTerminatedOpacity(opacity); m_itemPackage.st_FBX_Monitor->setStatusOpacity(opacity); if (opacity >=10) { m_thtimer_initMonitorSetMasks->stop(); } m_itemPackage.st_ThreadMonitorDataNode->Modified(); m_itemPackage.st_MultiWidget->RequestUpdate(); } //============================================== //======== W O R K E R S ________ E N D ======== //============================================== // ========= HERE STARTS THE ACTUAL FIBERB2UNDLE DEVELOPER VIEW IMPLEMENTATION ====== const std::string QmitkFiberBundleDeveloperView::VIEW_ID = "org.mitk.views.fiberbundledeveloper"; const std::string id_DataManager = "org.mitk.views.datamanager"; using namespace berry; QmitkFiberBundleDeveloperView::QmitkFiberBundleDeveloperView() : QmitkFunctionality() , m_Controls( 0 ) , m_MultiWidget( NULL ) , m_FiberIDGenerator( NULL) , m_GeneratorFibersRandom( NULL ) , m_fiberMonitorIsOn( false ) { m_hostThread = new QThread; m_threadInProgress = false; } // Destructor QmitkFiberBundleDeveloperView::~QmitkFiberBundleDeveloperView() { //m_FiberBundleX->Delete(); using weakPointer, therefore no delete necessary delete m_hostThread; if (m_FiberIDGenerator != NULL) delete m_FiberIDGenerator; if (m_GeneratorFibersRandom != NULL) delete m_GeneratorFibersRandom; } void QmitkFiberBundleDeveloperView::CreateQtPartControl( QWidget *parent ) { // build up qt view, unless already done in QtDesigner, etc. if ( !m_Controls ) { // create GUI widgets from the Qt Designer's .ui file m_Controls = new Ui::QmitkFiberBundleDeveloperViewControls; m_Controls->setupUi( parent ); /*=========INITIALIZE BUTTON CONFIGURATION ================*/ m_Controls->radioButton_directionX->setEnabled(false); m_Controls->radioButton_directionY->setEnabled(false); m_Controls->radioButton_directionZ->setEnabled(false); m_Controls->buttonGenerateFiberIds->setEnabled(false); m_Controls->buttonGenerateFibers->setEnabled(true); + m_Controls->buttonColorFibers->setEnabled(false); - m_Controls->buttonColorFibers->setEnabled(false);//not yet implemented m_Controls->buttonSMFibers->setEnabled(false);//not yet implemented m_Controls->buttonVtkDecimatePro->setEnabled(false);//not yet implemented m_Controls->buttonVtkSmoothPD->setEnabled(false);//not yet implemented m_Controls->buttonGenerateTubes->setEnabled(false);//not yet implemented connect( m_Controls->buttonGenerateFibers, SIGNAL(clicked()), this, SLOT(DoGenerateFibers()) ); connect( m_Controls->buttonGenerateFiberIds, SIGNAL(pressed()), this, SLOT(DoGenerateFiberIDs()) ); connect( m_Controls->radioButton_directionRandom, SIGNAL(clicked()), this, SLOT(DoUpdateGenerateFibersWidget()) ); connect( m_Controls->radioButton_directionX, SIGNAL(clicked()), this, SLOT(DoUpdateGenerateFibersWidget()) ); connect( m_Controls->radioButton_directionY, SIGNAL(clicked()), this, SLOT(DoUpdateGenerateFibersWidget()) ); connect( m_Controls->radioButton_directionZ, SIGNAL(clicked()), this, SLOT(DoUpdateGenerateFibersWidget()) ); connect( m_Controls->toolBox, SIGNAL(currentChanged ( int ) ), this, SLOT(SelectionChangedToolBox(int)) ); + connect( m_Controls->tabWidget, SIGNAL(currentChanged ( int ) ), this, SLOT(SelectionChangedToolBox(int)) ); //needed to update GUI elements when tab selection of fiberProcessing page changes + + connect( m_Controls->buttonColorFibers, SIGNAL(clicked()), this, SLOT(DoColorFibers()) ); connect( m_Controls->checkBoxMonitorFiberThreads, SIGNAL(stateChanged(int)), this, SLOT(DoMonitorFiberThreads(int)) ); } // Checkpoint for fiber ORIENTATION if ( m_DirectionRadios.empty() ) { m_DirectionRadios.insert(0, m_Controls->radioButton_directionRandom); m_DirectionRadios.insert(1, m_Controls->radioButton_directionX); m_DirectionRadios.insert(2, m_Controls->radioButton_directionY); m_DirectionRadios.insert(3, m_Controls->radioButton_directionZ); } // set GUI elements of FiberGenerator to according configuration DoUpdateGenerateFibersWidget(); } /* THIS METHOD UPDATES ALL GUI ELEMENTS OF QGroupBox DEPENDING ON CURRENTLY SELECTED * RADIO BUTTONS */ void QmitkFiberBundleDeveloperView::DoUpdateGenerateFibersWidget() { //get selected radioButton QString fibDirection; //stores the object_name of selected radiobutton QVector::const_iterator i; for (i = m_DirectionRadios.begin(); i != m_DirectionRadios.end(); ++i) { QRadioButton* rdbtn = *i; if (rdbtn->isChecked()) fibDirection = rdbtn->objectName(); } if ( fibDirection == FIB_RADIOBUTTON_DIRECTION_RANDOM ) { // disable radiobuttons if (m_Controls->boxFiberMinLength->isEnabled()) m_Controls->boxFiberMinLength->setEnabled(false); if (m_Controls->labelFiberMinLength->isEnabled()) m_Controls->labelFiberMinLength->setEnabled(false); if (m_Controls->boxFiberMaxLength->isEnabled()) m_Controls->boxFiberMaxLength->setEnabled(false); if (m_Controls->labelFiberMaxLength->isEnabled()) m_Controls->labelFiberMaxLength->setEnabled(false); //enable radiobuttons if (!m_Controls->labelFibersTotal->isEnabled()) m_Controls->labelFibersTotal->setEnabled(true); if (!m_Controls->boxFiberNumbers->isEnabled()) m_Controls->boxFiberNumbers->setEnabled(true); if (!m_Controls->labelDistrRadius->isEnabled()) m_Controls->labelDistrRadius->setEnabled(true); if (!m_Controls->boxDistributionRadius->isEnabled()) m_Controls->boxDistributionRadius->setEnabled(true); } else { // disable radiobuttons if (m_Controls->labelDistrRadius->isEnabled()) m_Controls->labelDistrRadius->setEnabled(false); if (m_Controls->boxDistributionRadius->isEnabled()) m_Controls->boxDistributionRadius->setEnabled(false); //enable radiobuttons if (!m_Controls->labelFibersTotal->isEnabled()) m_Controls->labelFibersTotal->setEnabled(true); if (!m_Controls->boxFiberNumbers->isEnabled()) m_Controls->boxFiberNumbers->setEnabled(true); if (!m_Controls->boxFiberMinLength->isEnabled()) m_Controls->boxFiberMinLength->setEnabled(true); if (!m_Controls->labelFiberMinLength->isEnabled()) m_Controls->labelFiberMinLength->setEnabled(true); if (!m_Controls->boxFiberMaxLength->isEnabled()) m_Controls->boxFiberMaxLength->setEnabled(true); if (!m_Controls->labelFiberMaxLength->isEnabled()) m_Controls->labelFiberMaxLength->setEnabled(true); } } void QmitkFiberBundleDeveloperView::DoGenerateFibers() { // GET SELECTED FIBER DIRECTION QString fibDirection; //stores the object_name of selected radiobutton QVector::const_iterator i; for (i = m_DirectionRadios.begin(); i != m_DirectionRadios.end(); ++i) { QRadioButton* rdbtn = *i; if (rdbtn->isChecked()) fibDirection = rdbtn->objectName(); } // vtkPolyData* output; // FiberPD stores the generated PolyData... going to be generated in thread if ( fibDirection == FIB_RADIOBUTTON_DIRECTION_RANDOM ) { // build polydata with random lines and fibers // output = GenerateVtkFibersRandom(); } else if ( fibDirection == FIB_RADIOBUTTON_DIRECTION_X ) { // build polydata with XDirection fibers //output = GenerateVtkFibersDirectionX(); } else if ( fibDirection == FIB_RADIOBUTTON_DIRECTION_Y ) { // build polydata with YDirection fibers // output = GenerateVtkFibersDirectionY(); } else if ( fibDirection == FIB_RADIOBUTTON_DIRECTION_Z ) { // build polydata with ZDirection fibers // output = GenerateVtkFibersDirectionZ(); } } void QmitkFiberBundleDeveloperView::PutFibersToDataStorage( vtkPolyData* threadOutput) { MITK_INFO << "lines: " << threadOutput->GetNumberOfLines() << "pnts: " << threadOutput->GetNumberOfPoints(); //qthread mutex lock mitk::FiberBundleX::Pointer FB = mitk::FiberBundleX::New(); FB->SetFibers(threadOutput); FB->SetGeometry(this->GenerateStandardGeometryForMITK()); mitk::DataNode::Pointer FBNode; FBNode = mitk::DataNode::New(); FBNode->SetName("FiberBundleX"); FBNode->SetData(FB); FBNode->SetVisibility(true); GetDataStorage()->Add(FBNode); //output->Delete(); const mitk::PlaneGeometry * tsgeo = m_MultiWidget->GetTimeNavigationController()->GetCurrentPlaneGeometry(); if (tsgeo == NULL) { /* GetDataStorage()->Modified etc. have no effect, therefore proceed as followed below */ // get all nodes that have not set "includeInBoundingBox" to false mitk::NodePredicateNot::Pointer pred = mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("includeInBoundingBox" , mitk::BoolProperty::New(false))); mitk::DataStorage::SetOfObjects::ConstPointer rs = GetDataStorage()->GetSubset(pred); // calculate bounding geometry of these nodes mitk::TimeSlicedGeometry::Pointer bounds = GetDataStorage()->ComputeBoundingGeometry3D(rs); // initialize the views to the bounding geometry mitk::RenderingManager::GetInstance()->InitializeViews(bounds); } else { GetDataStorage()->Modified(); m_MultiWidget->RequestUpdate(); //necessary?? } //qthread mutex unlock } /* * Generate polydata of random fibers */ void QmitkFiberBundleDeveloperView::GenerateVtkFibersRandom() { /* ===== TIMER CONFIGURATIONS for visual effect ====== * start and stop is called in Thread */ QTimer *localTimer = new QTimer; // timer must be initialized here, otherwise timer is not fancy enough localTimer->setInterval( 10 ); connect( localTimer, SIGNAL(timeout()), this, SLOT(UpdateGenerateRandomFibersTimer()) ); struct Package4WorkingThread ItemPackageForRandomGenerator; ItemPackageForRandomGenerator.st_FBX = m_FiberBundleX; ItemPackageForRandomGenerator.st_Controls = m_Controls; ItemPackageForRandomGenerator.st_FancyGUITimer1 = localTimer; ItemPackageForRandomGenerator.st_host = this; ItemPackageForRandomGenerator.st_pntr_to_Method_PutFibersToDataStorage = &QmitkFiberBundleDeveloperView::PutFibersToDataStorage; //set element for thread monitoring if (m_fiberMonitorIsOn) ItemPackageForRandomGenerator.st_fiberThreadMonitorWorker = m_fiberThreadMonitorWorker; if (m_threadInProgress) return; //maybe popup window saying, working thread still in progress...pls wait m_GeneratorFibersRandom = new QmitkFiberGenerateRandomWorker(m_hostThread, ItemPackageForRandomGenerator); m_GeneratorFibersRandom->moveToThread(m_hostThread); connect(m_hostThread, SIGNAL(started()), this, SLOT( BeforeThread_GenerateFibersRandom()) ); connect(m_hostThread, SIGNAL(started()), m_GeneratorFibersRandom, SLOT(run()) ); connect(m_hostThread, SIGNAL(finished()), this, SLOT(AfterThread_GenerateFibersRandom()) ); connect(m_hostThread, SIGNAL(terminated()), this, SLOT(AfterThread_GenerateFibersRandom()) ); m_hostThread->start(QThread::LowestPriority); } void QmitkFiberBundleDeveloperView::UpdateGenerateRandomFibersTimer() { //MAKE SURE by yourself THAT NOTHING ELSE THAN A NUMBER IS SET IN THAT LABEL QString crntValue = m_Controls->infoTimerGenerateFiberBundle->text(); int tmpVal = crntValue.toInt(); m_Controls->infoTimerGenerateFiberBundle->setText(QString::number(++tmpVal)); m_Controls->infoTimerGenerateFiberBundle->update(); } void QmitkFiberBundleDeveloperView::BeforeThread_GenerateFibersRandom() { m_threadInProgress = true; if (m_fiberMonitorIsOn){ m_fiberThreadMonitorWorker->threadForFiberProcessingStarted(); //m_fiberThreadMonitorWorker->setThreadStatus(FBX_STATUS_STARTED); } } void QmitkFiberBundleDeveloperView::AfterThread_GenerateFibersRandom() { m_threadInProgress = false; if (m_fiberMonitorIsOn){ m_fiberThreadMonitorWorker->threadForFiberProcessingFinished(); m_fiberThreadMonitorWorker->setThreadStatus(FBX_STATUS_IDLE); } disconnect(m_hostThread, 0, 0, 0); m_hostThread->disconnect(); } vtkSmartPointer QmitkFiberBundleDeveloperView::GenerateVtkFibersDirectionX() { int numOfFibers = m_Controls->boxFiberNumbers->value(); vtkSmartPointer linesCell = vtkSmartPointer::New(); vtkSmartPointer points = vtkSmartPointer::New(); //insert Origin point, this point has index 0 in point array double originX = 0.0; double originY = 0.0; double originZ = 0.0; //after each iteration the origin of the new fiber increases //here you set which direction is affected. double increaseX = 0.0; double increaseY = 1.0; double increaseZ = 0.0; //walk along X axis //length of fibers increases in each iteration for (int i=0; i newFiber = vtkSmartPointer::New(); newFiber->GetPointIds()->SetNumberOfIds(i+2); //create starting point and add it to pointset points->InsertNextPoint(originX + (double)i * increaseX , originY + (double)i * increaseY, originZ + (double)i * increaseZ); //add starting point to fiber newFiber->GetPointIds()->SetId(0,points->GetNumberOfPoints()-1); //insert remaining points for fiber for (int pj=0; pj<=i ; ++pj) { //generate next point on X axis points->InsertNextPoint( originX + (double)pj+1 , originY + (double)i * increaseY, originZ + (double)i * increaseZ ); newFiber->GetPointIds()->SetId(pj+1,points->GetNumberOfPoints()-1); } linesCell->InsertNextCell(newFiber); } vtkSmartPointer PDX = vtkSmartPointer::New(); PDX->SetPoints(points); PDX->SetLines(linesCell); return PDX; } vtkSmartPointer QmitkFiberBundleDeveloperView::GenerateVtkFibersDirectionY() { vtkSmartPointer PDY = vtkSmartPointer::New(); //todo return PDY; } vtkSmartPointer QmitkFiberBundleDeveloperView::GenerateVtkFibersDirectionZ() { vtkSmartPointer PDZ = vtkSmartPointer::New(); //todo return PDZ; } - +void QmitkFiberBundleDeveloperView::DoColorFibers() +{ + // + MITK_INFO << "call fibercoloring in fiberBundleX"; +} /* === OutSourcedMethod: THIS METHOD GENERATES ESSENTIAL GEOMETRY PARAMETERS FOR THE MITK FRAMEWORK === * WITHOUT, the rendering mechanism will ignore objects without valid Geometry * for each object, MITK requires: ORIGIN, SPACING, TRANSFORM MATRIX, BOUNDING-BOX */ mitk::Geometry3D::Pointer QmitkFiberBundleDeveloperView::GenerateStandardGeometryForMITK() { mitk::Geometry3D::Pointer geometry = mitk::Geometry3D::New(); // generate origin mitk::Point3D origin; origin[0] = 0; origin[1] = 0; origin[2] = 0; geometry->SetOrigin(origin); // generate spacing float spacing[3] = {1,1,1}; geometry->SetSpacing(spacing); // generate identity transform-matrix vtkMatrix4x4* m = vtkMatrix4x4::New(); geometry->SetIndexToWorldTransformByVtkMatrix(m); // generate boundingbox // for an usable bounding-box use gui parameters to estimate the boundingbox float bounds[] = {500, 500, 500, -500, -500, -500}; // GET SELECTED FIBER DIRECTION QString fibDirection; //stores the object_name of selected radiobutton QVector::const_iterator i; for (i = m_DirectionRadios.begin(); i != m_DirectionRadios.end(); ++i) { QRadioButton* rdbtn = *i; if (rdbtn->isChecked()) fibDirection = rdbtn->objectName(); } if ( fibDirection == FIB_RADIOBUTTON_DIRECTION_RANDOM ) { // use information about distribution parameter to calculate bounding box int distrRadius = m_Controls->boxDistributionRadius->value(); bounds[0] = distrRadius; bounds[1] = distrRadius; bounds[2] = distrRadius; bounds[3] = -distrRadius; bounds[4] = -distrRadius; bounds[5] = -distrRadius; } else { // so far only X,Y,Z directions are available MITK_INFO << "_______GEOMETRY ISSUE_____\n***BoundingBox for X, Y, Z fiber directions are not optimized yet!***"; int maxFibLength = m_Controls->boxFiberMaxLength->value(); bounds[0] = maxFibLength; bounds[1] = maxFibLength; bounds[2] = maxFibLength; bounds[3] = -maxFibLength; bounds[4] = -maxFibLength; bounds[5] = -maxFibLength; } geometry->SetFloatBounds(bounds); geometry->SetImageGeometry(true); //?? return geometry; } void QmitkFiberBundleDeveloperView::UpdateFiberIDTimer() { //MAKE SURE by yourself THAT NOTHING ELSE THAN A NUMBER IS SET IN THAT LABEL QString crntValue = m_Controls->infoTimerGenerateFiberIds->text(); int tmpVal = crntValue.toInt(); m_Controls->infoTimerGenerateFiberIds->setText(QString::number(++tmpVal)); m_Controls->infoTimerGenerateFiberIds->update(); } /* Initialie ID dataset in FiberBundleX */ void QmitkFiberBundleDeveloperView::DoGenerateFiberIDs() { /* ===== TIMER CONFIGURATIONS for visual effect ====== * start and stop is called in Thread */ QTimer *localTimer = new QTimer; // timer must be initialized here, otherwise timer is not fancy enough localTimer->setInterval( 10 ); connect( localTimer, SIGNAL(timeout()), this, SLOT(UpdateFiberIDTimer()) ); // pack items which are needed by thread processing struct Package4WorkingThread FiberIdPackage; FiberIdPackage.st_FBX = m_FiberBundleX; FiberIdPackage.st_FancyGUITimer1 = localTimer; FiberIdPackage.st_Controls = m_Controls; //set element for thread monitoring if (m_fiberMonitorIsOn) FiberIdPackage.st_fiberThreadMonitorWorker = m_fiberThreadMonitorWorker; if (m_threadInProgress) return; //maybe popup window saying, working thread still in progress...pls wait // THREAD CONFIGURATION m_FiberIDGenerator = new QmitkFiberIDWorker(m_hostThread, FiberIdPackage); m_FiberIDGenerator->moveToThread(m_hostThread); connect(m_hostThread, SIGNAL(started()), this, SLOT( BeforeThread_IdGenerate()) ); connect(m_hostThread, SIGNAL(started()), m_FiberIDGenerator, SLOT(run())); connect(m_hostThread, SIGNAL(finished()), this, SLOT(AfterThread_IdGenerate())); connect(m_hostThread, SIGNAL(terminated()), this, SLOT(AfterThread_IdGenerate())); m_hostThread->start(QThread::LowestPriority); // m_Controls->infoTimerGenerateFiberIds->setText(QString::number(clock.GetTotal())); } void QmitkFiberBundleDeveloperView::BeforeThread_IdGenerate() { m_threadInProgress = true; if (m_fiberMonitorIsOn){ m_fiberThreadMonitorWorker->threadForFiberProcessingStarted(); m_fiberThreadMonitorWorker->setThreadStatus(FBX_STATUS_STARTED); } } void QmitkFiberBundleDeveloperView::AfterThread_IdGenerate() { m_threadInProgress = false; if (m_fiberMonitorIsOn){ m_fiberThreadMonitorWorker->threadForFiberProcessingFinished(); m_fiberThreadMonitorWorker->setThreadStatus(FBX_STATUS_IDLE); } disconnect(m_hostThread, 0, 0, 0); m_hostThread->disconnect(); } void QmitkFiberBundleDeveloperView::ResetFiberInfoWidget() { if (m_Controls->infoAnalyseNumOfFibers->isEnabled()) { m_Controls->infoAnalyseNumOfFibers->setText("-"); m_Controls->infoAnalyseNumOfPoints->setText("-"); m_Controls->infoAnalyseNumOfFibers->setEnabled(false); } } void QmitkFiberBundleDeveloperView::FeedFiberInfoWidget() { if (!m_Controls->infoAnalyseNumOfFibers->isEnabled()) m_Controls->infoAnalyseNumOfFibers->setEnabled(true); QString numOfFibers; numOfFibers.setNum( m_FiberBundleX->GetFibers()->GetNumberOfLines() ); QString numOfPoints; numOfPoints.setNum( m_FiberBundleX->GetFibers()->GetNumberOfPoints() ); m_Controls->infoAnalyseNumOfFibers->setText( numOfFibers ); m_Controls->infoAnalyseNumOfPoints->setText( numOfPoints ); } void QmitkFiberBundleDeveloperView::SelectionChangedToolBox(int idx) { - MITK_INFO << "printtoolbox: " << idx; - if (m_Controls->page_FiberInfo->isVisible() && m_FiberBundleX != NULL) + // show/reset items of selected toolbox page FiberInfo + if (m_Controls->page_FiberInfo->isVisible()) { - FeedFiberInfoWidget(); - - } else { - //if infolables are disabled: return - //else set info back to - and set label and info to disabled - - if (!m_Controls->page_FiberInfo->isVisible()) { - return; + if (m_FiberBundleX != NULL) { + FeedFiberInfoWidget(); + } else { + //if infolables are disabled: return + //else set info back to - and set label and info to disabled ResetFiberInfoWidget(); } } + // show/reset items of selected toolbox page FiberProcessing + if (m_Controls->page_FiberProcessing->isVisible()) + { + if (m_FiberBundleX != NULL) + { + if (m_Controls->tabColoring->isVisible()){ + //show button colorCoding + m_Controls->buttonColorFibers->setEnabled(true); + MITK_INFO << "Color"; + + }else if(m_Controls->tabCutting->isVisible()){ +// m_Controls->buttonGenerateFiberIds->setEnabled(true); + + + }else if(m_Controls->tabShape->isVisible()){ +// m_Controls->buttonSMFibers->setEnabled(true); +// m_Controls->buttonVtkDecimatePro->setEnabled(true); +// m_Controls->buttonVtkSmoothPD->setEnabled(true); +// m_Controls->buttonGenerateTubes->setEnabled(true); + } + + + } else { + m_Controls->buttonColorFibers->setEnabled(false); + m_Controls->buttonGenerateFiberIds->setEnabled(false); + m_Controls->buttonSMFibers->setEnabled(false); + m_Controls->buttonVtkDecimatePro->setEnabled(false); + m_Controls->buttonVtkSmoothPD->setEnabled(false); + m_Controls->buttonGenerateTubes->setEnabled(true); + + } + } + } void QmitkFiberBundleDeveloperView::FBXDependendGUIElementsConfigurator(bool isVisible) { - // ==== FIBER PROCESSING ELEMENTS ====== - m_Controls->buttonGenerateFiberIds->setEnabled(isVisible); + // ==== FIBER PROCESSING ELEMENTS and ALL ELEMENTS WHICH NEED A FBX DATANODE====== +// m_Controls->buttonGenerateFiberIds->setEnabled(isVisible); moved to selectionChangedToolBox + SelectionChangedToolBox(-1); //set gui elements with respect to active tab, widget, etc. -1 has no effect } void QmitkFiberBundleDeveloperView::DoMonitorFiberThreads(int checkStatus) { //check if in datanode exists already a node of type mitkFiberBundleXThreadMonitor //if not then put node to datastorage //if checkStatus is 1 then start qtimer using fading in starting text in datanode //if checkStatus is 0 then fade out dataNode using qtimer if (checkStatus) { m_fiberMonitorIsOn = true; // Generate Node hosting thread information mitk::FiberBundleXThreadMonitor::Pointer FBXThreadMonitor = mitk::FiberBundleXThreadMonitor::New(); FBXThreadMonitor->SetGeometry(this->GenerateStandardGeometryForMITK()); m_MonitorNode = mitk::DataNode::New(); m_MonitorNode->SetName("FBX_threadMonitor"); m_MonitorNode->SetData(FBXThreadMonitor); m_MonitorNode->SetVisibility(true); m_MonitorNode->SetOpacity(1.0); GetDataStorage()->Add(m_MonitorNode); //following code is needed for rendering text in mitk! without geometry nothing is rendered const mitk::PlaneGeometry * tsgeo = m_MultiWidget->GetTimeNavigationController()->GetCurrentPlaneGeometry(); if (tsgeo == NULL) { /* GetDataStorage()->Modified etc. have no effect, therefore proceed as followed below */ // get all nodes that have not set "includeInBoundingBox" to false mitk::NodePredicateNot::Pointer pred = mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New( "includeInBoundingBox" , mitk::BoolProperty::New(false))); mitk::DataStorage::SetOfObjects::ConstPointer rs = GetDataStorage()->GetSubset(pred); // calculate bounding geometry of these nodes mitk::TimeSlicedGeometry::Pointer bounds = GetDataStorage()->ComputeBoundingGeometry3D(rs); // initialize the views to the bounding geometry mitk::RenderingManager::GetInstance()->InitializeViews(bounds); } else { GetDataStorage()->Modified(); m_MultiWidget->RequestUpdate(); //necessary?? } //__GEOMETRY FOR THREADMONITOR GENERATED /* ====== initialize thread for managing fiberThread information ========= */ m_monitorThread = new QThread; // the package needs datastorage, MonitorDatanode, standardmultiwidget, struct Package4WorkingThread ItemPackageForThreadMonitor; ItemPackageForThreadMonitor.st_DataStorage = GetDataStorage(); ItemPackageForThreadMonitor.st_ThreadMonitorDataNode = m_MonitorNode; ItemPackageForThreadMonitor.st_MultiWidget = m_MultiWidget; ItemPackageForThreadMonitor.st_FBX_Monitor = FBXThreadMonitor; m_fiberThreadMonitorWorker = new QmitkFiberThreadMonitorWorker(m_monitorThread, ItemPackageForThreadMonitor); m_fiberThreadMonitorWorker->moveToThread(m_monitorThread); connect ( m_monitorThread, SIGNAL( started() ), m_fiberThreadMonitorWorker, SLOT( run() ) ); m_monitorThread->start(QThread::LowestPriority); m_fiberThreadMonitorWorker->initializeMonitor();//do some init animation ;-) } else { m_fiberMonitorIsOn = false; m_monitorThread->quit(); //think about outsourcing following lines to quit / terminate slot of thread GetDataStorage()->Remove(m_MonitorNode); GetDataStorage()->Modified(); m_MultiWidget->RequestUpdate(); //necessary?? } } void QmitkFiberBundleDeveloperView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_MultiWidget = &stdMultiWidget; } void QmitkFiberBundleDeveloperView::StdMultiWidgetNotAvailable() { m_MultiWidget = NULL; } /* OnSelectionChanged is registered to SelectionService, therefore no need to implement SelectionService Listener explicitly */ void QmitkFiberBundleDeveloperView::OnSelectionChanged( std::vector nodes ) { /* ==== reset everyhing related to FiberBundleX ====== * - variable m_FiberBundleX * - visualization of analysed fiberbundle */ m_FiberBundleX = NULL; //reset pointer, so that member does not point to depricated locations ResetFiberInfoWidget(); FBXDependendGUIElementsConfigurator(false); //every gui element which needs a FBX for processing is disabled //timer reset only when no thread is in progress if (!m_threadInProgress) { m_Controls->infoTimerGenerateFiberIds->setText("-"); //set GUI representation of timer to - m_Controls->infoTimerGenerateFiberBundle->setText( "-" ); } //==================================================== if (nodes.empty()) return; for( std::vector::iterator it = nodes.begin(); it != nodes.end(); ++it ) { mitk::DataNode::Pointer node = *it; /* CHECKPOINT: FIBERBUNDLE*/ if( node.IsNotNull() && dynamic_cast(node->GetData()) ) { m_FiberBundleX = dynamic_cast(node->GetData()); if (m_FiberBundleX == NULL) MITK_INFO << "========ATTENTION=========\n unable to load selected FiberBundleX to FiberBundleDeveloper-plugin \n"; // ==== FIBERBUNDLE_INFO ELEMENTS ==== if ( m_Controls->page_FiberInfo->isVisible() ) FeedFiberInfoWidget(); // enable FiberBundleX related Gui Elements, such as buttons etc. FBXDependendGUIElementsConfigurator(true); } } } void QmitkFiberBundleDeveloperView::Activated() { MITK_INFO << "FB DevelopersV ACTIVATED()"; } diff --git a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberBundleDeveloperView.h b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberBundleDeveloperView.h index 989d530d0d..1b1bebcc3f 100644 --- a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberBundleDeveloperView.h +++ b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberBundleDeveloperView.h @@ -1,289 +1,290 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2010-03-31 16:40:27 +0200 (Mi, 31 Mrz 2010) $ Version: $Revision: 21975 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef QmitkFiberBundleDeveloperView_h #define QmitkFiberBundleDeveloperView_h #include #include #include #include "ui_QmitkFiberBundleDeveloperViewControls.h" #include #include #include #include // Qt #include #include #include // VTK #include #include #include #include #include #include class QmitkFiberThreadMonitorWorker; //include needed for struct element class QmitkFiberBundleDeveloperView; //this include is needed for the struct element, especially for functors to QmitkFiberBundleDeveloperView /* ==== THIS STRUCT CONTAINS ALL NECESSARY VARIABLES * TO EXECUTE AND UPDATE GUI ELEMENTS DURING PROCESSING OF A THREAD * why? either you add tons of friendclasses (e.g. FiberWorker objects), or you create a package containing all items needed. Otherwise you have to set all members etc. to public! */ struct Package4WorkingThread { mitk::FiberBundleX* st_FBX; QTimer* st_FancyGUITimer1; Ui::QmitkFiberBundleDeveloperViewControls* st_Controls; //functors to outdoor methods QmitkFiberBundleDeveloperView* st_host; void (QmitkFiberBundleDeveloperView::*st_pntr_to_Method_PutFibersToDataStorage) (vtkPolyData*); //==DO NOT TOUCH THIS SECTION=== //host MITK I/O elements, especially needed for thread monitoring QmitkFiberThreadMonitorWorker *st_fiberThreadMonitorWorker; mitk::FiberBundleXThreadMonitor::Pointer st_FBX_Monitor; //needed for direct access do animation/fancy methods mitk::DataNode::Pointer st_ThreadMonitorDataNode; //needed for renderer to recognize node modifications mitk::DataStorage::Pointer st_DataStorage; //well that is discussable if needed ;-) probably not QmitkStdMultiWidget* st_MultiWidget; //needed for rendering update }; // ==================================================================== // ============= WORKER WHICH IS PASSED TO THREAD ===================== // ==================================================================== //## Documentation //## This class does the actual work for generating fiber ids. class QmitkFiberIDWorker : public QObject { Q_OBJECT public: QmitkFiberIDWorker( QThread*, Package4WorkingThread ); public slots: void run(); private: Package4WorkingThread m_itemPackage; QThread* m_hostingThread; }; // ==================================================================== // ============= WORKER WHICH IS PASSED TO THREAD ===================== // ==================================================================== class QmitkFiberGenerateRandomWorker : public QObject { Q_OBJECT public: QmitkFiberGenerateRandomWorker( QThread*, Package4WorkingThread ); public slots: void run(); private: Package4WorkingThread m_itemPackage; QThread* m_hostingThread; }; class QmitkFiberThreadMonitorWorker : public QObject { Q_OBJECT public: QmitkFiberThreadMonitorWorker( QThread*, Package4WorkingThread ); void initializeMonitor(); void threadForFiberProcessingStarted(); void threadForFiberProcessingFinished(); void threadForFiberProcessingTerminated(); void setThreadStatus(QString); public slots: void run(); void fancyMonitorInitialization(); void fancyMonitorInitializationFinalPos(); void fancyMonitorInitializationMask(); void fancyTextFading_threadStarted(); void fancyTextFading_threadFinished(); void fancyTextFading_threadTerminated(); private: Package4WorkingThread m_itemPackage; QThread* m_hostingThread; QTimer* m_thtimer_initMonitor; QTimer* m_thtimer_initMonitorSetFinalPosition; QTimer* m_thtimer_initMonitorSetMasks; QTimer* m_thtimer_threadStarted; QTimer* m_thtimer_threadFinished; QTimer* m_thtimer_threadTerminated; // flags for fancy fading bool m_decreaseOpacity_threadStarted; bool m_decreaseOpacity_threadFinished; bool m_decreaseOpacity_threadTerminated; // members for fancy animation int m_pixelstepper; int m_steppingDistance; }; // strings to display fiber_thread monitor const QString FBX_STATUS_IDLE = "idle"; const QString FBX_STATUS_STARTED = "starting"; const QString FBX_STATUS_RUNNING = "running"; // ========= HERE STARTS THE ACTUAL FIBERBUNDLE DEVELOPER VIEW ======= const QString FIB_RADIOBUTTON_DIRECTION_RANDOM = "radioButton_directionRandom"; const QString FIB_RADIOBUTTON_DIRECTION_X = "radioButton_directionX"; const QString FIB_RADIOBUTTON_DIRECTION_Y = "radioButton_directionY"; const QString FIB_RADIOBUTTON_DIRECTION_Z = "radioButton_directionZ"; /*! \brief QmitkFiberBundleView \warning This application module is not yet documented. Use "svn blame/praise/annotate" and ask the author to provide basic documentation. \sa QmitkFunctionality \ingroup Functionalities */ class QmitkFiberBundleDeveloperView : public QmitkFunctionality { // this is needed for all Qt objects that should have a Qt meta-object // (everything that derives from QObject and wants to have signal/slots) Q_OBJECT public: static const std::string VIEW_ID; QmitkFiberBundleDeveloperView(); virtual ~QmitkFiberBundleDeveloperView(); virtual void CreateQtPartControl(QWidget *parent); virtual void StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget); virtual void StdMultiWidgetNotAvailable(); virtual void Activated(); protected slots: void DoGenerateFibers(); void DoGenerateFiberIDs(); void DoUpdateGenerateFibersWidget(); void SelectionChangedToolBox(int); void DoMonitorFiberThreads(int); + void DoColorFibers(); //SLOTS FOR THREADS void BeforeThread_IdGenerate(); void AfterThread_IdGenerate(); void BeforeThread_GenerateFibersRandom(); void AfterThread_GenerateFibersRandom(); //SLOTS FOR TIMERS void UpdateFiberIDTimer(); void UpdateGenerateRandomFibersTimer(); protected: /// \brief called by QmitkFunctionality when DataManager's selection has changed virtual void OnSelectionChanged( std::vector nodes ); Ui::QmitkFiberBundleDeveloperViewControls* m_Controls; QmitkStdMultiWidget* m_MultiWidget; private: /* METHODS GENERATING FIBERSTRUCTURES */ void GenerateVtkFibersRandom(); vtkSmartPointer GenerateVtkFibersDirectionX(); vtkSmartPointer GenerateVtkFibersDirectionY(); vtkSmartPointer GenerateVtkFibersDirectionZ(); void PutFibersToDataStorage( vtkPolyData* ); /* METHODS FOR FIBER PROCESSING OR PREPROCESSING */ /* HELPERMETHODS */ mitk::Geometry3D::Pointer GenerateStandardGeometryForMITK(); void ResetFiberInfoWidget(); void FeedFiberInfoWidget(); void FBXDependendGUIElementsConfigurator(bool); void SetGeneratedFBX(); //contains the selected FiberBundle //mitk::FiberBundleX* m_FiberBundleX; mitk::WeakPointer m_FiberBundleX; // radiobutton groups QVector< QRadioButton* > m_DirectionRadios; QVector< QRadioButton* > m_FARadios; QVector< QRadioButton* > m_GARadios; // Thread based Workers which do some processing of fibers QmitkFiberIDWorker * m_FiberIDGenerator; QmitkFiberGenerateRandomWorker * m_GeneratorFibersRandom; QThread * m_hostThread; QThread * m_monitorThread; bool m_threadInProgress; mitk::DataNode::Pointer m_MonitorNode; QmitkFiberThreadMonitorWorker *m_fiberThreadMonitorWorker; bool m_fiberMonitorIsOn; }; #endif // _QMITKFIBERTRACKINGVIEW_H_INCLUDED diff --git a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberBundleDeveloperViewControls.ui b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberBundleDeveloperViewControls.ui index 63db98fc7d..a25449e11a 100644 --- a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberBundleDeveloperViewControls.ui +++ b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberBundleDeveloperViewControls.ui @@ -1,846 +1,927 @@ QmitkFiberBundleDeveloperViewControls 0 0 - 405 - 753 + 539 + 966 Form 12 50 false - 0 + 1 0 0 - 366 - 449 + 500 + 540 Fiber Generator 0 Fiber Bundles Generate Fiberbundle Fiber Parameters 11 Total number of Fibers 10 999999999 100 Qt::Horizontal 40 20 11 Distribution Radius 10 9999 100 11 Fiber Length Max (points) 10 50 11 Fiber Length Min (points) 10 10 labelFibersTotal boxFiberNumbers horizontalSpacer_3 labelDistrRadius boxDistributionRadius labelFiberMaxLength boxFiberMaxLength labelFiberMinLength boxFiberMinLength 11 Fiber Orientation along Z Axis along X Axis random true along Y Axis Qt::Horizontal 40 20 Qt::Vertical 20 40 QFrame::StyledPanel QFrame::Raised 10 Time: 10 - DWI Values GA Values no values true nothing yet implemented 11 FA Values const value false 10 1.000000000000000 0.100000000000000 1.000000000000000 random range false 10 1.000000000000000 0.100000000000000 no values true false 10 1.000000000000000 0.100000000000000 Qt::Vertical 20 40 Page Select a FiberBundle in Datamanager Qt::Vertical 20 40 0 0 - 307 - 403 + 500 + 409 Fiber Processor - 2 + 0 Colors - + Fiber Coloring - - + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Orientation based + + + true + + + + + + + FA based + + + + + + + - Color Fibers + Colorcode Fibers + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + QFormLayout::FieldsStayAtSizeHint + + + + + + 10 + + + + Timer: + + + + + + + + 10 + + + + - + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + - + Qt::Vertical 20 40 - + Shape Qt::Vertical 20 40 Fiber Smoothing Smooth Fibers QFrame::StyledPanel QFrame::Raised static value relative in% false 10 none true false 10 9999 Qt::Horizontal 40 20 vtkFilters Tubes vtkDecimatePro vtkSmoothPolyDataFilter - + Cutting Step1: Generate Fibers IDs in FBX Qt::Vertical 20 40 QFrame::StyledPanel QFrame::Raised QFormLayout::FieldsStayAtSizeHint 10 Timer: 10 - Execute Step1 0 0 - 185 - 116 + 515 + 348 FiberInfo General Information Number of Fibers: - Number of Points: - Qt::Vertical 20 40 Qt::Horizontal Monitor Fiber Threading in mitkRenderWindow4 Qt::Vertical 20 40 diff --git a/Modules/DiffusionImaging/IODataStructures/FiberBundle/mitkFiberBundle.cpp b/Modules/DiffusionImaging/IODataStructures/FiberBundle/mitkFiberBundle.cpp index 18948c3471..0e3690424e 100644 --- a/Modules/DiffusionImaging/IODataStructures/FiberBundle/mitkFiberBundle.cpp +++ b/Modules/DiffusionImaging/IODataStructures/FiberBundle/mitkFiberBundle.cpp @@ -1,1863 +1,1865 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2010-03-31 16:40:27 +0200 (Mi, 31 Mrz 2010) $ Version: $Revision: 21975 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkFiberBundle.h" #include "mitkGeometry2D.h" #include "mitkVector.h" #include "mitkPlaneGeometry.h" #include #include "mitkPlanarFigure.h" #include "mitkPlanarCircle.h" #include "mitkPlanarRectangle.h" #include "mitkPlanarPolygon.h" #include "mitkPlanarFigureComposite.h" #include //#include /* statics values to define the position of a fiberTractPoint * related to the plane of a ROI */ const int mitk::FiberBundle::TRACTPOINT_BACKFACE = 0; const int mitk::FiberBundle::TRACTPOINT_ON_PLANE = 1; const int mitk::FiberBundle::TRACTPOINT_FRNTFACE = 2; // implementation of all essential methods from superclass mitk::FiberBundle::FiberBundle() { + MITK_INFO << "init FB"; + m_GroupFiberBundle = FiberGroupType::New(); m_TractContainer = ContainerType::New(); //by default set a standard geometry, usually geometry is set by the user on initializing //a mitkFiberBundle Object mitk::Geometry3D::Pointer fbgeometry = mitk::Geometry3D::New(); fbgeometry->SetIdentity(); this->SetGeometry(fbgeometry); /* for debugging only */ m_debugITKContainer = itkStochTractContainerType::New(); } mitk::FiberBundle::~FiberBundle() { - + MITK_INFO << "destructed FB"; } void mitk::FiberBundle::SetBounds(float* b) { m_boundsFB[0] = b[0]; m_boundsFB[1] = b[1]; m_boundsFB[2] = b[2]; } void mitk::FiberBundle::SetBounds(double* b) { m_boundsFB[0] = b[0]; m_boundsFB[1] = b[1]; m_boundsFB[2] = b[2]; } float* mitk::FiberBundle::GetBounds() { return m_boundsFB; } void mitk::FiberBundle::PushPoint(int fiberIndex, ContainerPointType point) { if( (unsigned)fiberIndex >= m_TractContainer->Size() ) { fiberIndex = m_TractContainer->Size(); ContainerTractType::Pointer tract = ContainerTractType::New(); tract->InsertElement(tract->Size(),point); m_TractContainer->InsertElement(fiberIndex, tract); } else if(fiberIndex>=0) { m_TractContainer->ElementAt(fiberIndex)->InsertElement(m_TractContainer->ElementAt(fiberIndex)->Size(), point); } } void mitk::FiberBundle::PushTract(ContainerTractType::Pointer tract) { m_TractContainer->InsertElement(m_TractContainer->Size(), tract); } mitk::FiberBundle::Pointer mitk::FiberBundle::JoinBundle(mitk::FiberBundle::Pointer bundle) { mitk::FiberBundle::Pointer retval = mitk::FiberBundle::New(); retval->SetGeometry(this->GetGeometry()); retval->SetBounds(this->m_boundsFB); retval->InsertBundle(this); retval->InsertBundle(bundle); return retval; } void mitk::FiberBundle::InsertBundle(mitk::FiberBundle::Pointer bundle) { // INCOMPLETE, SHOULD CHECK FOR DIFFERENT GEOMETRIES IN THIS+BUNDLE // DO INDEX1 -> WORLD -> INDEX2 TRANSFORMATION, IF THEY ARE DIFFERENT. int num = this->GetNumTracts(); FiberGroupType::Pointer groupFiberBundle = bundle->GetGroupFiberBundle(); ChildrenListType *fiberList = groupFiberBundle->GetChildren(); for(ChildrenListType::iterator itLst = fiberList->begin(); itLst != fiberList->end(); ++itLst) { itk::SpatialObject<3>::Pointer tmp_fbr; tmp_fbr = *itLst; mitk::FiberBundle::DTITubeType::Pointer dtiTract = dynamic_cast< mitk::FiberBundle::DTITubeType * > (tmp_fbr.GetPointer()); if (dtiTract.IsNull()) { MITK_INFO << "DTI Tract is NULL!!!!! omg"; continue; } dtiTract->SetId(num++); this->addSingleDTITract(dtiTract); } ContainerType::Pointer container = bundle->GetTractContainer(); for(int i=0; iSize();i++) { this->PushTract(container->ElementAt(i)); } } int mitk::FiberBundle::FindTractByEndpoints(mitk::FiberBundle::DTITubeType::Pointer searchTract) { int searchNrPnts = searchTract->GetNumberOfPoints(); mitk::FiberBundle::DTITubeType::PointListType searchPntList = searchTract->GetPoints(); typedef mitk::FiberBundle::DTITubeType::PointType PointType; DTITubePointType searchPointFirst = searchPntList.at(0); PointType searchPos1 = searchPointFirst.GetPosition(); DTITubePointType searchPointLast = searchPntList.at(searchNrPnts-1); PointType searchPos2 = searchPointLast.GetPosition(); FiberGroupType::Pointer groupFiberBundle = this->GetGroupFiberBundle(); ChildrenListType *fiberList = groupFiberBundle->GetChildren(); for(ChildrenListType::iterator itLst = fiberList->begin(); itLst != fiberList->end(); ++itLst) { itk::SpatialObject<3>::Pointer tmp_fbr; tmp_fbr = *itLst; mitk::FiberBundle::DTITubeType::Pointer dtiTract = dynamic_cast< mitk::FiberBundle::DTITubeType * > (tmp_fbr.GetPointer()); if (dtiTract.IsNull()) { MITK_INFO << "DTI Tract is NULL!!!!! omg"; continue; } mitk::FiberBundle::DTITubeType::PointListType dtiPntList = dtiTract->GetPoints(); int fibrNrPnts = dtiTract->GetNumberOfPoints(); DTITubePointType point_first = dtiPntList.at(0); PointType pos1 = point_first.GetPosition(); DTITubePointType point_last = dtiPntList.at(fibrNrPnts-1); PointType pos2 = point_last.GetPosition(); if( (pos1 == searchPos1 && pos2 == searchPos2) || (pos2 == searchPos1 && pos1 == searchPos2) ) { return dtiTract->GetId(); } } return -1; } mitk::FiberBundle::Pointer mitk::FiberBundle::SubstractBundle(mitk::FiberBundle::Pointer bundle) { mitk::FiberBundle::Pointer retval = mitk::FiberBundle::New(); retval->SetGeometry(this->GetGeometry()); mitk::FiberBundle::Pointer largeBundle = bundle; mitk::FiberBundle::Pointer smallBundle = this; MITK_INFO << "large children " << largeBundle->GetGroupFiberBundle()->GetNumberOfChildren() << "!="<GetNumTracts(); MITK_INFO << "small children " << smallBundle->GetGroupFiberBundle()->GetNumberOfChildren() << "!="<GetNumTracts(); if(this->GetGroupFiberBundle()->GetNumberOfChildren() > bundle->GetGroupFiberBundle()->GetNumberOfChildren()) { MITK_INFO << "this is large (" << this->GetNumTracts() << ">" << bundle->GetNumTracts() << ")"; largeBundle = this; smallBundle = bundle; } ContainerType::Pointer container = largeBundle->GetTractContainer(); int counter = 0; FiberGroupType::Pointer groupFiberBundle = largeBundle->GetGroupFiberBundle(); ChildrenListType *fiberList = groupFiberBundle->GetChildren(); MITK_INFO << "large number children " << groupFiberBundle->GetNumberOfChildren(); for(ChildrenListType::iterator itLst = fiberList->begin(); itLst != fiberList->end(); ++itLst) { itk::SpatialObject<3>::Pointer tmp_fbr; tmp_fbr = *itLst; mitk::FiberBundle::DTITubeType::Pointer dtiTract = dynamic_cast< mitk::FiberBundle::DTITubeType * > (tmp_fbr.GetPointer()); if (dtiTract.IsNull()) { MITK_INFO << "DTI Tract is NULL!!!!! omg"; continue; } int delId = smallBundle->FindTractByEndpoints(dtiTract); if( delId == -1 ) { retval->addSingleDTITract(dtiTract); retval->PushTract(container->ElementAt(counter)); } MITK_INFO << "Counter " << counter++; } return retval; } mitk::FiberBundle::ContainerPointType mitk::FiberBundle::GetPoint(int tractIndex, int pointIndex) { if (tractIndex>=0 && tractIndex=0 && pointIndexGetElement(tractIndex)->GetElement(pointIndex); } return NULL; } int mitk::FiberBundle::GetNumTracts() { return m_TractContainer->Size(); } int mitk::FiberBundle::GetNumPoints(int tractIndex) { if ((unsigned)tractIndex>=0 && (unsigned)tractIndexSize()) { return m_TractContainer->GetElement(tractIndex)->Size(); } else { //added by igi return NULL; } } mitk::FiberBundle::ContainerTractType::Pointer mitk::FiberBundle::GetTract(int tractIndex) { ContainerTractType::Pointer out; if ((unsigned)tractIndex>0 && (unsigned)tractIndexSize()) return m_TractContainer->GetElement(tractIndex); return out; } void mitk::FiberBundle::additkStochTractContainer(itkStochTractContainerType::Pointer itkStochCont) { //for debugging only m_debugITKContainer = itkStochCont; //******************** /* transform itkStochContainer to standardized TractContainer */ for (itkStochTractContainerType::ConstIterator itCont = itkStochCont->Begin(); itCont != itkStochCont->End(); ++itCont) { // get fiber of itkContainer itkStochTractType::Pointer tract = itCont->Value(); itkStochTractType::VertexListType::ConstPointer vertexlist = tract->GetVertexList(); //init a desired containerFiber ContainerTractType::Pointer contTract = ContainerTractType::New(); //get points of fiber for( int j=0; j<(int)vertexlist->Size(); ++j) { // put the point of vertex pointList in itkContainer itkStochTractType::VertexType vertex = vertexlist->GetElement(j); //prepare for dtiPoint ContainerPointType contPnt; contPnt[0] = (float) vertex[0]; contPnt[1] = (float) vertex[1]; contPnt[2] = (float) vertex[2]; contTract->InsertElement(contTract->Size(), contPnt); /* coordinate testing*/ /*if ((float)vertex[0] == contPnt[0]) { MITK_INFO << " [OK] ... X "; }else { MITK_INFO << "[FAIL] ... itkX: " << vertex[0] << " " << contPnt[0] << "\n" ; } if ((float)vertex[1] == contPnt[1]) { MITK_INFO << " [OK] ... Y "; }else { MITK_INFO << "[FAIL] ... itkY: " << vertex[1] << " " << contPnt[1] << "\n" ; } if ((float)vertex[2] == contPnt[2]) { MITK_INFO << " [OK] ... Z " << "\n" ; MITK_INFO << " Values X Y Z: " << contPnt[0] << " " << contPnt[1] << " " << contPnt[2] << "\n"; }else { MITK_INFO << "[FAIL] ... itkZ: " << vertex[2] << " " << contPnt[2] << "\n" ; } */ } // add filled fiber to container m_TractContainer->InsertElement(m_TractContainer->Size(), contTract); } } void mitk::FiberBundle::addTractContainer( ContainerType::Pointer tractContainer ) { m_TractContainer = tractContainer; } void mitk::FiberBundle::initFiberGroup() { /* iterate through the tractContainer and store fibers in DTISpatialObjects */ for (ContainerType::ConstIterator itCont = m_TractContainer->Begin(); itCont != m_TractContainer->End(); ++itCont) { // init new dtiTube and DTITubeType::Pointer dtiTube = DTITubeType::New(); DTITubeType::PointListType list; // get current tract of container ContainerTractType::Pointer contTract = itCont->Value(); // iterate through the number of points ... use iterator, no index-output is needed anyway for(ContainerTractType::Iterator itContTrct = contTract->Begin(); itContTrct != contTract->End(); ++itContTrct) { // init DTITube point DTITubePointType p; ContainerPointType cntp = itContTrct->Value(); p.SetPosition(cntp[0], cntp[1], cntp[2]); p.SetRadius(1); mitk::FiberBundle::fiberPostprocessing_setTensorMatrix( &p ); mitk::FiberBundle::fiberPostprocessing_FA( &p ); //mitk::FiberBundle::fiberPostprocessing_setTensorMatrix( &p ); p.AddField(DTITubePointType::GA, 3); p.SetColor(1,0,0,1); list.push_back(p); } // dtiTubes dtiTube->GetProperty()->SetName("dtiTube"); dtiTube->SetId(itCont->Index()); dtiTube->SetPoints(list); m_GroupFiberBundle->AddSpatialObject(dtiTube); } } void mitk::FiberBundle::fiberPostprocessing_setTensorMatrix(DTITubePointType *dtiP) { float tMatrix[6]; tMatrix[0]=0.0f; tMatrix[1]=1.0f; tMatrix[2]=2.0f; tMatrix[3]=3.0f; tMatrix[4]=4.0f; tMatrix[5]=5.0f; dtiP->SetTensorMatrix(tMatrix); } /* this method is a HowTo method, used for debugging only */ void mitk::FiberBundle::fiberPostprocessing_setPoint(DTITubePointType *dtiP, ContainerPointType vrtx) { /* get values of variable referenced by a ponter double vtxIdx1, vtxIdx2, vtxIdx3; vtxIdx1 = * (double*) &vrtx[0]; vtxIdx2 = * (double*) &vrtx[1]; vtxIdx3 = * (double*) &vrtx[2]; dtiP->SetPosition(vtxIdx1, vtxIdx2, vtxIdx3); */ dtiP->SetPosition(vrtx[0], vrtx[1], vrtx[2]); } void mitk::FiberBundle::fiberPostprocessing_FA(DTITubePointType *dtiP) { debug_PrototypeCounter ++; float valFA; if (debug_PrototypeCounter % 10 < 5) { valFA = 1.0; } else if (debug_PrototypeCounter % 10 == 7) { valFA = 0.3; } else if (debug_PrototypeCounter % 10 == 8) { valFA = 0; } else { valFA = 0.5; } dtiP->AddField(DTITubePointType::FA, valFA); } /* methods for high speed perfoermance dispay or live-monitoring of fiber results */ void mitk::FiberBundle::addContainer4speedDisplay(ContainerType::Pointer speedTractContainer) { } void mitk::FiberBundle::addSingleDTITract(mitk::FiberBundle::DTITubeType::Pointer dtiFbrTrct) { //MITK_INFO << " start addSingleDTITract(): " << m_GroupFiberBundle->GetNumberOfChildren(); m_GroupFiberBundle->AddSpatialObject(dtiFbrTrct); //MITK_INFO << "end addSingleDTITract(): " << m_GroupFiberBundle->GetNumberOfChildren(); } mitk::FiberBundle::FiberGroupType::Pointer mitk::FiberBundle::getGroupFiberBundle() { return m_GroupFiberBundle; } std::vector mitk::FiberBundle::getAllIDsInFiberBundle() { std::vector allFBIds; FiberGroupType::Pointer fiberGroup = this->getGroupFiberBundle(); ChildrenListType *FiberList; FiberList = fiberGroup->GetChildren(); for(ChildrenListType::iterator itLst = FiberList->begin(); itLst != FiberList->end(); ++itLst) { itk::SpatialObject<3>::Pointer tmp_fbr; tmp_fbr = *itLst; mitk::FiberBundle::DTITubeType::Pointer dtiTract = dynamic_cast< mitk::FiberBundle::DTITubeType * > (tmp_fbr.GetPointer()); if (dtiTract.IsNull()) { MITK_INFO << "DTI Tract is NULL!!!!! omg"; continue; } allFBIds.push_back(dtiTract->GetId()); } return allFBIds; } mitk::FiberBundle::Pointer mitk::FiberBundle::extractFibersById(std::vector idSet) { mitk::FiberBundle::Pointer resultingFibers = mitk::FiberBundle::New(); resultingFibers->SetGeometry(this->GetGeometry()); resultingFibers->SetBounds(this->GetBounds()); //get Fiber by ID //get childrenList //compare if current FiberID is in idSet FiberGroupType::Pointer fiberGroup = this->getGroupFiberBundle(); ChildrenListType *FiberList; FiberList = fiberGroup->GetChildren(); MITK_INFO << "writing fibers into datastructure:...."; for (int cg=0; cgPushTract( m_TractContainer->GetElement(trctId) ); } MITK_INFO << "init new fiberBundle..."; resultingFibers->initFiberGroup(); MITK_INFO << "init new fiberBundle [DONE]"; /* for(ChildrenListType::iterator itLst = FiberList->begin(); itLst != FiberList->end(); ++itLst) { itk::SpatialObject<3>::Pointer tmp_fbr; tmp_fbr = *itLst; mitk::FiberBundle::DTITubeType::Pointer dtiTract = dynamic_cast< mitk::FiberBundle::DTITubeType * > (tmp_fbr.GetPointer()); if (dtiTract.IsNull()) { MITK_INFO << "DTI Tract is NULL!!!!! omg"; continue; } // MITK_INFO << "current DTI tract id: " << dtiTract->GetId(); std::vector::iterator retFibers = find(idSet.begin(), idSet.end(), dtiTract->GetId()); if (retFibers != idSet.end()) { //MITK_INFO << "Fiber and ID equal: "; DTITubeType::Pointer copyDTITract = this->copySingleDTITract(dtiTract); MITK_INFO << "fibercontainer before adding new tract" << resultingFibers->GetNumTracts(); resultingFibers->addSingleDTITract(copyDTITract); MITK_INFO << "fibercontainer after adding new tract" << resultingFibers->GetNumTracts(); } //else { // MITK_INFO << "Fiber and ID not ident!"; //} //std::set::iterator retFibers //retFibers = idSet.find(dtiTract->GetId()); } */ return resultingFibers; } /* extract fibers using planar Figures */ //mitk::FiberBundle::Pointer mitk::FiberBundle::extractFibersPF(mitk::PlanarFigure::Pointer pf) std::vector mitk::FiberBundle::extractFibersByPF(mitk::PlanarFigure::Pointer pf, std::vector* smaller_set) { // if incoming pf is a pfc mitk::PlanarFigureComposite::Pointer pfcomp= dynamic_cast(pf.GetPointer()); if (!pfcomp.IsNull()) { //PFC switch (pfcomp->getOperationType()) { case 0: { //AND std::vector childResults = this->extractFibersByPF(pfcomp->getChildAt(0), smaller_set); std::vector tmpChild = childResults; for (int i=1; igetNumberOfChildren(); ++i) { tmpChild = extractFibersByPF(pfcomp->getChildAt(i),&tmpChild); } std::vector AND_Assamblage(tmpChild.begin(), tmpChild.end()); return AND_Assamblage; } case 1: { //OR std::vector childResults = this->extractFibersByPF(pfcomp->getChildAt(0), smaller_set); std::sort(childResults.begin(), childResults.end()); std::vector tmp_container(m_TractContainer->Size()); std::vector::iterator end; for (int i=1; igetNumberOfChildren(); ++i) { std::vector tmpChild = extractFibersByPF(pfcomp->getChildAt(i), smaller_set); sort(tmpChild.begin(), tmpChild.end()); end = std::set_union(childResults.begin(), childResults.end(), tmpChild.begin(), tmpChild.end(), tmp_container.begin() ); childResults.assign(tmp_container.begin(), end); } std::vector OR_Assamblage(childResults.begin(), childResults.end()); return OR_Assamblage; } case 2: { //NOT // FIRST AN AND OPERATION std::vector childResults = this->extractFibersByPF(pfcomp->getChildAt(0), smaller_set); std::sort(childResults.begin(), childResults.end()); std::vector tmpChild = childResults; for (int i=1; igetNumberOfChildren(); ++i) { tmpChild = extractFibersByPF(pfcomp->getChildAt(i),&tmpChild); } std::vector AND_Assamblage(tmpChild.begin(), tmpChild.end()); // get IDs of interesting fibers std::vector interesting_fibers; if(!smaller_set) interesting_fibers = this->getAllIDsInFiberBundle(); else interesting_fibers.assign(smaller_set->begin(), smaller_set->end()); std::sort(interesting_fibers.begin(), interesting_fibers.end()); // all interesting fibers that are not in the AND assemblage std::vector tmp_not(interesting_fibers.size()); std::vector::iterator end; end = std::set_difference(interesting_fibers.begin(), interesting_fibers.end(), AND_Assamblage.begin(), AND_Assamblage.end(), tmp_not.begin() ); std::vector NOT_Assamblage(tmp_not.begin(),end); return NOT_Assamblage; } default: MITK_INFO << "we have an UNDEFINED composition... ERROR" ; break; } } else { mitk::PlanarCircle::Pointer circleName = mitk::PlanarCircle::New(); mitk::PlanarRectangle::Pointer rectName = mitk::PlanarRectangle::New(); mitk::PlanarPolygon::Pointer polyName = mitk::PlanarPolygon::New(); if (pf->GetNameOfClass() == circleName->GetNameOfClass() ) { //MITK_INFO << "We have a circle :-) " ; int cntGaps = 0; //init output FiberBundle mitk::FiberBundle::Pointer FB_Clipped = mitk::FiberBundle::New(); FB_Clipped->SetGeometry(this->GetGeometry()); //get geometry containing the plane which we need to calculate the xrossingPoints mitk::Geometry2D::ConstPointer pfgeometry = pf->GetGeometry2D(); const mitk::PlaneGeometry* planeGeometry = dynamic_cast (pfgeometry.GetPointer()); std::vector XingPoints; std::vector fiberIDs; //################################################################# //############### Find Gap, FrontFace BackFace #################### //################################################################# //get fibercontainer and iterate through the fibers FiberGroupType::Pointer fiberGroup = this->getGroupFiberBundle(); //extract single fibers ChildrenListType *FiberList; FiberList = fiberGroup->GetChildren(); // iterate through each single tract //int cntFibId = -1; for(ChildrenListType::iterator itLst = FiberList->begin(); itLst != FiberList->end(); ++itLst) { //MITK_INFO << "***************** NEW FIBER *********************"; //cntFibId++; itk::SpatialObject<3>::Pointer tmp_fbr; tmp_fbr = *itLst; mitk::FiberBundle::DTITubeType::Pointer dtiTract = dynamic_cast< mitk::FiberBundle::DTITubeType * > (tmp_fbr.GetPointer()); if (dtiTract.IsNull()) { MITK_INFO << " could not cast groupFiberBundle child into dtiTract!... LEVEL 4 ERROR"; continue; } if (smaller_set && std::find(smaller_set->begin(), smaller_set->end(), dtiTract->GetId())==smaller_set->end()) continue; //get list of points int fibrNrPnts = dtiTract->GetNumberOfPoints(); mitk::FiberBundle::DTITubeType::PointListType dtiPntList = dtiTract->GetPoints(); // if one fiber is represented by just one point.... // check if this point is on the plane if (fibrNrPnts <= 0) { MITK_INFO << "HyperERROR in mitkFiberBundle.cpp, No point in fiber....check ur algorithm:"; continue; } /* for finding a gap we need to have knowledge of the previous normal * be aware that there can be more than 1 gaps! */ int prevPntFacing = -999999; int currPntFacing = -999999; //double prevFacing = -99999999099; mitk::Point3D prevFiberPntmm; for(int i=0; iGetGeometry()->IndexToWorld(tmpFiberVec, currentFiberPntmm); double faceing = pfgeometry->SignedDistance(currentFiberPntmm); //MITK_INFO << "FacingOutput: " << faceing; /////////////////////////////////////// if (faceing < 0) { //backface currPntFacing = TRACTPOINT_BACKFACE; //MITK_INFO << "is BACKFACE" << currentFiberPntmm ; } else if (faceing > 0) { //frontface currPntFacing = TRACTPOINT_FRNTFACE; // MITK_INFO << "is FRONTFACE" << currentFiberPntmm ; } else if (faceing == 0) { //onplane currPntFacing = TRACTPOINT_ON_PLANE; //MITK_INFO << "is on PLANE" << currentFiberPntmm ; } //////////////////////////////////////// if (currPntFacing == TRACTPOINT_ON_PLANE) { //strike, //calculate distance //TODO SOURCE THIS CONTROLSTRUCTURE OUT if(isPointInSelection(tmpFiberVec,pf)) { DTITubeType::Pointer copyDTITract = copySingleDTITract(dtiTract); //MITK_INFO << "GroupFB extract after copy of Children: " << fiberGroup->GetNumberOfChildren(); FB_Clipped->addSingleDTITract(copyDTITract); } } else { // Point is BACKFACE or FRONTFACE if (i > 0) { //check if there is a gap between previous and current bool isGap = checkForGap(currPntFacing, prevPntFacing); if (isGap == true) { ++cntGaps; // mitk::Vector3D LineDirection; LineDirection[0] = currentFiberPntmm[0] - prevFiberPntmm[0]; LineDirection[1] = currentFiberPntmm[1] - prevFiberPntmm[1]; LineDirection[2] = currentFiberPntmm[2] - prevFiberPntmm[2]; mitk::Line3D Xingline( prevFiberPntmm, LineDirection ); mitk::Point3D intersectionPoint; Vector3D planeNormal = planeGeometry->GetNormal(); planeNormal.Normalize(); Vector3D lineDirection = Xingline.GetDirection(); lineDirection.Normalize(); double t = planeNormal * lineDirection; if ( fabs( t ) < eps ) { } Vector3D diff; diff = planeGeometry->GetOrigin() - Xingline.GetPoint(); t = ( planeNormal * diff ) / t; intersectionPoint = Xingline.GetPoint() + lineDirection * t; // bool successXing = planeGeometry->IntersectionPoint( Xingline, intersectionPoint ); //mitk::Point3D intersectionPointmm; //planeGeometry->IndexToWorld(intersectionPoint,intersectionPointmm ); // MITK_INFO << "PlaneIntersectionPoint: " << intersectionPoint; if (false) { MITK_INFO << " ERROR CALCULATING INTERSECTION POINT.....should not happen!! "; } //TODO more nice if this if is outside... bool pntInROI = isPointInSelection(intersectionPoint,pf); if(pntInROI) { // MITK_INFO << "POINT ALSO in ROI"; // MITK_INFO << "GroupFB extract before copy new object. of Children: " << fiberGroup->GetNumberOfChildren(); /* dtiTubeSpatial::Pointer can not occur in 2 GroupSpatialObjects, therefore we have to copy the whole dtiTract of current List and add the copy to the desired FiberBundle */ // DTITubeType::Pointer copyDTITract = copySingleDTITract(dtiTract); // MITK_INFO << "GroupFB extract after copy of Children: " << fiberGroup->GetNumberOfChildren(); //FB_Clipped->addSingleDTITract(copyDTITract); //MITK_INFO << "GroupFB extract after adding dtiTract to now FB NR. of Children: " << fiberGroup->GetNumberOfChildren(); //MITK_INFO << "DTI Tract ID: " << dtiTract->GetId(); // MITK_INFO << "size of Vector before pushing: " << fiberIDs.size(); fiberIDs.push_back(dtiTract->GetId()); // MITK_INFO << "size of Vector after pushing: " << fiberIDs.size(); //MITK_INFO << "GroupFB extract after adding dtiTract to now FB NR. of Children: " << fiberGroup->GetNumberOfChildren(); break; } } // MITK_INFO << "---no gap---"; } //endif i>0 } //endif Facing // MITK_INFO << "GroupFB extract end Facing, NR. of Children: " << fiberGroup->GetNumberOfChildren(); //update point flag prevPntFacing = currPntFacing; prevFiberPntmm = currentFiberPntmm; } //end for fiberPoints //MITK_INFO ;<< "GroupFB extract end of single tract, NR. of Children: " << fiberGroup->GetNumberOfChildren(); } //end for fiberTracts // MITK_INFO << "GroupFB extract end of iterating through fiberBundle, NR. of Children: " << fiberGroup->GetNumberOfChildren(); // MITK_INFO << "selected " << fiberIDs.size() << " fibers " << " | counted gaps: " << cntGaps; return fiberIDs; } else if (pf->GetNameOfClass() == rectName->GetNameOfClass() ){ MITK_INFO << "We have a rectangle :-) " ; } else if (pf->GetNameOfClass() == polyName->GetNameOfClass() ) { //MITK_INFO << "We have a polygon :-) " ; int cntGaps = 0; //init output FiberBundle mitk::FiberBundle::Pointer FB_Clipped = mitk::FiberBundle::New(); FB_Clipped->SetGeometry(this->GetGeometry()); //get geometry containing the plane which we need to calculate the xrossingPoints mitk::Geometry2D::ConstPointer pfgeometry = pf->GetGeometry2D(); const mitk::PlaneGeometry* planeGeometry = dynamic_cast (pfgeometry.GetPointer()); std::vector XingPoints; std::vector fiberIDs; //################################################################# //############### Find Gap, FrontFace BackFace #################### //################################################################# //get fibercontainer and iterate through the fibers FiberGroupType::Pointer fiberGroup = this->getGroupFiberBundle(); //extract single fibers ChildrenListType *FiberList; FiberList = fiberGroup->GetChildren(); int nrFibrs = fiberGroup->GetNumberOfChildren(); // iterate through each single tract int cntFib = 1; for(ChildrenListType::iterator itLst = FiberList->begin(); itLst != FiberList->end(); ++itLst) { if (cntFib % 500 == 0) { MITK_INFO << "================\n prosessed fibers: " << cntFib << " of " << nrFibrs;; } ++cntFib; //MITK_INFO << "***************** NEW FIBER *********************"; //cntFibId++; itk::SpatialObject<3>::Pointer tmp_fbr; tmp_fbr = *itLst; mitk::FiberBundle::DTITubeType::Pointer dtiTract = dynamic_cast< mitk::FiberBundle::DTITubeType * > (tmp_fbr.GetPointer()); if (dtiTract.IsNull()) { MITK_INFO << " could not cast groupFiberBundle child into dtiTract!... LEVEL 4 ERROR"; continue; } if (smaller_set && std::find(smaller_set->begin(), smaller_set->end(), dtiTract->GetId())==smaller_set->end()) continue; //get list of points int fibrNrPnts = dtiTract->GetNumberOfPoints(); mitk::FiberBundle::DTITubeType::PointListType dtiPntList = dtiTract->GetPoints(); // if one fiber is represented by just one point.... // check if this point is on the plane if (fibrNrPnts <= 0) { MITK_INFO << "HyperERROR in mitkFiberBundle.cpp, No point in fiber....check ur algorithm:"; continue; } /* for finding a gap we need to have knowledge of the previous normal * be aware that there can be more than 1 gaps! */ int prevPntFacing = -999999; int currPntFacing = -999999; //double prevFacing = -99999999099; mitk::Point3D prevFiberPntmm; for(int i=0; iGetGeometry()->IndexToWorld(tmpFiberVec, currentFiberPntmm); double faceing = pfgeometry->SignedDistance(currentFiberPntmm); //MITK_INFO << "FacingOutput: " << faceing; /////////////////////////////////////// if (faceing < 0) { //backface currPntFacing = TRACTPOINT_BACKFACE; //MITK_INFO << "is BACKFACE" << currentFiberPntmm ; } else if (faceing > 0) { //frontface currPntFacing = TRACTPOINT_FRNTFACE; // MITK_INFO << "is FRONTFACE" << currentFiberPntmm ; } else if (faceing == 0) { //onplane currPntFacing = TRACTPOINT_ON_PLANE; //MITK_INFO << "is on PLANE" << currentFiberPntmm ; } //////////////////////////////////////// if (currPntFacing == TRACTPOINT_ON_PLANE) { //strike, //calculate distance //TODO SOURCE THIS CONTROLSTRUCTURE OUT if(isPointInSelection(tmpFiberVec,pf)) { DTITubeType::Pointer copyDTITract = copySingleDTITract(dtiTract); //MITK_INFO << "GroupFB extract after copy of Children: " << fiberGroup->GetNumberOfChildren(); FB_Clipped->addSingleDTITract(copyDTITract); } } else { // Point is BACKFACE or FRONTFACE if (i > 0) { //check if there is a gap between previous and current bool isGap = checkForGap(currPntFacing, prevPntFacing); if (isGap == true) { ++cntGaps; // mitk::Vector3D LineDirection; LineDirection[0] = currentFiberPntmm[0] - prevFiberPntmm[0]; LineDirection[1] = currentFiberPntmm[1] - prevFiberPntmm[1]; LineDirection[2] = currentFiberPntmm[2] - prevFiberPntmm[2]; mitk::Line3D Xingline( prevFiberPntmm, LineDirection ); mitk::Point3D intersectionPoint; Vector3D planeNormal = planeGeometry->GetNormal(); planeNormal.Normalize(); Vector3D lineDirection = Xingline.GetDirection(); lineDirection.Normalize(); double t = planeNormal * lineDirection; if ( fabs( t ) < eps ) { } Vector3D diff; diff = planeGeometry->GetOrigin() - Xingline.GetPoint(); t = ( planeNormal * diff ) / t; intersectionPoint = Xingline.GetPoint() + lineDirection * t; // bool successXing = planeGeometry->IntersectionPoint( Xingline, intersectionPoint ); //mitk::Point3D intersectionPointmm; //planeGeometry->IndexToWorld(intersectionPoint,intersectionPointmm ); // MITK_INFO << "PlaneIntersectionPoint: " << intersectionPoint; if (false) { MITK_INFO << " ERROR CALCULATING INTERSECTION POINT.....should not happen!! "; } //TODO more nice if this if is outside... bool pntInROI = isPointInSelection(intersectionPoint,pf); if(pntInROI) { // MITK_INFO << "POINT ALSO in ROI"; // MITK_INFO << "GroupFB extract before copy new object. of Children: " << fiberGroup->GetNumberOfChildren(); /* dtiTubeSpatial::Pointer can not occur in 2 GroupSpatialObjects, therefore we have to copy the whole dtiTract of current List and add the copy to the desired FiberBundle */ // DTITubeType::Pointer copyDTITract = copySingleDTITract(dtiTract); // MITK_INFO << "GroupFB extract after copy of Children: " << fiberGroup->GetNumberOfChildren(); //FB_Clipped->addSingleDTITract(copyDTITract); //MITK_INFO << "GroupFB extract after adding dtiTract to now FB NR. of Children: " << fiberGroup->GetNumberOfChildren(); //MITK_INFO << "DTI Tract ID: " << dtiTract->GetId(); // MITK_INFO << "size of Vector before pushing: " << fiberIDs.size(); fiberIDs.push_back(dtiTract->GetId()); // MITK_INFO << "size of Vector after pushing: " << fiberIDs.size(); //MITK_INFO << "GroupFB extract after adding dtiTract to now FB NR. of Children: " << fiberGroup->GetNumberOfChildren(); break; } } // MITK_INFO << "---no gap---"; } //endif i>0 } //endif Facing // MITK_INFO << "GroupFB extract end Facing, NR. of Children: " << fiberGroup->GetNumberOfChildren(); //update point flag prevPntFacing = currPntFacing; prevFiberPntmm = currentFiberPntmm; } //end for fiberPoints //MITK_INFO ;<< "GroupFB extract end of single tract, NR. of Children: " << fiberGroup->GetNumberOfChildren(); } //end for fiberTracts // MITK_INFO << "GroupFB extract end of iterating through fiberBundle, NR. of Children: " << fiberGroup->GetNumberOfChildren(); // MITK_INFO << "selected " << fiberIDs.size() << " fibers " << " | counted gaps: " << cntGaps; return fiberIDs; } else { MITK_INFO << "[ERROR] unhandled PlanarFigureType found!"; } } } mitk::FiberBundle::DTITubeType::Pointer mitk::FiberBundle::copySingleDTITract(mitk::FiberBundle::DTITubeType::Pointer currentDtiFiber) { DTITubeType::Pointer newCopyDtiFiber = DTITubeType::New(); //*** get ID newCopyDtiFiber->SetId( currentDtiFiber->GetId() ); //*** get points DTITubeType::PointListType list; //get list of dtiPoints int fibrNrPnts = currentDtiFiber->GetNumberOfPoints(); mitk::FiberBundle::DTITubeType::PointListType dtiPntList = currentDtiFiber->GetPoints(); for(int i=0; iSetPoints(list); std::string dtiname = currentDtiFiber->GetProperty()->GetName(); newCopyDtiFiber->GetProperty()->SetName(dtiname.c_str()); return newCopyDtiFiber; } /* This Method checks * To recognize a gap between the 2 points, the previous must differ from the current * but if the previous is on the plane and the current one not, then mark this situation as no gap * if both, previous and current are on plane, you'll never jump into this Method */ bool mitk::FiberBundle::checkForGap(int crntPntFacing, int prevPntFacing) { bool isGap = false; if (prevPntFacing != TRACTPOINT_ON_PLANE && crntPntFacing != prevPntFacing) { isGap = true; } else if (prevPntFacing == TRACTPOINT_ON_PLANE && crntPntFacing == TRACTPOINT_ON_PLANE) { MITK_INFO << "###########################################"; MITK_INFO << "$$$ HYPER ERROR, LOGIC MALFUNCTION!! previous point and current point in a fiber are recognized as a potential GAP! THIS IS NOT ALLOWED $$$"; MITK_INFO << "###########################################"; } return isGap; } mitk::Point3D mitk::FiberBundle::calculateCrossingPoint(mitk::Point3D pntFrnt, mitk::Point3D pntbck, mitk::PlanarFigure::Pointer pf) { mitk::Point3D pntXing; //################################################################# //######### Calculate intersection of plane and fiber ############# //################################################################# // transform in space :-) // y = k*x +d // k = (y1 - y0)/(x1 - x0) // d = ok // z adoption, take xy ratio to plane intersection and adopt it to z coordinate // z_intersx = (x1 - intersX)/(x1 - x0) * (z1 - z0) + z1 double y; double k; //slope double d; double x0 = pntFrnt[0]; double y0 = pntFrnt[1]; double z0 = pntFrnt[2]; double x1 = pntbck[0]; double y1 = pntbck[1]; double z1 = pntbck[2]; k = (y1 - y0) / (x1 - x0); // if slope == 0 then leave y as it is, change x // if slope == 1 then leave x as it is, change y // if z of p0 and p1 is the same, just take z /* mitk::PlanarCircle::Pointer circleName = mitk::PlanarCircle::New(); mitk::PlanarRectangle::Pointer rectName = mitk::PlanarRectangle::New(); mitk::PlanarPolygon::Pointer polyName = mitk::PlanarPolygon::New(); if (pf->GetNameOfClass() == circleName->GetNameOfClass() ) { MITK_INFO << "We have a circle :-) " ; //controlpoint 1 is middlepoint //controlpoint 2 is radiuspoint mitk::Vector3D V1w = pf->GetWorldControlPoint(0); //centerPoint mitk::Vector3D V2w = pf->GetWorldControlPoint(1); //radiusPoint mitk::Vector3D V1; mitk::Vector3D V2; this->GetGeometry()->WorldToIndex(V1w, V1); this->GetGeometry()->WorldToIndex(V2w, V2); //calculate distance between those 2 and mitk::Point3D distV; distV = V2 - V1; distV[0] = sqrt( pow(distV[0], 2.0) ); distV[1] = sqrt( pow(distV[1], 2.0) ); distV[2] = sqrt( pow(distV[2], 2.0) ); mitk::Point3D distPnt; distPnt = pnt3D - V1; distPnt[0] = sqrt( pow(distPnt[0], 2.0) ); distPnt[1] = sqrt( pow(distPnt[1], 2.0) ); distPnt[2] = sqrt( pow(distPnt[2], 2.0) ); if ( (distPnt <= distV) ) { pntIsInside = true; } return pntIsInside; //compare the result to the distance of all points an a fiber } else if (pf->GetNameOfClass() == rectName->GetNameOfClass() ){ MITK_INFO << "We have a rectangle :-) " ; } else if (pf->GetNameOfClass() == polyName->GetNameOfClass() ) { MITK_INFO << "We have a polygon :-) " ; } */ return pntXing; } bool mitk::FiberBundle::isPointInSelection(mitk::Point3D pnt3D, mitk::PlanarFigure::Pointer pf) { /* TODO needs to be redesigned.... each time because in planarPolygonsection VTK object will be initialized for each point!...PERFORMANCE LACK!!!!!!! */ //calculate distances mitk::PlanarCircle::Pointer circleName = mitk::PlanarCircle::New(); mitk::PlanarRectangle::Pointer rectName = mitk::PlanarRectangle::New(); mitk::PlanarPolygon::Pointer polyName = mitk::PlanarPolygon::New(); if (pf->GetNameOfClass() == circleName->GetNameOfClass() ) { //MITK_INFO << "We have a circle :-) " ; //controlpoint 1 is middlepoint //controlpoint 2 is radiuspoint mitk::Point3D V1w = pf->GetWorldControlPoint(0); //centerPoint mitk::Point3D V2w = pf->GetWorldControlPoint(1); //radiusPoint mitk::Vector3D V1; mitk::Vector3D V2; // this->GetGeometry()->WorldToIndex(V1w, V1); // this->GetGeometry()->WorldToIndex(V2w, V2); //calculate distance between those 2 and double distPF; distPF = sqrt((double) (V2w[0] - V1w[0]) * (V2w[0] - V1w[0]) + (V2w[1] - V1w[1]) * (V2w[1] - V1w[1]) + (V2w[2] - V1w[2]) * (V2w[2] - V1w[2])); double XdistPnt = sqrt((double) (pnt3D[0] - V1w[0]) * (pnt3D[0] - V1w[0]) + (pnt3D[1] - V1w[1]) * (pnt3D[1] - V1w[1]) + (pnt3D[2] - V1w[2]) * (pnt3D[2] - V1w[2])) ; if ( (distPF > XdistPnt) ) { return true; } return false; //compare the result to the distance of all points an a fiber } else if (pf->GetNameOfClass() == rectName->GetNameOfClass() ){ MITK_INFO << "We have a rectangle :-) " ; } else if (pf->GetNameOfClass() == polyName->GetNameOfClass() ) { //create vtkPolygon using controlpoints from planarFigure polygon vtkPolygon* polygonVtk = vtkPolygon::New(); //get the control points from pf and insert them to vtkPolygon unsigned int nrCtrlPnts = pf->GetNumberOfControlPoints(); // MITK_INFO << "We have a polygon with " << nrCtrlPnts << " controlpoints: " ; for (int i=0; iGetPoints()->InsertNextPoint((double)pf->GetWorldControlPoint(i)[0], (double)pf->GetWorldControlPoint(i)[1], (double)pf->GetWorldControlPoint(i)[2] ); } //prepare everything for using pointInPolygon function double n[3]; polygonVtk->ComputeNormal(polygonVtk->GetPoints()->GetNumberOfPoints(), static_cast(polygonVtk->GetPoints()->GetData()->GetVoidPointer(0)), n); double bounds[6]; polygonVtk->GetPoints()->GetBounds(bounds); double checkIn[3] = {pnt3D[0], pnt3D[1], pnt3D[2]}; int isInPolygon = polygonVtk->PointInPolygon(checkIn, polygonVtk->GetPoints()->GetNumberOfPoints() , static_cast(polygonVtk->GetPoints()->GetData()->GetVoidPointer(0)), bounds, n); // MITK_INFO << "======IsPointOnPolygon:========\n" << isInPolygon << "\n ======================== "; polygonVtk->Delete(); if (isInPolygon == 1) { // MITK_INFO << "return true"; return true; } else if (isInPolygon == 0) { // MITK_INFO << "return false"; return false; } else { MITK_INFO << "&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*& \n YOUR DRAWN POLYGON DOES IS DEGENERATED AND NOT ACCEPTED \n DRAW A NEW ONE!! HAI CAPITO \n &*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&"; } } } void mitk::FiberBundle::debug_members() { /* Debug Workflow description * Test1: check if both, groupSpatialObject and Tract container have the same amount of fiberTracts * Test2: check if points in tracts contain the same coordinates * next... to be continued */ /* ######### TEST 1 START ######### */ //************************************* MITK_INFO << " ############### \n *** TEST Equal Amount of Fibers *** \n "; unsigned int groupEls = m_GroupFiberBundle->GetNumberOfChildren(); unsigned int contEls = m_TractContainer->Size(); unsigned int itkcontEls = m_debugITKContainer->Size(); if (groupEls == contEls && contEls == itkcontEls) { MITK_INFO << "[OK] .... Test1 passed. # of Fibers: " << groupEls << " \n ******************** "; } else { MITK_INFO << "[FAIL]: Container and FiberGroup do not contain same amount of fibers! \n "; // MITK_INFO << " Container # of Fibers: " << contEls << " | FiberBundle # of Fibers: " << groupEls << "\n"; MITK_INFO << " # of Fibers m_Cont: " << contEls << " | GroupFibers: " << groupEls << " | ITKCont: " << itkcontEls << "\n"; } /* ######### TEST 1 END ######### */ //*********************************** /* ######### TEST 2 START ######### */ //************************************* /* iterate through itkcontainer*/ itkStochTractContainerType::ConstIterator itITKCnt; itITKCnt = m_debugITKContainer->Begin(); /* extract DTIFiberTracts of the GroupFiberBundle Object */ // all smartPointers to fibers stored in in a ChildrenList ChildrenListType * FiberList; FiberList = m_GroupFiberBundle->GetChildren(); /* iterate through container, itkcontainer groupFiberBundle in one iteration step */ ChildrenListType::iterator itLst; //STL "list" itself provides no index output of current iteration step. itLst = FiberList->begin(); ContainerType::ConstIterator vecIter; for ( vecIter = m_TractContainer->Begin(); vecIter != m_TractContainer->End(); vecIter++ ) { unsigned int itIdx = vecIter->Index(); MITK_INFO << "FiberIteration: " << itIdx << "\n" ; //get single tract of container ContainerTractType::Pointer contTract = vecIter->Value(); int contNrPnts = contTract->Size(); //get singel tract of itkContainer itkStochTractType::Pointer itkcontTract = itITKCnt->Value(); itkStochTractType::VertexListType::ConstPointer itkcontVrtx = itkcontTract->GetVertexList(); int itkcontNrPnts = itkcontVrtx->Size(); /* lists output is SpatialObject, we know we have DTITubeSpacialObjects dynamic cast only likes pointers, no smartpointers, so each dsmartpointer has membermethod .GetPointer() */ itk::SpatialObject<3>::Pointer tmp_fbr; tmp_fbr = *itLst; DTITubeType::Pointer dtiTract = dynamic_cast (tmp_fbr.GetPointer()); if (dtiTract.IsNull()) { MITK_INFO << " ############### *** ERRROR *** ############### \n ############### *** ERRROR *** ############### \n ############### *** ERRROR *** ############### \n "; return; } //get points of tract int fibrNrPnts = dtiTract->GetNumberOfPoints(); DTITubeType::PointListType dtiPntList = dtiTract->GetPoints(); MITK_INFO << " ############### \n *** TEST Equal Amount of Points in Tract *** \n "; if (contNrPnts == itkcontNrPnts && itkcontNrPnts == fibrNrPnts) { MITK_INFO << "[OK] .... Test2 passed. # of Points in fiber: " << fibrNrPnts << " \n ******************** "; } else { MITK_INFO << "[FAIL]: Tracts do not contain same amount of points! \n "; MITK_INFO << " # of Points m_Cont: " << contNrPnts << " | GroupFibers: " << fibrNrPnts << " | ITKCont: " << itkcontNrPnts << "\n"; } //use for()loop with index instead of iterator cuz of accessing more elements, std vectors provide no index output for(int ip=0; ipGetElement(ip); //get point from itkStochContainer itkStochTractType::VertexType itkPnt = itkcontVrtx->GetElement(ip); //get point from dtiGroup DTITubePointType tmpDtiPnt = dtiPntList.at(ip); DTITubePointType::PointType dtiPoint = tmpDtiPnt.GetPosition(); if (tmpcontPnt[0] == (float)itkPnt[0] && (float)itkPnt[0] == (float)dtiPoint[0]) { MITK_INFO << "TractCont | ITKCont | DTIGroup X: " << tmpcontPnt[0] << "...TEST [OK] " << "\n"; }else{ MITK_INFO << "TractCont | ITKCont | DTIGroup X: " << tmpcontPnt[0] << " " << itkPnt[0] << " " << dtiPoint[0] << "...TEST ##### [FAIL] \n"; } if (tmpcontPnt[1] == (float)itkPnt[1] && (float)itkPnt[1] == (float)dtiPoint[1]) { MITK_INFO << "TractCont | ITKCont | DTIGroup Y: " << tmpcontPnt[1] << "...TEST [OK] " << "\n"; }else{ MITK_INFO << "TractCont | ITKCont | DTIGroup Y: " << tmpcontPnt[1] << " " << itkPnt[1] << " " << dtiPoint[1] << "\n"; } if (tmpcontPnt[2] == (float)itkPnt[2] && (float)itkPnt[2] == (float)dtiPoint[2]) { MITK_INFO << "TractCont | ITKCont | DTIGroup Z: " << tmpcontPnt[2] << "...TEST [OK] " << "\n"; }else{ MITK_INFO << "TractCont | ITKCont | DTIGroup Z: " << tmpcontPnt[2] << " " << itkPnt[2] << " " << dtiPoint[2] << "\n"; } } ++itITKCnt; ++itLst; } } vtkPolyData* mitk::FiberBundle::GeneratePolydata() { MITK_INFO << "writing polydata"; //extractn single fibers //in the groupFiberBundle all smartPointers to single fibers are stored in in a ChildrenList mitk::FiberBundle::ChildrenListType * FiberList; FiberList = this->m_GroupFiberBundle->GetChildren(); /* ######## FIBER PREPARATION END ######### */ /* ######## VTK FIBER REPRESENTATION ######## */ //create a vtkPoints object and store the all the brainFiber points in it vtkPoints *vtkpoints = vtkPoints::New(); //in vtkcells all polylines are stored, actually all id's of them are stored vtkCellArray *vtkcells = vtkCellArray::New(); //in some cases a fiber includes just 1 point, so put it in here vtkCellArray *vtkVrtxs = vtkCellArray::New(); //colors and alpha value for each single point, RGBA = 4 components vtkUnsignedCharArray *colorsT = vtkUnsignedCharArray::New(); colorsT->SetNumberOfComponents(4); colorsT->SetName("ColorValues"); vtkDoubleArray *faColors = vtkDoubleArray::New(); faColors->SetName("FaColors"); //vtkDoubleArray *tubeRadius = vtkDoubleArray::New(); //tubeRadius->SetName("TubeRadius"); // iterate through FiberList for(mitk::FiberBundle::ChildrenListType::iterator itLst = FiberList->begin(); itLst != FiberList->end(); ++itLst) { //all points are stored in one vtkpoints list, soooooooo that the lines find their point id to start and end we need some kind of helper index who monitors the current ids for a polyline unsigned long pntIdxHelper = vtkpoints->GetNumberOfPoints(); // lists output is SpatialObject, we know we have DTITubeSpacialObjects // dynamic cast only likes pointers, no smartpointers, so each dsmartpointer has membermethod .GetPointer() itk::SpatialObject<3>::Pointer tmp_fbr; tmp_fbr = *itLst; mitk::FiberBundle::DTITubeType::Pointer dtiTract = dynamic_cast< mitk::FiberBundle::DTITubeType * > (tmp_fbr.GetPointer()); if (dtiTract.IsNull()) { return NULL; } //get list of points int fibrNrPnts = dtiTract->GetNumberOfPoints(); mitk::FiberBundle::DTITubeType::PointListType dtiPntList = dtiTract->GetPoints(); //create a new polyline for a dtiTract //smartpointer vtkPolyLine *polyLine = vtkPolyLine::New(); polyLine->GetPointIds()->SetNumberOfIds(fibrNrPnts); unsigned char rgba[4] = {255,255,255,255}; //tubeRadius->SetNumberOfTuples(fibrNrPnts); //double tbradius = 1;//default value for radius if (fibrNrPnts <= 0) { //this should never occour! but who knows MITK_INFO << "HyperERROR in fiberBundleMapper3D.cpp ...no point in fiberBundle!!! .. check ur trackingAlgorithm"; continue; } for (int i=0; iGetGeometry()->IndexToWorld(indexPnt, worldPnt); double worldFbrPnt[3] = {worldPnt[0], worldPnt[1], worldPnt[2]}; vtkpoints->InsertNextPoint(worldFbrPnt); // tubeRadius->SetTuple1(i,tbradius); //tuple with 1 argument if (fibrNrPnts == 1) { // if there ist just 1 point in a fiber...wtf, but however represent it as a point vtkVertex *vrtx = vtkVertex::New(); vrtx->GetPointIds()->SetNumberOfIds(1); vrtx->GetPointIds()->SetId(i,i+pntIdxHelper); colorsT->InsertNextTupleValue(rgba); vtkVrtxs->InsertNextCell(vrtx); } else { polyLine->GetPointIds()->SetId(i,i+pntIdxHelper); //colorcoding orientation based if (i0) { //nimm nur diff1 mitk::FiberBundle::DTITubePointType nxttmpFiberPntLst = dtiPntList.at(i+1); mitk::FiberBundle::DTITubePointType::PointType nxttmpFiberPnt = nxttmpFiberPntLst.GetPosition(); //double nxttmpvtkPnt[3] = {nxttmpFiberPnt[0], nxttmpFiberPnt[1], nxttmpFiberPnt[2]}; vnl_vector_fixed< double, 3 > tmpPntvtk((double)tmpvtkPnt[0], (double)tmpvtkPnt[1],(double)tmpvtkPnt[2]); vnl_vector_fixed< double, 3 > nxttmpPntvtk(nxttmpFiberPnt[0], nxttmpFiberPnt[1], nxttmpFiberPnt[2]); vnl_vector_fixed< double, 3 > diff; diff = tmpPntvtk - nxttmpPntvtk; diff.normalize(); rgba[0] = (unsigned char) (255.0 * std::abs(diff[0])); rgba[1] = (unsigned char) (255.0 * std::abs(diff[1])); rgba[2] = (unsigned char) (255.0 * std::abs(diff[2])); rgba[3] = (unsigned char) (255.0); } else if(i==0) { //explicit handling of startpoint of line //nimm nur diff1 mitk::FiberBundle::DTITubePointType nxttmpFiberPntLst = dtiPntList.at(i+1); mitk::FiberBundle::DTITubePointType::PointType nxttmpFiberPnt = nxttmpFiberPntLst.GetPosition(); //double nxttmpvtkPnt[3] = {nxttmpFiberPnt[0], nxttmpFiberPnt[1], nxttmpFiberPnt[2]}; vnl_vector_fixed< double, 3 > tmpPntvtk((double)tmpvtkPnt[0], (double)tmpvtkPnt[1],(double)tmpvtkPnt[2]); vnl_vector_fixed< double, 3 > nxttmpPntvtk(nxttmpFiberPnt[0], nxttmpFiberPnt[1], nxttmpFiberPnt[2]); vnl_vector_fixed< double, 3 > diff; diff = tmpPntvtk - nxttmpPntvtk; diff.normalize(); rgba[0] = (unsigned char) (255.0 * std::abs(diff[0])); rgba[1] = (unsigned char) (255.0 * std::abs(diff[1])); rgba[2] = (unsigned char) (255.0 * std::abs(diff[2])); rgba[3] = (unsigned char) (255.0); } else if(i==fibrNrPnts) { // nimm nur diff2 mitk::FiberBundle::DTITubePointType nxttmpFiberPntLst = dtiPntList.at(i-1); mitk::FiberBundle::DTITubePointType::PointType nxttmpFiberPnt = nxttmpFiberPntLst.GetPosition(); vnl_vector_fixed< double, 3 > tmpPntvtk((double)tmpvtkPnt[0], (double)tmpvtkPnt[1],(double)tmpvtkPnt[2]); vnl_vector_fixed< double, 3 > nxttmpPntvtk(nxttmpFiberPnt[0], nxttmpFiberPnt[1], nxttmpFiberPnt[2]); vnl_vector_fixed< double, 3 > diff; diff = tmpPntvtk - nxttmpPntvtk; diff.normalize(); rgba[0] = (unsigned char) (255.0 * std::abs(diff[0])); rgba[1] = (unsigned char) (255.0 * std::abs(diff[1])); rgba[2] = (unsigned char) (255.0 * std::abs(diff[2])); rgba[3] = (unsigned char) (255.0); } colorsT->InsertNextTupleValue(rgba); //get FA value float faVal = tmpFiberPntLst.GetField(mitk::FiberBundle::DTITubePointType::FA); //use insertNextValue cuz FA Values are reperesented as a single number (1 Tuple containing 1 parameter) faColors->InsertNextValue((double) faVal); } } vtkcells->InsertNextCell(polyLine); } //vtkcells->InitTraversal(); // Put points and lines together in one polyData structure m_PolyData = vtkPolyData::New(); m_PolyData->SetPoints(vtkpoints); m_PolyData->SetLines(vtkcells); if (vtkVrtxs->GetSize() > 0) { m_PolyData->SetVerts(vtkVrtxs); } m_PolyData->GetPointData()->AddArray(colorsT); m_PolyData->GetPointData()->AddArray(faColors); return m_PolyData; } /* NECESSARY IMPLEMENTATION OF SUPERCLASS METHODS */ void mitk::FiberBundle::UpdateOutputInformation() { } void mitk::FiberBundle::SetRequestedRegionToLargestPossibleRegion() { } bool mitk::FiberBundle::RequestedRegionIsOutsideOfTheBufferedRegion() { return false; } bool mitk::FiberBundle::VerifyRequestedRegion() { return true; } void mitk::FiberBundle::SetRequestedRegion( itk::DataObject *data ) { } /* TUTORIAL INSERT POINTS / FIBERS to TRACTCONTAINER */ // points and vectors do not need to be initiated but itkVectorContainer /*ContainerPointType pnt1; pnt1[0] = 1.0; pnt1[1] = 2.0; pnt1[2] = 3.0; ContainerPointType pnt2; pnt2[0] = 4.0; pnt2[1] = 5.0; pnt2[2] = 6.0; ContainerTractType tract1; tract1.push_back(pnt1); tract1.push_back(pnt2); ContainerType::Pointer testContainer = ContainerType::New(); unsigned int freeIdx = testContainer->Size(); MITK_INFO << freeIdx << "\n"; testContainer->InsertElement(freeIdx, tract1); //iterate through all fibers stored in container for(ContainerType::ConstIterator itCont = testContainer->Begin(); itCont != testContainer->End(); itCont++) { //get single tract ContainerTractType tmp_fiber = itCont->Value(); // MITK_INFO << tmp_fiber << "\n"; //iterate through all points within a fibertract for(ContainerTractType::iterator itPnt = tmp_fiber.begin(); itPnt != tmp_fiber.end(); ++itPnt) { // get single point with its coordinates ContainerPointType tmp_pntEx = *itPnt; MITK_INFO << tmp_pntEx[0] << "\n"; MITK_INFO << tmp_pntEx[1] << "\n"; MITK_INFO << tmp_pntEx[2] << "\n"; } } ################### DTI FIBERs TUTORIAL ########################### TUTORIAL HOW TO READ POINTS / FIBERS from DTIGroupSpatialObjectContainer assume our dti fibers are stored in m_GroupFiberBundle // all smartPointers to fibers stored in in a ChildrenList ChildrenListType * FiberList; FiberList = m_GroupFiberBundle->GetChildren(); // iterate through container, itkcontainer groupFiberBundle in one iteration step for(ChildrenListType::iterator itLst = FiberList->begin(); itLst != FiberList->end(); ++FiberList) { // lists output is SpatialObject, we know we have DTITubeSpacialObjects // dynamic cast only likes pointers, no smartpointers, so each dsmartpointer has membermethod .GetPointer() itk::SpatialObject<3>::Pointer tmp_fbr; tmp_fbr = *itLst; DTITubeType::Pointer dtiTract = dynamic_cast (tmp_fbr.GetPointer()); if (dtiTract.IsNull()) { return; } //get list of points int fibrNrPnts = dtiTract->GetNumberOfPoints(); DTITubeType::PointListType dtiPntList = dtiTract->GetPoints(); } */ diff --git a/Modules/DiffusionImaging/IODataStructures/FiberBundle/mitkFiberBundle.h b/Modules/DiffusionImaging/IODataStructures/FiberBundle/mitkFiberBundle.h index b588b83e36..1d9c96f1aa 100644 --- a/Modules/DiffusionImaging/IODataStructures/FiberBundle/mitkFiberBundle.h +++ b/Modules/DiffusionImaging/IODataStructures/FiberBundle/mitkFiberBundle.h @@ -1,196 +1,196 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Module: $RCSfile$ Language: C++ Date: $Date$ Version: $Revision: 11989 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _MITK_FiberBundle_H #define _MITK_FiberBundle_H //includes for MITK datastructure #include "mitkBaseData.h" -#include "MitkDiffusionImagingExports.h" +//#include "MitkDiffusionImagingExports.h" //=======modernized================ //includes storing fiberdata #include //may be replaced by class precompile argument #include // may be replaced by class #include // my be replaced by class //includes processing of fibers // //=========modernized end=========== #include "mitkPlanarFigure.h" /* This Class represents a bunch of FiberTracts as a Bundle. A Bundle is represented by a GroupSpatialObject */ #include "itkDTITubeSpatialObject.h" #include "itkDTITubeSpatialObjectPoint.h" #include "itkGroupSpatialObject.h" #include "itkPolyLineParametricPath.h" #include "itkSlowPolyLineParametricPath.h" #include "itkVectorContainer.h" #include "itkPointSet.h" #include "itkVector.h" #include //#include #include #include #include #include #include #include namespace mitk { /** * \brief Base Class for Fiber Bundles; */ - class MitkDiffusionImaging_EXPORT FiberBundle : public BaseData + class FiberBundle : public BaseData { public: /* friend classes wanna access typedefs ContainerPointType, ContainerTractType, ContainerType */ friend class FiberBundleWriter; friend class FiberBundleReader; // friend class itkTractsToDWIImageFilter; /** Types for the standardized TractContainer **/ typedef itk::Point ContainerPointType; //no need to init, is no smartpointer typedef itk::VectorContainer ContainerTractType; typedef itk::VectorContainer< unsigned int, ContainerTractType::Pointer > ContainerType; //init via smartpointer /** Types for the ITK Stochastic TractContainer **/ typedef itk::SlowPolyLineParametricPath< 3 > itkStochTractType; typedef itk::VectorContainer< unsigned int, itkStochTractType::Pointer > itkStochTractContainerType; // virtual methods that need to be implemented virtual void UpdateOutputInformation(); virtual void SetRequestedRegionToLargestPossibleRegion(); virtual bool RequestedRegionIsOutsideOfTheBufferedRegion(); virtual bool VerifyRequestedRegion(); virtual void SetRequestedRegion( itk::DataObject *data ); static const int TRACTPOINT_BACKFACE; static const int TRACTPOINT_ON_PLANE; static const int TRACTPOINT_FRNTFACE; /* DTITubeSpatialObject Definitions */ typedef itk::GroupSpatialObject<3> FiberGroupType; typedef FiberGroupType::ChildrenListType ChildrenListType; typedef itk::DTITubeSpatialObject<3> DTITubeType; typedef itk::DTITubeSpatialObjectPoint<3> DTITubePointType; mitkClassMacro( FiberBundle, BaseData ); itkNewMacro( Self ); /* Handle Output Type of ITK Stochastic Tractography Fiber Tracking */ void addTractContainer( ContainerType::Pointer ); void additkStochTractContainer(itkStochTractContainerType::Pointer); void initFiberGroup(); void addSingleDTITract(mitk::FiberBundle::DTITubeType::Pointer); DTITubeType::Pointer copySingleDTITract(DTITubeType::Pointer); /* Methods for PlanarFigure ROIs */ //mitk::FiberBundle::Pointer extractFibersPF(mitk::PlanarFigure::Pointer); std::vector extractFibersByPF(mitk::PlanarFigure::Pointer, std::vector* set=0); mitk::FiberBundle::Pointer extractFibersById(std::vector ); std::vector getAllIDsInFiberBundle(); mitk::Point3D calculateCrossingPoint(mitk::Point3D , mitk::Point3D , mitk::PlanarFigure::Pointer ); //depricated bool checkForGap(int, int); //depricated /*********************************/ void debug_members(); void SetBounds(float* b); void SetBounds(double* b); float* GetBounds(); //**** REALTIME MONITOR CONTAINER METHOD ****// //flag overwrite existing bundle void addContainer4speedDisplay( ContainerType::Pointer ); itkGetMacro(GroupFiberBundle, FiberGroupType::Pointer); itkGetMacro(TractContainer, ContainerType::Pointer); //** explicit handling of FiberBundleDataStructure contents *// void PushPoint(int fiberIndex, ContainerPointType point); void PushTract(ContainerTractType::Pointer tract); ContainerPointType GetPoint(int tractIndex, int pointIndex); ContainerTractType::Pointer GetTract(int tractIndex); int GetNumTracts(); int GetNumPoints(int tractIndex); FiberGroupType::Pointer getGroupFiberBundle(); mitk::FiberBundle::Pointer JoinBundle(mitk::FiberBundle::Pointer bundle); int FindTractByEndpoints(mitk::FiberBundle::DTITubeType::Pointer searchTract); mitk::FiberBundle::Pointer SubstractBundle(mitk::FiberBundle::Pointer bundle); void InsertBundle(mitk::FiberBundle::Pointer bundle); vtkPolyData* GeneratePolydata(); // int SearchFiber(worldPoint, tolerance, resultDistance); protected: FiberBundle(); virtual ~FiberBundle(); private: // =========MODERNIZED========== // The following polydata variables are used for fiber- and pointbased representation of the tractography results. As VTK suggests, one vtkPolyData is used to manage vertices and the other for polylines. // FiberPolyData stores all brain fibers using polylines (in world coordinates) vtkSmartPointer m_FiberPolyData; // VertexPolyData stores all original points as vertices computed by tracking algorithms vtkSmartPointer m_VertexPolyData; vtkSmartPointer m_Particles; // ===============Moedernized end===== FiberGroupType::Pointer m_GroupFiberBundle; ContainerType::Pointer m_TractContainer; itkStochTractContainerType::Pointer m_debugITKContainer; void fiberPostprocessing_FA( DTITubePointType* ); void fiberPostprocessing_setPoint(DTITubePointType* , ContainerPointType ); void fiberPostprocessing_setTensorMatrix(DTITubePointType*); int debug_PrototypeCounter; float m_boundsFB[3]; /* Methods for PlanarFigure ROIs */ bool isPointInSelection(mitk::Point3D, mitk::PlanarFigure::Pointer); vtkPolyData* m_PolyData; }; } // namespace mitk #endif /* _MITK_FiberBundle_H */ diff --git a/Modules/DiffusionImaging/IODataStructures/mitkDiffusionImagingObjectFactory.cpp b/Modules/DiffusionImaging/IODataStructures/mitkDiffusionImagingObjectFactory.cpp index 194803fc23..d26e4b1788 100644 --- a/Modules/DiffusionImaging/IODataStructures/mitkDiffusionImagingObjectFactory.cpp +++ b/Modules/DiffusionImaging/IODataStructures/mitkDiffusionImagingObjectFactory.cpp @@ -1,320 +1,337 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2009-06-18 15:59:04 +0200 (Do, 18 Jun 2009) $ Version: $Revision: 16916 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkDiffusionImagingObjectFactory.h" #include "mitkProperties.h" #include "mitkBaseRenderer.h" #include "mitkDataNode.h" #include "mitkNrrdDiffusionImageIOFactory.h" #include "mitkNrrdDiffusionImageWriterFactory.h" #include "mitkNrrdDiffusionImageWriter.h" #include "mitkDiffusionImage.h" #include "mitkNrrdQBallImageIOFactory.h" #include "mitkNrrdQBallImageWriterFactory.h" #include "mitkNrrdQBallImageWriter.h" #include "mitkNrrdTensorImageIOFactory.h" #include "mitkNrrdTensorImageWriterFactory.h" #include "mitkNrrdTensorImageWriter.h" #include "mitkCompositeMapper.h" #include "mitkDiffusionImageMapper.h" #include "mitkGPUVolumeMapper3D.h" #include "mitkVolumeDataVtkMapper3D.h" //====depricated fiberstructure===== #include "mitkFiberBundle.h" +#include "mitkFiberBundleMapper2D.h" #include "mitkFiberBundleMapper3D.h" #include "mitkFiberBundleIOFactory.h" #include "mitkFiberBundleWriterFactory.h" #include "mitkFiberBundleWriter.h" //================================== //modernized fiberbundle datastrucutre #include "mitkFiberBundleX.h" #include "mitkFiberBundleXIOFactory.h" #include "mitkFiberBundleXWriterFactory.h" #include "mitkFiberBundleXWriter.h" #include "mitkFiberBundleXMapper3D.h" #include "mitkFiberBundleXThreadMonitorMapper3D.h" #include "mitkFiberBundleXThreadMonitor.h" #include "mitkNrrdTbssImageIOFactory.h" #include "mitkNrrdTbssImageWriterFactory.h" #include "mitkNrrdTbssImageWriter.h" typedef short DiffusionPixelType; typedef char TbssRoiPixelType; typedef mitk::DiffusionImage DiffusionImageShort; typedef std::multimap MultimapType; mitk::DiffusionImagingObjectFactory::DiffusionImagingObjectFactory(bool /*registerSelf*/) :CoreObjectFactoryBase() { static bool alreadyDone = false; if (!alreadyDone) { MITK_INFO << "DiffusionImagingObjectFactory c'tor" << std::endl; RegisterIOFactories(); mitk::NrrdDiffusionImageIOFactory::RegisterOneFactory(); mitk::NrrdQBallImageIOFactory::RegisterOneFactory(); mitk::NrrdTensorImageIOFactory::RegisterOneFactory(); mitk::FiberBundleIOFactory::RegisterOneFactory(); mitk::NrrdTbssImageIOFactory::RegisterOneFactory(); mitk::FiberBundleXIOFactory::RegisterOneFactory(); //modernized mitk::NrrdDiffusionImageWriterFactory::RegisterOneFactory(); mitk::NrrdQBallImageWriterFactory::RegisterOneFactory(); mitk::NrrdTensorImageWriterFactory::RegisterOneFactory(); mitk::FiberBundleWriterFactory::RegisterOneFactory(); mitk::NrrdTbssImageWriterFactory::RegisterOneFactory(); mitk::FiberBundleXWriterFactory::RegisterOneFactory();//modernized m_FileWriters.push_back( NrrdDiffusionImageWriter::New().GetPointer() ); m_FileWriters.push_back( NrrdQBallImageWriter::New().GetPointer() ); m_FileWriters.push_back( NrrdTensorImageWriter::New().GetPointer() ); m_FileWriters.push_back( mitk::FiberBundleWriter::New().GetPointer() ); m_FileWriters.push_back( NrrdTbssImageWriter::New().GetPointer() ); m_FileWriters.push_back( mitk::FiberBundleXWriter::New().GetPointer() );//modernized mitk::CoreObjectFactory::GetInstance()->RegisterExtraFactory(this); CreateFileExtensionsMap(); alreadyDone = true; } } mitk::Mapper::Pointer mitk::DiffusionImagingObjectFactory::CreateMapper(mitk::DataNode* node, MapperSlotId id) { mitk::Mapper::Pointer newMapper=NULL; if ( id == mitk::BaseRenderer::Standard2D ) { std::string classname("QBallImage"); if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { newMapper = mitk::CompositeMapper::New(); newMapper->SetDataNode(node); node->SetMapper(3, ((CompositeMapper*)newMapper.GetPointer())->GetImageMapper()); } classname = "TensorImage"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { newMapper = mitk::CompositeMapper::New(); newMapper->SetDataNode(node); node->SetMapper(3, ((CompositeMapper*)newMapper.GetPointer())->GetImageMapper()); } classname = "DiffusionImage"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { newMapper = mitk::DiffusionImageMapper::New(); newMapper->SetDataNode(node); } mitk::Mapper::Pointer newMapper=NULL; classname = "TbssImage"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { newMapper = mitk::ImageVtkMapper2D::New(); newMapper->SetDataNode(node); } + + classname = "FiberBundle"; + if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) + { + newMapper = mitk::FiberBundleMapper2D::New(); + newMapper->SetDataNode(node); + } + + classname = "FiberBundleX"; + if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) + { + newMapper = mitk::FiberBundleMapper2D::New(); + newMapper->SetDataNode(node); + } } else if ( id == mitk::BaseRenderer::Standard3D ) { std::string classname("QBallImage"); if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { newMapper = mitk::GPUVolumeMapper3D::New(); newMapper->SetDataNode(node); } classname = "TensorImage"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { newMapper = mitk::GPUVolumeMapper3D::New(); newMapper->SetDataNode(node); } classname = "DiffusionImage"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { newMapper = mitk::GPUVolumeMapper3D::New(); newMapper->SetDataNode(node); } classname = "FiberBundle"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { newMapper = mitk::FiberBundleMapper3D::New(); newMapper->SetDataNode(node); } classname = "FiberBundleX"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { newMapper = mitk::FiberBundleXMapper3D::New(); newMapper->SetDataNode(node); } classname = "FiberBundleXThreadMonitor"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { newMapper = mitk::FiberBundleXThreadMonitorMapper3D::New(); newMapper->SetDataNode(node); } classname = "TbssImage"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { newMapper = mitk::VolumeDataVtkMapper3D::New(); newMapper->SetDataNode(node); } } return newMapper; } void mitk::DiffusionImagingObjectFactory::SetDefaultProperties(mitk::DataNode* node) { std::string classname = "QBallImage"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { mitk::CompositeMapper::SetDefaultProperties(node); mitk::GPUVolumeMapper3D::SetDefaultProperties(node); } classname = "TensorImage"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { mitk::CompositeMapper::SetDefaultProperties(node); mitk::GPUVolumeMapper3D::SetDefaultProperties(node); } classname = "DiffusionImage"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { mitk::DiffusionImageMapper::SetDefaultProperties(node); mitk::GPUVolumeMapper3D::SetDefaultProperties(node); } classname = "FiberBundle"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { mitk::FiberBundleMapper3D::SetDefaultProperties(node); +// mitk::FiberBundleMapper2D::SetDefaultProperties(node); } classname = "FiberBundleX"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { mitk::FiberBundleXMapper3D::SetDefaultProperties(node); +// mitk::FiberBundleXMapper2D::SetDefaultProperties(node); } classname = "FiberBundleXThreadMonitor"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { mitk::FiberBundleXThreadMonitorMapper3D::SetDefaultProperties(node); } classname = "TbssImage"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { mitk::ImageVtkMapper2D::SetDefaultProperties(node); mitk::VolumeDataVtkMapper3D::SetDefaultProperties(node); } } const char* mitk::DiffusionImagingObjectFactory::GetFileExtensions() { std::string fileExtension; this->CreateFileExtensions(m_FileExtensionsMap, fileExtension); return fileExtension.c_str(); }; mitk::CoreObjectFactoryBase::MultimapType mitk::DiffusionImagingObjectFactory::GetFileExtensionsMap() { return m_FileExtensionsMap; } const char* mitk::DiffusionImagingObjectFactory::GetSaveFileExtensions() { std::string fileExtension; this->CreateFileExtensions(m_SaveFileExtensionsMap, fileExtension); return fileExtension.c_str(); }; mitk::CoreObjectFactoryBase::MultimapType mitk::DiffusionImagingObjectFactory::GetSaveFileExtensionsMap() { return m_SaveFileExtensionsMap; } void mitk::DiffusionImagingObjectFactory::CreateFileExtensionsMap() { m_FileExtensionsMap.insert(std::pair("*.dwi", "Diffusion Weighted Images")); m_FileExtensionsMap.insert(std::pair("*.hdwi", "Diffusion Weighted Images")); m_FileExtensionsMap.insert(std::pair("*.nii", "Diffusion Weighted Images for FSL")); m_FileExtensionsMap.insert(std::pair("*.fsl", "Diffusion Weighted Images for FSL")); m_FileExtensionsMap.insert(std::pair("*.fslgz", "Diffusion Weighted Images for FSL")); m_FileExtensionsMap.insert(std::pair("*.qbi", "Q-Ball Images")); m_FileExtensionsMap.insert(std::pair("*.hqbi", "Q-Ball Images")); m_FileExtensionsMap.insert(std::pair("*.dti", "Tensor Images")); m_FileExtensionsMap.insert(std::pair("*.hdti", "Tensor Images")); m_FileExtensionsMap.insert(std::pair("*.fib", "Fiber Bundle")); m_FileExtensionsMap.insert(std::pair("*.vfib", "Fiber Bundle Polydata")); m_FileExtensionsMap.insert(std::pair("*.vtk", "Fiber Bundle Polydata")); m_FileExtensionsMap.insert(std::pair("*.tbss", "TBSS data")); m_SaveFileExtensionsMap.insert(std::pair("*.dwi", "Diffusion Weighted Images")); m_SaveFileExtensionsMap.insert(std::pair("*.hdwi", "Diffusion Weighted Images")); m_SaveFileExtensionsMap.insert(std::pair("*.nii", "Diffusion Weighted Images for FSL")); m_SaveFileExtensionsMap.insert(std::pair("*.fsl", "Diffusion Weighted Images for FSL")); m_SaveFileExtensionsMap.insert(std::pair("*.fslgz", "Diffusion Weighted Images for FSL")); m_SaveFileExtensionsMap.insert(std::pair("*.qbi", "Q-Ball Images")); m_SaveFileExtensionsMap.insert(std::pair("*.hqbi", "Q-Ball Images")); m_SaveFileExtensionsMap.insert(std::pair("*.dti", "Tensor Images")); m_SaveFileExtensionsMap.insert(std::pair("*.hdti", "Tensor Images")); m_SaveFileExtensionsMap.insert(std::pair("*.fib", "Fiber Bundle")); m_SaveFileExtensionsMap.insert(std::pair("*.vfib", "Fiber Bundle Polydata")); m_SaveFileExtensionsMap.insert(std::pair("*.vtk", "Fiber Bundle Polydata")); m_SaveFileExtensionsMap.insert(std::pair("*.tbss", "TBSS data")); } void mitk::DiffusionImagingObjectFactory::RegisterIOFactories() { } void RegisterDiffusionImagingObjectFactory() { static bool oneDiffusionImagingObjectFactoryRegistered = false; if ( ! oneDiffusionImagingObjectFactoryRegistered ) { MITK_INFO << "Registering DiffusionImagingObjectFactory..." << std::endl; mitk::CoreObjectFactory::GetInstance()->RegisterExtraFactory(mitk::DiffusionImagingObjectFactory::New()); oneDiffusionImagingObjectFactoryRegistered = true; } } diff --git a/Modules/DiffusionImaging/Rendering/mitkDiffusionImageMapper.cpp b/Modules/DiffusionImaging/Rendering/mitkDiffusionImageMapper.cpp index 4af1bf21f0..bd95ac041f 100644 --- a/Modules/DiffusionImaging/Rendering/mitkDiffusionImageMapper.cpp +++ b/Modules/DiffusionImaging/Rendering/mitkDiffusionImageMapper.cpp @@ -1,65 +1,67 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2009-05-12 19:56:03 +0200 (Di, 12 Mai 2009) $ Version: $Revision: 17179 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef DiffusionImageMapper_txx_HEADER_INCLUDED #define DiffusionImageMapper_txx_HEADER_INCLUDED #include "mitkProperties.h" #include "mitkDiffusionImage.h" template mitk::DiffusionImageMapper::DiffusionImageMapper() { + MITK_INFO << "DiffMapper init"; } template mitk::DiffusionImageMapper::~DiffusionImageMapper() { + MITK_INFO << "DiffMapper destroyed"; } template void mitk::DiffusionImageMapper::GenerateDataForRenderer( mitk::BaseRenderer *renderer ) { int displayIndex(0); this->GetDataNode()->GetIntProperty( "DisplayChannel", displayIndex, renderer ); mitk::Image *input = const_cast< mitk::Image* >( this->GetInput() ); mitk::DiffusionImage *input2 = dynamic_cast< mitk::DiffusionImage* >( input ); MITK_INFO << "displayindex: " << displayIndex; input2->SetDisplayIndexForRendering(displayIndex); Superclass::GenerateDataForRenderer(renderer); } template void mitk::DiffusionImageMapper::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { node->AddProperty( "DisplayChannel", mitk::IntProperty::New( 0 ), renderer, overwrite ); Superclass::SetDefaultProperties(node, renderer, overwrite); } #endif diff --git a/Modules/DiffusionImaging/Rendering/mitkFiberBundleMapper2D.cpp b/Modules/DiffusionImaging/Rendering/mitkFiberBundleMapper2D.cpp new file mode 100644 index 0000000000..18e421f1c2 --- /dev/null +++ b/Modules/DiffusionImaging/Rendering/mitkFiberBundleMapper2D.cpp @@ -0,0 +1,477 @@ +/* + * mitkFiberBundleMapper2D.cpp + * mitk-all + * + * Created by HAL9000 on 1/17/11. + * Copyright 2011 __MyCompanyName__. All rights reserved. + * + */ + +#include "mitkFiberBundleMapper2D.h" +#include +#include "mitkFiberBundleMapper3D.h" + +#include +#include +#include +#include +//#include + +//#include +#include +#include +#include +#include +#include +#include +#include + + +#include +#include + +mitk::FiberBundleMapper2D::FiberBundleMapper2D() +{ + MITK_INFO << "FB Mapper2d initialized"; +} + +mitk::FiberBundleMapper2D::~FiberBundleMapper2D() +{ + MITK_INFO << "FB Mapper2d destroyed"; +} + + +const mitk::FiberBundle* mitk::FiberBundleMapper2D::GetInput() +{ + return dynamic_cast ( GetData() ); +} + + + +void mitk::FiberBundleMapper2D::Update(mitk::BaseRenderer * renderer) +{ + + + + if ( !this->IsVisible( renderer ) ) + { + return; + } + +// const mitk::FiberBundle::Pointer data = const_cast< mitk::FiberBundle* > ( this->GetInput() ); +// if ( data == NULL ) +// { +// return; +// } + + // Calculate time step of the input data for the specified renderer (integer value) + // this method is implemented in mitkMapper + this->CalculateTimeStep( renderer ); + + //check if updates occured in the node or on the display + FBLocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); + const DataNode *node = this->GetDataNode(); + if ( (localStorage->m_LastUpdateTime < node->GetMTime()) + || (localStorage->m_LastUpdateTime < node->GetPropertyList()->GetMTime()) //was a property modified? + || (localStorage->m_LastUpdateTime < node->GetPropertyList(renderer)->GetMTime()) ) + { + MITK_INFO << "UPDATE NEEDED FOR _ " << renderer->GetName(); + this->GenerateDataForRenderer( renderer ); + } + + if ((localStorage->m_LastUpdateTime < renderer->GetDisplayGeometry()->GetMTime()) ) //was the display geometry modified? e.g. zooming, panning) + { + MITK_INFO << "update clipping range only:"; + //get information about current position of views + mitk::SliceNavigationController::Pointer sliceContr = renderer->GetSliceNavigationController(); + mitk::PlaneGeometry::ConstPointer planeGeo = sliceContr->GetCurrentPlaneGeometry(); + + // + vtkCamera* camera = renderer->GetVtkRenderer()->GetActiveCamera(); + double *focPnt = camera->GetFocalPoint(); + double *camPos = camera->GetPosition(); + double dist1 = sqrt( pow( (focPnt[0]-camPos[0]), 2.0) + pow( (focPnt[1]-camPos[1]), 2.0) + pow( (focPnt[2]-camPos[2]), 2.0)); + MITK_INFO << "DIST for CLIPPING RANGE: " << dist1; + camera->SetClippingRange( (dist1-1.0),(dist1+1.0) ); + double cl1 = camera->GetClippingRange()[0]; + double cl2 = camera->GetClippingRange()[1]; + MITK_INFO << "Camera clipping range: " << cl1 << " " << cl2; + + + + } + + + + + + + + +} + + +// ALL RAW DATA FOR VISUALIZATION IS GENERATED HERE. +// vtkActors and Mappers are feeded here +void mitk::FiberBundleMapper2D::GenerateDataForRenderer(mitk::BaseRenderer *renderer) +{ + MITK_INFO << "FiberBundlemapper2D _ GENERATE DATA"; + + //the handler of local storage gets feeded in this method with requested data for related renderwindow + FBLocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); + +// if ( !this->IsVisible( renderer ) ) +// { +// return; +// } +// + //this procedure is depricated, + //not needed after initializaton anymore + mitk::DataNode::ConstPointer node = this->GetDataNode(); + if ( node.IsNull() ) + { + MITK_INFO << "check DATANODE: ....[Fail] "; + return; + } + /////////////////////////////////// + + mitk::FiberBundleMapper3D::Pointer FBMapper3D = dynamic_cast< mitk::FiberBundleMapper3D* > (node->GetMapper( 2 )); + if ( FBMapper3D->GetInput() == NULL ) + { + MITK_INFO << "check FBMapper3D Input: ....[Fail] "; + return; + } + + + //get information about current position of views +// mitk::SliceNavigationController::Pointer sliceContr = renderer->GetSliceNavigationController(); +// mitk::PlaneGeometry::ConstPointer planeGeo = sliceContr->GetCurrentPlaneGeometry(); +// +// +// //generate according cutting planes based on the view position +// double planeN[3], planeOrigin[3], cutParams[3]; +//// +// planeN[0] = planeGeo->GetNormal()[0]; +// planeN[1] = planeGeo->GetNormal()[1]; +// planeN[2] = planeGeo->GetNormal()[2]; +// +// planeOrigin[0] = planeGeo->GetOrigin()[0]; +// planeOrigin[1] = planeGeo->GetOrigin()[1]; +// planeOrigin[2] = planeGeo->GetOrigin()[2]; +//// +// MITK_INFO << "renWinNAME: " << renderer->GetName(); +// MITK_INFO << "PlaneNormal: " << planeN[0] << " | " << planeN[1] << " | " << planeN[2]; +// MITK_INFO << "PlaneOrigin: " << planeOrigin[0] << " | " << planeOrigin[1] << " | " << planeOrigin[2]; +// +// +// //cutParams[0] = this->GetDataNode()->GetPropertyValue("ColorCoding", nodeCC);; + + //feed cutter with parameters gathered from GUI +// int numSlices; +// bool existsPropNS = this->GetDataNode()->GetPropertyValue("2DPlanes", numSlices); +// if ( !existsPropNS ){ +// return; +// } +// +// int distFront; +// bool existsPropDF = this->GetDataNode()->GetPropertyValue("2DFront", distFront); +// if ( !existsPropDF ){ +// return; +// } +// +// int distBackDB; +// bool existsProp = this->GetDataNode()->GetPropertyValue("2DBack", distBackDB); +// if ( !existsProp ){ +// return; +// } +// +// +// cutParams[0] = numSlices; +// cutParams[1] = distFront; +// cutParams[2] = distBackDB; + + + + + //feed local storage with data we want to visualize +// localStorage->m_SlicedResult = FBMapper3D->GetCut(planeOrigin, planeN, cutParams); + // localStorage->m_SlicedResult = FBMapper3D->GetVtkFBPolyDataMapper(); + localStorage->m_SlicedResult = (vtkPolyData*) FBMapper3D->getVtkFiberBundleMapper()->GetInputAsDataSet(); + MITK_INFO << renderer->GetName() << " OutputPoints#: " << localStorage->m_SlicedResult->GetNumberOfPoints(); + + + vtkLookupTable *lut = vtkLookupTable::New(); + lut->Build(); + localStorage->m_PointMapper->SetScalarModeToUsePointFieldData(); + //m_VtkFiberDataMapperGL->SelectColorArray("FaColors"); + localStorage->m_PointMapper->SelectColorArray("ColorValues"); + localStorage->m_PointMapper->SetLookupTable(lut); //apply the properties after the slice was set + this->ApplyProperties( renderer ); + + //setup the camera according to the actor with zooming/panning etc. + // this->AdjustCamera( renderer, planeGeo ); + + //get distance from camera to focal point + + + vtkCamera* camera = renderer->GetVtkRenderer()->GetActiveCamera(); + double *focPnt = camera->GetFocalPoint(); + double *camPos = camera->GetPosition(); + double dist1 = sqrt( pow( (focPnt[0]-camPos[0]), 2.0) + pow( (focPnt[1]-camPos[1]), 2.0) + pow( (focPnt[2]-camPos[2]), 2.0)); + MITK_INFO << "DIST for CLIPPING RANGE: " << dist1; + camera->SetClippingRange( (dist1-1.0),(dist1+1.0) ); + double cl1 = camera->GetClippingRange()[0]; + double cl2 = camera->GetClippingRange()[1]; + MITK_INFO << "Camera clipping range: " << cl1 << " " << cl2; + + // feed the vtk fiber mapper with point data ...TODO do in constructor + localStorage->m_PointMapper->SetInput(localStorage->m_SlicedResult); // in optimized version, mapper is feeded by localStorage->m_cutter->GetOutput(); + localStorage->m_PointActor->SetMapper(localStorage->m_PointMapper); + + + + + // We have been modified => save this for next Update() + localStorage->m_LastUpdateTime.Modified(); + +} + + +vtkProp* mitk::FiberBundleMapper2D::GetVtkProp(mitk::BaseRenderer *renderer) +{ + + //MITK_INFO << "FiberBundleMapper2D GetVtkProp(renderer)"; + this->Update(renderer); + return m_LSH.GetLocalStorage(renderer)->m_PointActor; + +} + +void mitk::FiberBundleMapper2D::AdjustCamera(mitk::BaseRenderer* renderer, mitk::PlaneGeometry::ConstPointer planeGeo ) +{ + + + //activate parallel projection for 2D + renderer->GetVtkRenderer()->GetActiveCamera()->SetParallelProjection(true); + + //get the display geometry of the current renderer. + const mitk::DisplayGeometry* displayGeometry = renderer->GetDisplayGeometry(); + + //get hight and width of current point set + double fibMapHeightInMM = 0.0; + double displayHeightInMM = displayGeometry->GetSizeInMM()[1]; //the display height in mm (gets smaller when you zoom in) + double zoomFactor = 0.0; + +//============ ugly hack start ================================ + // ugly hack...better do it in generate data and use normal of plane or view to get requested dimensions + // and set 2Ddimension in local storage + + std::string renWinName = renderer->GetName(); + std::string renWinTransveral = "stdmulti.widget1"; + std::string renWinSaggital = "stdmulti.widget2"; + std::string renWinCoronal = "stdmulti.widget3"; + + double cameraUp[3]; + + + double fibmapspacing = 0.0; + double fibmapsize = 0.0; + + double cameraPosition[3]; + +// + + + if (renWinName == renWinTransveral) { + MITK_INFO << renWinTransveral << "----use Z (width) and Y (height) ---"; +// origin of Y = -106.737 + fibmapspacing = 2.5; + fibmapsize = 82; + cameraUp[0] = 0.0; + cameraUp[1] = 1.0; + cameraUp[2] = 0.0; + cameraPosition[0] = -1.25; + cameraPosition[1] = 454.0; + cameraPosition[2] = 487.0; //Reason for 900000: VTK seems to calculate the clipping planes wrong for small values. See VTK bug (id #7823) in VTK bugtracker. +//renderer->GetVtkRenderer()->GetActiveCamera()->SetPosition( cameraPosition ); + + } else if (renWinName == renWinSaggital) { + MITK_INFO << renWinSaggital << "--use X (width) and Z (height) ------"; + fibmapspacing = 2.5; + fibmapsize = 40; + cameraUp[0] = 0.0; + cameraUp[1] = 0.0; + cameraUp[2] = 1.0; + cameraPosition[0] = 600; + cameraPosition[1] = 16.0; + cameraPosition[2] = 43.0; //Reason for 900000: VTK seems to calculate the clipping planes wrong for small values. See VTK bug (id #7823) in VTK bugtracker. + //renderer->GetVtkRenderer()->GetActiveCamera()->Elevation(2.0); + //renderer->GetVtkRenderer()->GetActiveCamera()->SetPosition( cameraPosition ); + + } else if (renWinName == renWinCoronal) { + MITK_INFO << renWinCoronal << "--use X (width) and Y (height)------"; + fibmapspacing = 2.5; + fibmapsize = 82; + cameraUp[0] = 0.0; + cameraUp[1] = 0.0; + cameraUp[2] = 1.0; + cameraPosition[0] = -1.25; + cameraPosition[1] = -644.0; + cameraPosition[2] = 43.0; //Reason for 900000: VTK seems to calculate the clipping planes wrong for small values. See VTK bug (id #7823) in VTK bugtracker. + //renderer->GetVtkRenderer()->GetActiveCamera()->SetPosition( cameraPosition ); + } + + fibMapHeightInMM = fibmapspacing * fibmapsize; +//========== ugly hack end ================================== + + zoomFactor = fibMapHeightInMM / displayHeightInMM; + + Vector2D displayGeometryOriginInMM = displayGeometry->GetOriginInMM(); //top left of the render window (Origin) + Vector2D displayGeometryCenterInMM = displayGeometryOriginInMM + displayGeometry->GetSizeInMM()*0.5; //center of the render window: (Origin + Size/2) + + + + mitk::Point2D dispCenterMM; + dispCenterMM[0] = displayGeometryCenterInMM[0]; + dispCenterMM[1] = displayGeometryCenterInMM[1]; + + mitk::Point3D dispCenter3D; + //map diplay-geo to centerpoint + displayGeometry->Map(dispCenterMM, dispCenter3D); + + Vector3D normal, dispCenter3Dv; + normal[0] = planeGeo->GetNormal()[0]; + normal[1] = planeGeo->GetNormal()[1]; + normal[2] = planeGeo->GetNormal()[2]; + normal.Normalize(); + + double focalPoint[3]; + focalPoint[0] = dispCenter3D[0]; + focalPoint[1] = dispCenter3D[1]; + focalPoint[2] = dispCenter3D[2]; + + dispCenter3Dv[0] = dispCenter3D[0]; + dispCenter3Dv[1] = dispCenter3D[1]; + dispCenter3Dv[2] = dispCenter3D[2]; + + //Vector3D camPos = dispCenter3Dv * normal; + // normal * dispCenter3D ; + + + cameraPosition[0] = dispCenter3D[0] + 500 * normal[0]; + cameraPosition[1] = dispCenter3D[1] + 500 * normal[1]; + cameraPosition[2] = dispCenter3D[2] + 500 * normal[2]; + + + + + + //calculate distance + //po§sition = mittelpunkt + distanz * normierte_normale + + //Scale the rendered object: + //The image is scaled by a single factor, because in an orthographic projection sizes + //are preserved (so you cannot scale X and Y axis with different parameters). The + //parameter sets the size of the total display-volume. If you set this to the image + //height, the image plus a border with the size of the image will be rendered. + //Therefore, the size is imageHeightInMM / 2. + renderer->GetVtkRenderer()->GetActiveCamera()->SetParallelScale(fibMapHeightInMM*0.5 ); + //zooming with the factor calculated by dividing displayHeight through imegeHeight. The factor is inverse, because the VTK zoom method is working inversely. + renderer->GetVtkRenderer()->GetActiveCamera()->Zoom(zoomFactor); + + + //set the camera corresponding to the textured plane + vtkSmartPointer camera = renderer->GetVtkRenderer()->GetActiveCamera(); + if (camera) + { + camera->SetPosition( cameraPosition ); //set the camera position on the textured plane normal (in our case this is the view plane normal) + camera->SetFocalPoint( focalPoint ); //set the focal point to the center of the textured plane + camera->SetViewUp( cameraUp ); //set the view-up for the camera + camera->SetClippingRange(0.1, 1000000.0); + //Reason for huge range: VTK seems to calculate the clipping planes wrong for small values. See VTK bug (id #7823) in VTK bugtracker. + + MITK_INFO << "CamPos: " << camera->GetPosition()[0] << " "<< camera->GetPosition()[1] << " "<< camera->GetPosition()[2]; + MITK_INFO << "CamFoc: " << camera->GetFocalPoint()[0] << " "<< camera->GetFocalPoint()[1] << " "<< camera->GetFocalPoint()[2]; + MITK_INFO << "upVec: " << camera->GetViewUp()[0] << " " << camera->GetViewUp()[1] << " " << camera->GetViewUp()[2]; + + } + + + +} + +// this method prepares data for VTK mapping and rendering +void mitk::FiberBundleMapper2D::ApplyProperties(mitk::BaseRenderer* renderer) +{ + + //get the current localStorage for the corresponding renderer + //FBLocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); + + renderer->GetVtkRenderer()->GetRenderWindow()->SetInteractor(NULL); + //float opacity = 1.0f; + //float rgb[3] = {1.0f, 1.0f, 1.0f}; + + //set opacity (from propertyList) to visualized fibers + //GetOpacity( opacity, renderer ); + //localStorage->m_PointActor->GetProperty()->SetOpacity((double)opacity); + + //set color (from propertyList) to visualized fibers + // GetColor( rgb, renderer); + //localStorage->m_PointActor->GetProperty()->SetColor((double)rgb[0], (double)rgb[1], (double)rgb[2]); + + + +} + + +// following methods are essential, they actually call the GetVtkProp() method +// which returns the desired actors +void mitk::FiberBundleMapper2D::MitkRenderOverlay(BaseRenderer* renderer) +{ +// MITK_INFO << "FiberBundleMapper2D MitkRenderOVerlay(renderer)"; + if ( this->IsVisible(renderer)==false ) + return; + + if ( this->GetVtkProp(renderer)->GetVisibility() ) + { + this->GetVtkProp(renderer)->RenderOverlay(renderer->GetVtkRenderer()); + } +} + +void mitk::FiberBundleMapper2D::MitkRenderOpaqueGeometry(BaseRenderer* renderer) +{ +// MITK_INFO << "FiberBundleMapper2D MitkRenderOpaqueGeometry(renderer)"; + if ( this->IsVisible( renderer )==false ) + return; + + if ( this->GetVtkProp(renderer)->GetVisibility() ) + this->GetVtkProp(renderer)->RenderOpaqueGeometry( renderer->GetVtkRenderer() ); +} +void mitk::FiberBundleMapper2D::MitkRenderTranslucentGeometry(BaseRenderer* renderer) +{ +// MITK_INFO << "FiberBundleMapper2D MitkRenderTranslucentGeometry(renderer)"; + if ( this->IsVisible(renderer)==false ) + return; + + //TODO is it possible to have a visible BaseRenderer AND an invisible VtkRenderer??? + if ( this->GetVtkProp(renderer)->GetVisibility() ) + this->GetVtkProp(renderer)->RenderTranslucentPolygonalGeometry(renderer->GetVtkRenderer()); + +} +void mitk::FiberBundleMapper2D::MitkRenderVolumetricGeometry(BaseRenderer* renderer) +{ +// MITK_INFO << "FiberBundleMapper2D MitkRenderVolumentricGeometry(renderer)"; + if(IsVisible(renderer)==false) + return; + + //TODO is it possible to have a visible BaseRenderer AND an invisible VtkRenderer??? + if ( GetVtkProp(renderer)->GetVisibility() ) + this->GetVtkProp(renderer)->RenderVolumetricGeometry(renderer->GetVtkRenderer()); + +} + +mitk::FiberBundleMapper2D::FBLocalStorage::FBLocalStorage() +{ + m_PointActor = vtkSmartPointer::New(); + m_PointMapper = vtkSmartPointer::New(); + +} diff --git a/Modules/DiffusionImaging/Rendering/mitkFiberBundleMapper2D.h b/Modules/DiffusionImaging/Rendering/mitkFiberBundleMapper2D.h new file mode 100644 index 0000000000..10cdea9cd0 --- /dev/null +++ b/Modules/DiffusionImaging/Rendering/mitkFiberBundleMapper2D.h @@ -0,0 +1,118 @@ +/*========================================================================= + + Program: Medical Imaging & Interaction Toolkit + Language: C++ + Date: $Date: 2010-09-26 20:40:22 +0200 (So, 26 Sep 2010) $ + Version: $Revision$ + + Copyright (c) German Cancer Research Center, Division of Medical and + Biological Informatics. All rights reserved. + See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + + =========================================================================*/ + +#ifndef FIBERBUNDLEMAPPER2D_H_HEADER_INCLUDED +#define FIBERBUNDLEMAPPER2D_H_HEADER_INCLUDED + +//MITK Rendering +#include +#include +//#include "MitkDiffusionImagingExports.h" + +#include +#include +#include + + +//#include "FBLocalStorage.h" + +class vtkActor; +//class vtkPropAssembly; //lets see if we need it +class mitkBaseRenderer; +class vtkPolyDataMapper; +class vtkCutter; +class vtkPlane; +class vtkPolyData; + + + +namespace mitk { + + + class FiberBundleMapper2D : public VtkMapper2D + { + + public: + mitkClassMacro(FiberBundleMapper2D, VtkMapper2D); + itkNewMacro(Self); + const mitk::FiberBundle* GetInput(); + + + /** \brief Checks whether this mapper needs to update itself and generate + * data. */ + virtual void Update(mitk::BaseRenderer * renderer); + + + virtual void ApplyProperties(mitk::BaseRenderer* renderer); + + //### methods of MITK-VTK rendering pipeline + virtual vtkProp* GetVtkProp(mitk::BaseRenderer* renderer); + virtual void MitkRenderOverlay(BaseRenderer* renderer); + virtual void MitkRenderOpaqueGeometry(BaseRenderer* renderer); + virtual void MitkRenderTranslucentGeometry(BaseRenderer* renderer); + virtual void MitkRenderVolumetricGeometry(BaseRenderer* renderer); + //### end of methods of MITK-VTK rendering pipeline + + + class FBLocalStorage : public mitk::Mapper::BaseLocalStorage + { + public: + /** \brief Point Actor of a 2D render window. */ + vtkSmartPointer m_PointActor; + /** \brief Point Mapper of a 2D render window. */ + vtkSmartPointer m_PointMapper; + /** \brief Point Actor of a 2D render window. */ + // vtkSmartPointer m_TubeActor; //not in use right now + /** \brief Point Mapper of a 2D render window. */ + // vtkSmartPointer m_TubeMapper; //not in use right now + /** \brief Current slice of a 2D render window. */ + // vtkSmartPointer m_cutter; //needed later when optimized 2D mapper + vtkSmartPointer m_SlicingPlane; //needed later when optimized 2D mapper + vtkSmartPointer m_SlicedResult; //might be depricated in optimized 2D mapper + + /** \brief Timestamp of last update of stored data. */ + itk::TimeStamp m_LastUpdateTime; + /** \brief Constructor of the local storage. Do as much actions as possible in here to avoid double executions. */ + FBLocalStorage(); //if u copy&paste from this 2Dmapper, be aware that the implementation of this constructor is in the cpp file + + ~FBLocalStorage() + { + } + }; + + /** \brief This member holds all three LocalStorages for the three 2D render windows. */ + mitk::Mapper::LocalStorageHandler m_LSH; + + + + protected: + FiberBundleMapper2D(); + virtual ~FiberBundleMapper2D(); + + /** Does the actual resampling, without rendering. */ + virtual void GenerateDataForRenderer(mitk::BaseRenderer*); + + void AdjustCamera(mitk::BaseRenderer* , mitk::PlaneGeometry::ConstPointer); + + + + }; + + +}//end namespace + +#endif \ No newline at end of file diff --git a/Modules/DiffusionImaging/Rendering/mitkFiberBundleMapper3D.cpp b/Modules/DiffusionImaging/Rendering/mitkFiberBundleMapper3D.cpp index 773ea3d4e1..b26fc51eae 100644 --- a/Modules/DiffusionImaging/Rendering/mitkFiberBundleMapper3D.cpp +++ b/Modules/DiffusionImaging/Rendering/mitkFiberBundleMapper3D.cpp @@ -1,1140 +1,1145 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2009-05-12 19:56:03 +0200 (Di, 12 Mai 2009) $ Version: $Revision: 17179 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkProperties.h" #include "mitkFiberBundleMapper3D.h" #include #include #include #include #include #include #include #include #include #include #include #include "vtkVertex.h" #include #include #include #include #include #include "mitkFiberBundleInteractor.h" #include "mitkGlobalInteraction.h" //template mitk::FiberBundleMapper3D::FiberBundleMapper3D() : m_vtkFiberList(NULL), //m_VtkFiberDataMapperGL(NULL), m_VtkFiberDataMapperGL(vtkOpenGLPolyDataMapper::New()), m_vtkTubeMapper(NULL) { - //MITK_INFO << "FiberBundleMapper3D()"; + MITK_INFO << "FiberBundleMapper3D()"; m_FiberAssembly = vtkPropAssembly::New(); m_FiberActor = vtkOpenGLActor::New(); m_TubeActor = vtkOpenGLActor::New(); /* vtkUnsignedCharArray *colorsT = vtkUnsignedCharArray::New(); colorsT->SetName("Colors"); colorsT->SetNumberOfComponents(4); unsigned char red1[4] = {255, 0, 0 , 10}; colorsT->InsertNextTupleValue(red1); unsigned char red2[4] = {255,0, 0 , 255}; colorsT->InsertNextTupleValue(red2); colorsT->SetValue(3, (unsigned char)(255)); colorsT->SetValue(7, (unsigned char)(255)); //Create points for polyline1. double origin[3] = {100.0, 400.0, 0.0}; double p0[3] = {300.0, 400.0, 0.0}; double p1[3] = {300.0, 200.0, 0.0}; double p2[3] = {100.0, 300.0, 0.0}; double p3[3] = {130.0, 250.0, 0.0}; //create points for polyline2 //double p01[3] = {50.0, 50.0, 13.0}; //double p11[3] = {200.0, 100.0, 13.0}; //insert points to vtkPointarray vtkPoints *pnts = vtkPoints::New(); pnts->InsertPoint(0,origin); pnts->InsertPoint(1,p0); pnts->InsertPoint(2,p1); pnts->InsertPoint(3,p2); //pnts->InsertPoint(4,p01); //pnts->InsertPoint(5,p11); pnts->InsertPoint(4,p3); //generate and define polyline1 vtkPolyLine *polyLine = vtkPolyLine::New(); polyLine->GetPointIds()->SetNumberOfIds(4); polyLine->GetPointIds()->SetId(0,0); polyLine->GetPointIds()->SetId(1,1); polyLine->GetPointIds()->SetId(2,2); polyLine->GetPointIds()->SetId(3,3); /*generate and define polyline2 vtkPolyLine *polyLine2 = vtkPolyLine::New(); polyLine2->GetPointIds()->SetNumberOfIds(2); polyLine2->GetPointIds()->SetId(0,4); polyLine2->GetPointIds()->SetId(1,5); */ /* vtkVertex *vtx = vtkVertex::New(); vtx->GetPointIds()->SetNumberOfIds(1); vtx->GetPointIds()->SetId(0,4); vtkCellArray *lines = vtkCellArray::New(); lines->InsertNextCell(polyLine); //lines->InsertNextCell(vtx); //lines->InsertNextCell(polyLine2); vtkCellArray *vertx = vtkCellArray::New(); vertx->InsertNextCell(vtx); vtkPolyData *polyDataT = vtkPolyData::New(); polyDataT->SetPoints(pnts); polyDataT->SetLines(lines); polyDataT->SetVerts(vertx); //color and opacity handling vtkUnsignedCharArray *colorT = vtkUnsignedCharArray::New(); colorT->SetName("Colors"); colorT->SetNumberOfComponents(4); //4 components cuz of RGBA unsigned char rgba[4] = {255,0,0,255}; unsigned char rgba2[4] = {0,255,0,255}; //if just 1 point in there colorT->InsertNextTupleValue(rgba); colorT->InsertNextTupleValue(rgba2); colorT->InsertNextTupleValue(rgba); colorT->InsertNextTupleValue(rgba2); colorT->InsertNextTupleValue(rgba); /*for(int i=0; i<6; i++) { double vtkPntTmp[3]; pnts->GetPoint(i, vtkPntTmp); double vtkPntTmpNxt[3]; pnts->GetPoint(i+1, vtkPntTmpNxt); vnl_vector_fixed< double, 3 > tmpPntvtk( vtkPntTmp[0], vtkPntTmp[1],vtkPntTmp[2]); vnl_vector_fixed< double, 3 > nxttmpPntvtk(vtkPntTmpNxt[0], vtkPntTmpNxt[1], vtkPntTmpNxt[2]); vnl_vector_fixed< double, 3 > diff; diff = tmpPntvtk - nxttmpPntvtk; diff.normalize(); rgba[0] = (unsigned char) (255.0 * std::abs(diff[0])); rgba[1] = (unsigned char) (255.0 * std::abs(diff[1])); rgba[2] = (unsigned char) (255.0 * std::abs(diff[2])); rgba[3] = (unsigned char) (255.0); if(i==3) { colorT->InsertNextTupleValue(rgba); colorT->InsertNextTupleValue(rgba); }else if(i==4) { //do nothing }else{ colorT->InsertNextTupleValue(rgba); } } /* unsigned char red[4] = {255, 0, 0 , 20}; unsigned char green[4] = {0, 255, 0 , 190}; unsigned char blue[4] = {0, 0, 255, 255}; unsigned char white[4] = {255, 255, 255, 255}; colorT->InsertNextTupleValue(red); //color for point0 colorT->InsertNextTupleValue(green); //color for point1 colorT->InsertNextTupleValue(blue); colorT->InsertNextTupleValue(white); colorT->InsertNextTupleValue(white); colorT->InsertNextTupleValue(white); //color for point5 polyDataT->GetPointData()->AddArray(colorT); vtkTubeFilter *tube = vtkTubeFilter::New(); tube->SetInput(polyDataT); tube->SetNumberOfSides(8); tube->SetRadius(5); vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetInput(polyDataT); //mapper->SetInputConnection(tube->GetOutputPort()); mapper->ScalarVisibilityOn(); mapper->SetScalarModeToUsePointFieldData(); //mapper->SetColorModeToMapScalars(); mapper->SelectColorArray("Colors"); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); actor->GetProperty()->SetOpacity(1.0); //actor->GetProperty()->SetLineWidth(20); actor->GetProperty()->SetPointSize(5.0); vtkSmartPointer renderer = vtkSmartPointer::New(); renderer->AddActor(actor); //renderer->SetBackground(.2, .3, .4); // Make an oblique view renderer->GetActiveCamera()->Azimuth(30); renderer->GetActiveCamera()->Elevation(30); renderer->ResetCamera(); vtkSmartPointer renWin = vtkSmartPointer::New(); vtkSmartPointer iren = vtkSmartPointer::New(); iren->SetRenderWindow(renWin); renWin->AddRenderer(renderer); //renWin->LineSmoothingOff(); renWin->SetSize(500, 500); renWin->Render(); vtkSmartPointer style = vtkSmartPointer::New(); iren->SetInteractorStyle(style); iren->Start(); MITK_INFO << "swerwas"; /* // Spiral tube double vX, vY, vZ; unsigned int nV = 256; // No. of vertices unsigned int nCyc = 5; // No. of spiral cycles double rT1 = 0.1, rT2 = 0.5;// Start/end tube radii double rS = 2; // Spiral radius double h = 10; // Height unsigned int nTv = 8; // No. of surface elements for each tube vertex unsigned int i; // Create points and cells for the spiral vtkSmartPointer points = vtkSmartPointer::New(); for(i = 0; i < nV; i++) { // Spiral coordinates vX = rS * cos(2 * 3 * nCyc * i / (nV - 1)); vY = rS * sin(2 * 3 * nCyc * i / (nV - 1)); vZ = h * i / nV; points->InsertPoint(i, vX, vY, vZ); } vtkSmartPointer lines = vtkSmartPointer::New(); lines->InsertNextCell(nV); for (i = 0; i < nV; i++) { lines->InsertCellPoint(i); } vtkSmartPointer polyData = vtkSmartPointer::New(); polyData->SetPoints(points); polyData->SetLines(lines); // RBG array (could add Alpha channel too I guess...) // Varying from blue to red vtkSmartPointer colors = vtkSmartPointer::New(); colors->SetName("Colors"); colors->SetNumberOfComponents(3); colors->SetNumberOfTuples(nV); for (i = 0; i < nV ;i++) { unsigned char red[3] = {char(255 * i/ (nV - 1)),0,char(255 * (nV - 1 - i)/(nV - 1))}; colors->InsertNextTupleValue( red); } polyData->GetPointData()->AddArray(colors); vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetInput(polyData); mapper->ScalarVisibilityOn(); mapper->SetScalarModeToUsePointFieldData(); mapper->SelectColorArray("Colors"); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); vtkSmartPointer renderer = vtkSmartPointer::New(); renderer->AddActor(actor); renderer->SetBackground(.2, .3, .4); // Make an oblique view renderer->GetActiveCamera()->Azimuth(30); renderer->GetActiveCamera()->Elevation(30); renderer->ResetCamera(); vtkSmartPointer renWin = vtkSmartPointer::New(); vtkSmartPointer iren = vtkSmartPointer::New(); iren->SetRenderWindow(renWin); renWin->AddRenderer(renderer); renWin->SetSize(500, 500); renWin->Render(); vtkSmartPointer style = vtkSmartPointer::New(); iren->SetInteractorStyle(style); iren->Start(); /* double origin[3] = {0.0, 0.0, 0.0}; double p0[3] = {10.0, 0.0, 0.0}; double p1[3] = {10.0, 10.0, 0.0}; double p2[3] = {0.0, 10.0, 0.0}; double p3[3] = {10.0, 10.0, 0.0}; double p4[3] = {10.0, 20.0, 0.0}; double p5[3] = {0.0, 20.0, 0.0}; //create a vtkPoints object and store the points in it vtkSmartPointer points = vtkSmartPointer::New(); points->InsertNextPoint(origin); points->InsertNextPoint(p0); points->InsertNextPoint(p1); points->InsertNextPoint(p2); points->InsertNextPoint(p3); points->InsertNextPoint(p4); points->InsertNextPoint(p5); vtkSmartPointer polyLine = vtkSmartPointer::New(); polyLine->GetPointIds()->SetNumberOfIds(7); for(unsigned int i = 0; i < 7; i++) { polyLine->GetPointIds()->SetId(i,i); } double origin2[3] = {30.0, 0.0, 0.0}; double p02[3] = {40.0, 0.0, 0.0}; double p12[3] = {40.0, 20.0, 0.0}; double p22[3] = {30.0, 20.0, 0.0}; double p23[3] = {30.0, 0.0, 0.0}; points->InsertNextPoint(origin2); points->InsertNextPoint(p02); points->InsertNextPoint(p12); points->InsertNextPoint(p22); points->InsertNextPoint(p23); vtkSmartPointer polyLine2 = vtkSmartPointer::New(); polyLine2->GetPointIds()->SetNumberOfIds(5); for(unsigned int i = 0; i < 5; i++) { polyLine2->GetPointIds()->SetId(i,i+7); } //Create a cell array to store the lines in and add the lines to it vtkSmartPointer cells = vtkSmartPointer::New(); cells->InsertNextCell(polyLine); cells->InsertNextCell(polyLine2); //Create a polydata to store everything in vtkSmartPointer polyData = vtkSmartPointer::New(); //add the points to the dataset polyData->SetPoints(points); //add the lines to the dataset polyData->SetLines(cells); //setup actor and mapper vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetInput(polyData); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); m_FiberAssembly->AddPart(actor); */ } //template mitk::FiberBundleMapper3D::~FiberBundleMapper3D() { - //MITK_INFO << "FiberBundleMapper3D(destructor)"; + MITK_INFO << "FiberBundleMapper3D(destructor)"; m_FiberActor->Delete(); m_FiberAssembly->Delete(); //m_vtkFiberList->Delete(); //m_VtkFiberDataMapperGL->Delete(); //m_VtkFiberDataMapper->Delete(); } const mitk::FiberBundle* mitk::FiberBundleMapper3D::GetInput() { //MITK_INFO << "FiberBundleMapper3D GetInput()" ; return static_cast ( GetData() ); } +vtkOpenGLPolyDataMapper* mitk::FiberBundleMapper3D::getVtkFiberBundleMapper() +{ + return m_VtkFiberDataMapperGL; +} + /* This method is called once the mapper gets new input, for UI rotation or changes in colorcoding this method is NOT called */ void mitk::FiberBundleMapper3D::GenerateData() { /* ######## FIBER PREPARATION START ######### */ //get fiberbundle mitk::FiberBundle::Pointer PFiberBundle = dynamic_cast< mitk::FiberBundle* > (this->GetData()); //get groupFiberBundle, which is a datastructure containing single fibers mitk::FiberBundle::FiberGroupType::Pointer groupFiberBundle = PFiberBundle->GetGroupFiberBundle(); //extractn single fibers //in the groupFiberBundle all smartPointers to single fibers are stored in in a ChildrenList mitk::FiberBundle::ChildrenListType * FiberList; FiberList = groupFiberBundle->GetChildren(); /* ######## FIBER PREPARATION END ######### */ /* ######## VTK FIBER REPRESENTATION ######## */ //create a vtkPoints object and store the all the brainFiber points in it vtkPoints* vtkSmoothPoints = vtkPoints::New(); //in smoothpoints the interpolated points representing a fiber are stored. //in vtkcells all polylines are stored, actually all id's of them are stored vtkCellArray *vtkSmoothCells = vtkCellArray::New(); //cellcontainer for smoothed lines //in some cases a fiber includes just 1 point, so put it in here vtkCellArray *vtkVrtxs = vtkCellArray::New(); //colors and alpha value for each single point, RGBA = 4 components vtkUnsignedCharArray *colorsT = vtkUnsignedCharArray::New(); colorsT->SetNumberOfComponents(4); colorsT->SetName("ColorValues"); vtkDoubleArray *faColors = vtkDoubleArray::New(); faColors->SetName("FaColors"); vtkDoubleArray *tubeRadius = vtkDoubleArray::New(); tubeRadius->SetName("TubeRadius"); // iterate through FiberList for(mitk::FiberBundle::ChildrenListType::iterator itLst = FiberList->begin(); itLst != FiberList->end(); ++itLst) { //all points are stored in one vtkpoints list, soooooooo that the lines find their point id to start and end we need some kind of helper index who monitors the current ids for a polyline //unsigned long pntIdxHelper = vtkpointsDTI->GetNumberOfPoints(); // lists output is SpatialObject, we know we have DTITubeSpacialObjects // dynamic cast only likes pointers, no smartpointers, so each dsmartpointer has membermethod .GetPointer() itk::SpatialObject<3>::Pointer tmp_fbr; tmp_fbr = *itLst; mitk::FiberBundle::DTITubeType::Pointer dtiTract = dynamic_cast< mitk::FiberBundle::DTITubeType * > (tmp_fbr.GetPointer()); if (dtiTract.IsNull()) { return; } //get list of points int fibrNrPnts = dtiTract->GetNumberOfPoints(); mitk::FiberBundle::DTITubeType::PointListType dtiPntList = dtiTract->GetPoints(); //MITK_INFO << "REAL AMOUNT OF FIBERS: " << fibrNrPnts; vtkPoints *vtkpointsDTI = vtkPoints::New(); if (fibrNrPnts <= 0) { //this should never occour! but who knows MITK_INFO << "HyperERROR in fiberBundleMapper3D.cpp ...no point in fiberBundle!!! .. check ur trackingAlgorithm"; continue; } ///////PROCESS ON FIBERS//////// for (int i=0; i1 PFiberBundle->GetGeometry()->IndexToWorld(indexPnt, worldPnt); double worldFbrPnt[3] = {worldPnt[0], worldPnt[1], worldPnt[2]}; vtkpointsDTI->InsertNextPoint(worldFbrPnt); } //MITK_INFO << "REDUCED AMOUNT OF FIBERS: " << vtkpointsDTI->GetNumberOfPoints(); ////POINTS OF DTI ARE READY FOR FUTHER VTK PROCESSING//// } /////PROCESS POLYLINE SMOOTHING///// vtkKochanekSpline* xSpline = vtkKochanekSpline::New(); vtkKochanekSpline* ySpline = vtkKochanekSpline::New(); vtkKochanekSpline* zSpline = vtkKochanekSpline::New(); vtkParametricSpline* spline = vtkParametricSpline::New(); spline->SetXSpline(xSpline); spline->SetYSpline(ySpline); spline->SetZSpline(zSpline); spline->SetPoints(vtkpointsDTI); vtkParametricFunctionSource* functionSource = vtkParametricFunctionSource::New(); functionSource->SetParametricFunction(spline); functionSource->SetUResolution(200); functionSource->SetVResolution(200); functionSource->SetWResolution(200); functionSource->Update(); vtkPolyData* outputFunction = functionSource->GetOutput(); vtkPoints* tmpSmoothPnts = outputFunction->GetPoints(); //smoothPoints of current fiber vtkPolyLine* smoothLine = vtkPolyLine::New(); smoothLine->GetPointIds()->SetNumberOfIds(tmpSmoothPnts->GetNumberOfPoints()); // MITK_INFO << "SMOOTHED AMOUNT OF POINTS:" << tmpSmoothPnts->GetNumberOfPoints(); /////CREATE SMOOTH POLYLINE OBJECT//// /////MANAGE LINE AND CORRELATED POINTS///// int pointHelperCnt = vtkSmoothPoints->GetNumberOfPoints(); //also put current points into global smooth pointcontainer int nrSmPnts = tmpSmoothPnts->GetNumberOfPoints(); tubeRadius->SetNumberOfTuples(nrSmPnts); double tbradius = 1;//default value for radius for(int ism=0; ismGetPointIds()->SetId(ism, ism+pointHelperCnt); vtkSmoothPoints->InsertNextPoint(tmpSmoothPnts->GetPoint(ism)); // MITK_INFO << "LinePntID: " << ism << " linked to: " << ism+pointHelperCnt << " val: " << tmpSmoothPnts->GetPoint(ism)[0] << " " << tmpSmoothPnts->GetPoint(ism)[1] << " " << tmpSmoothPnts->GetPoint(ism)[2]; tubeRadius->SetTuple1(ism,tbradius); //tuple with 1 argument //colorcoding orientation based unsigned char rgba[4] = {0,0,0,0}; if (ism < nrSmPnts-1 && ism>0) { // MITK_INFO << "inbetween fiber, at position:" << ism; // //nimm nur diff1 vnl_vector_fixed< double, 3 > tmpPntvtk(tmpSmoothPnts->GetPoint(ism)[0], tmpSmoothPnts->GetPoint(ism)[1],tmpSmoothPnts->GetPoint(ism)[2]); vnl_vector_fixed< double, 3 > nxttmpPntvtk(tmpSmoothPnts->GetPoint(ism+1)[0], tmpSmoothPnts->GetPoint(ism+1)[1], tmpSmoothPnts->GetPoint(ism+1)[2]); vnl_vector_fixed< double, 3 > prevtmpPntvtk(tmpSmoothPnts->GetPoint(ism-1)[0], tmpSmoothPnts->GetPoint(ism-1)[1], tmpSmoothPnts->GetPoint(ism-1)[2]); vnl_vector_fixed< double, 3 > diff1; diff1 = tmpPntvtk - nxttmpPntvtk; diff1.normalize(); vnl_vector_fixed< double, 3 > diff2; diff2 = tmpPntvtk - prevtmpPntvtk; diff2.normalize(); vnl_vector_fixed< double, 3 > diff; diff = (diff1 - diff2)/2.0; rgba[0] = (unsigned char) (255.0 * std::abs(diff[0])); rgba[1] = (unsigned char) (255.0 * std::abs(diff[1])); rgba[2] = (unsigned char) (255.0 * std::abs(diff[2])); rgba[3] = (unsigned char) (255.0); } else if(ism==0) { //explicit handling of startpoint of line //nimm nur diff1 vnl_vector_fixed< double, 3 > tmpPntvtk(tmpSmoothPnts->GetPoint(ism)[0], tmpSmoothPnts->GetPoint(ism)[1],tmpSmoothPnts->GetPoint(ism)[2]); vnl_vector_fixed< double, 3 > nxttmpPntvtk(tmpSmoothPnts->GetPoint(ism+1)[0], tmpSmoothPnts->GetPoint(ism+1)[1], tmpSmoothPnts->GetPoint(ism+1)[2]); vnl_vector_fixed< double, 3 > diff1; diff1 = tmpPntvtk - nxttmpPntvtk; diff1.normalize(); rgba[0] = (unsigned char) (255.0 * std::abs(diff1[0])); rgba[1] = (unsigned char) (255.0 * std::abs(diff1[1])); rgba[2] = (unsigned char) (255.0 * std::abs(diff1[2])); rgba[3] = (unsigned char) (255.0); // MITK_INFO << "first point color: " << rgba[0] << " " << rgba[1] << " " << rgba[2]; } else if(ism==nrSmPnts-1) { // last point in fiber // nimm nur diff2 vnl_vector_fixed< double, 3 > tmpPntvtk(tmpSmoothPnts->GetPoint(ism)[0], tmpSmoothPnts->GetPoint(ism)[1],tmpSmoothPnts->GetPoint(ism)[2]); vnl_vector_fixed< double, 3 > prevtmpPntvtk(tmpSmoothPnts->GetPoint(ism-1)[0], tmpSmoothPnts->GetPoint(ism-1)[1], tmpSmoothPnts->GetPoint(ism-1)[2]); vnl_vector_fixed< double, 3 > diff2; diff2 = tmpPntvtk - prevtmpPntvtk; diff2.normalize(); rgba[0] = (unsigned char) (255.0 * std::abs(diff2[0])); rgba[1] = (unsigned char) (255.0 * std::abs(diff2[1])); rgba[2] = (unsigned char) (255.0 * std::abs(diff2[2])); rgba[3] = (unsigned char) (255.0); // // MITK_INFO << "last point color: " << rgba[0] << " " << rgba[1] << " " << rgba[2]; } //end colorcoding // colorsT->InsertNextTupleValue(rgba); }//end of smoothline ///////smooth Fiber ready//////// vtkSmoothCells->InsertNextCell(smoothLine); } //vtkpointsDTI->Delete();//points are not needed anymore TODO uncomment! /* //get FA value ... for that FA has to be interpolated as well as DTItracktLine float faVal = tmpFiberPntLst.GetField(mitk::FiberBundle::DTITubePointType::FA); //use insertNextValue cuz FA Values are reperesented as a single number (1 Tuple containing 1 parameter) faColors->InsertNextValue((double) faVal); */ //vtkcells->InitTraversal(); // Put points and lines together in one polyData structure vtkPolyData *polyData = vtkPolyData::New(); polyData->SetPoints(vtkSmoothPoints); polyData->SetLines(vtkSmoothCells); if (vtkVrtxs->GetSize() > 0) { polyData->SetVerts(vtkVrtxs); } polyData->GetPointData()->AddArray(colorsT); //polyData->GetPointData()->AddArray(faColors); //polyData->GetPointData()->AddArray(tubeRadius); vtkLookupTable *lut = vtkLookupTable::New(); lut->Build(); // m_VtkFiberDataMapperGL = vtkOpenGLPolyDataMapper::New(); m_VtkFiberDataMapperGL->SetInput(polyData); m_VtkFiberDataMapperGL->ScalarVisibilityOn(); m_VtkFiberDataMapperGL->SetScalarModeToUsePointFieldData(); //m_VtkFiberDataMapperGL->SelectColorArray("FaColors"); m_VtkFiberDataMapperGL->SelectColorArray("ColorValues"); m_VtkFiberDataMapperGL->SetLookupTable(lut); m_vtkTubeMapper = vtkOpenGLPolyDataMapper::New(); //m_FiberActor = vtkOpenGLActor::New(); m_FiberActor->SetMapper(m_VtkFiberDataMapperGL); m_FiberActor->GetProperty()->SetOpacity(1.0); m_FiberActor->GetProperty()->SetPointSize(4.0f); // m_FiberActor->GetProperty()->SetColor(255.0, 0.0, 0.0); m_FiberAssembly->AddPart(m_FiberActor); //setting color and opacity in the fiberActor itself is not recommended //here cuz color and opacity of dataNode will be considered in GetData(baserenderer*) anyway this->GetDataNode()->SetColor(255.0,0,0); this->GetDataNode()->SetOpacity(1.0); } //template void mitk::FiberBundleMapper3D::GenerateDataForRenderer( mitk::BaseRenderer *renderer ) { // nodeCC = 1 ... ROI colorcoding // 2 ... orientation colorcoding // 3 ... FA colorcoding int nodeCC; bool isCCd = this->GetDataNode()->GetPropertyValue("ColorCoding", nodeCC); if ( isCCd && nodeCC == 1 ) { //get color and opacity from DataNode int tmpline; bool isLineProp = this->GetDataNode()->GetPropertyValue("LineWidth",tmpline); bool isPointRep; bool successPointProp = this->GetDataNode()->GetPropertyValue("RepPoints", isPointRep); float pointSize; bool successPointSize = this->GetDataNode()->GetPropertyValue("pointSize", pointSize); if (isLineProp) { m_FiberActor->GetProperty()->SetLineWidth(tmpline); } if(isPointRep) { m_FiberActor->GetProperty()->SetRepresentationToPoints(); m_FiberActor->GetProperty()->SetPointSize(pointSize); } } else if (isCCd && nodeCC == 2) { float tmpopa; this->GetDataNode()->GetOpacity(tmpopa, NULL); m_FiberActor->GetProperty()->SetOpacity((double) tmpopa); } else if (isCCd && nodeCC == 3) { float temprgb[3]; this->GetDataNode()->GetColor( temprgb, NULL ); double trgb[3] = { (double) temprgb[0], (double) temprgb[1], (double) temprgb[2] }; m_FiberActor->GetProperty()->SetColor(trgb); if(m_VtkFiberDataMapperGL->GetScalarVisibility()) //can be 0 or 1, for scalarVis On or Off { m_VtkFiberDataMapperGL->ScalarVisibilityOff(); } } else if (isCCd && nodeCC == 4) { if(!m_VtkFiberDataMapperGL->GetScalarVisibility()) //can be 0 or 1, for scalarVis On or Off { m_VtkFiberDataMapperGL->ScalarVisibilityOn(); } m_VtkFiberDataMapperGL->SelectColorArray("ColorValues"); } else if (isCCd && nodeCC == 5){ if(!m_VtkFiberDataMapperGL->GetScalarVisibility()) //if visibility is off, switch it on { m_VtkFiberDataMapperGL->ScalarVisibilityOn(); } m_VtkFiberDataMapperGL->SelectColorArray("FaColors"); } else if (isCCd && nodeCC == 6){ //orientationbased colorcoding + FA as opacity //get FA out of polydata, which is saved in faColor vtkDoubleArray vtkPolyData *tmpPolyData = m_VtkFiberDataMapperGL->GetInput(); vtkPointData *tmpPointData = tmpPolyData->GetPointData(); int hasAr = tmpPointData->HasArray("FaColors"); if(!hasAr) return; vtkDoubleArray *tmpFAarray = (vtkDoubleArray*)(tmpPointData->GetArray("FaColors")) ; /*for(int i=0; iGetNumberOfTuples(); i++) { double *tmpTuple; tmpFAarray->GetTuple(i, tmpTuple); for(int j=0; jGetNumberOfComponents(); j++) { MITK_INFO << "FA Value: at index " << i << ": " << tmpTuple[j]; } } */ //since we have our FA values, lets replace the alpha values in colorT //we know each 4th entry is a A value of RGBA int hasArCV = tmpPointData->HasArray("ColorValues"); if(!hasArCV) return; vtkUnsignedCharArray *colorsTtmp = dynamic_cast (tmpPointData->GetArray("ColorValues")); for(int i=0; iGetNumberOfTuples(); i++) { //double *tmpTupleCV = colorsTtmp->GetTuple4(i); double tmpTupleFA = tmpFAarray->GetTuple1(i); tmpTupleFA = tmpTupleFA * 255.0; colorsTtmp->SetComponent(i,3, tmpTupleFA ); // MITK_INFO << "----" << i; //MITK_INFO << tmpTupleCV[0]; //MITK_INFO << tmpTupleCV[1]; //MITK_INFO << tmpTupleCV[2]; //MITK_INFO << tmpTupleCV[3]; //double *test = m_VtkFiberDataMapperGL->GetInput()->GetPointData()->GetArray("ColorValues")->GetTuple4(i); //MITK_INFO << test[0]; //MITK_INFO << test[1]; //MITK_INFO << test[2]; //MITK_INFO << test[3]; } m_VtkFiberDataMapperGL->SelectColorArray(""); m_VtkFiberDataMapperGL->SelectColorArray("ColorValues"); } else if (isCCd && nodeCC == 7){ vtkPolyData *tmpPolyData = m_VtkFiberDataMapperGL->GetInput(); vtkPointData *tmpPointData = tmpPolyData->GetPointData(); int hasArCV = tmpPointData->HasArray("ColorValues"); if(!hasArCV) return; vtkUnsignedCharArray *colorsTtmp = dynamic_cast (tmpPointData->GetArray("ColorValues")); for(int i=0; iGetNumberOfTuples(); i++) { double tmpTupleFA = 255.0; colorsTtmp->SetComponent(i,3, tmpTupleFA ); } m_VtkFiberDataMapperGL->SelectColorArray(""); m_VtkFiberDataMapperGL->SelectColorArray("ColorValues"); } else if (isCCd && nodeCC == 8) { /* something is still missing to activate smoothing or make it work.... */ if (!renderer->GetRenderWindow()->GetLineSmoothing()) { renderer->GetRenderWindow()->SetLineSmoothing(1); renderer->GetRenderWindow()->Modified(); } if (!renderer->GetRenderWindow()->GetPointSmoothing()) { renderer->GetRenderWindow()->SetPointSmoothing(1); renderer->GetRenderWindow()->Modified(); } if (!renderer->GetRenderWindow()->GetPolygonSmoothing()) { renderer->GetRenderWindow()->SetPolygonSmoothing(1); renderer->GetRenderWindow()->Modified(); } } else if (isCCd && nodeCC == 9) { if (renderer->GetRenderWindow()->GetLineSmoothing()) { renderer->GetRenderWindow()->SetLineSmoothing(0); renderer->GetRenderWindow()->Modified(); } if (renderer->GetRenderWindow()->GetPointSmoothing()) { renderer->GetRenderWindow()->SetPointSmoothing(0); renderer->GetRenderWindow()->Modified(); } if (renderer->GetRenderWindow()->GetPolygonSmoothing()) { renderer->GetRenderWindow()->SetPolygonSmoothing(0); renderer->GetRenderWindow()->Modified(); } } else if (isCCd && nodeCC == 10) { // manipulate X Coordinates of selected FiberBundle int tmpXmove; bool isXmove = this->GetDataNode()->GetPropertyValue("Xmove",tmpXmove); if (!isXmove) return; vtkPolyData *tmpPolyData = m_VtkFiberDataMapperGL->GetInput(); vtkPoints* tmpVtkPnts = tmpPolyData->GetPoints(); double PtmpPntVal[3]; for (int i=0; iGetNumberOfPoints(); ++i ) { tmpVtkPnts->GetPoint(i,PtmpPntVal); PtmpPntVal[0] = PtmpPntVal[0] + (double) tmpXmove; tmpVtkPnts->SetPoint(i, PtmpPntVal); tmpPolyData->Modified(); } } else if (isCCd && nodeCC == 11) { // manipulate Y Coordinates of selected FiberBundle int tmpYmove; bool isYmove = this->GetDataNode()->GetPropertyValue("Ymove",tmpYmove); if (!isYmove) return; vtkPolyData *tmpPolyData = m_VtkFiberDataMapperGL->GetInput(); vtkPoints* tmpVtkPnts = tmpPolyData->GetPoints(); double PtmpPntVal[3]; for (int i=0; iGetNumberOfPoints(); ++i ) { tmpVtkPnts->GetPoint(i,PtmpPntVal); PtmpPntVal[1] = PtmpPntVal[1] + (double) tmpYmove; tmpVtkPnts->SetPoint(i, PtmpPntVal); tmpPolyData->Modified(); } } else if (isCCd && nodeCC == 12) { // manipulate Z Coordinates of selected FiberBundle int tmpZmove; bool isZmove = this->GetDataNode()->GetPropertyValue("Zmove",tmpZmove); if (!isZmove) return; vtkPolyData *tmpPolyData = m_VtkFiberDataMapperGL->GetInput(); vtkPoints* tmpVtkPnts = tmpPolyData->GetPoints(); double PtmpPntVal[3]; for (int i=0; iGetNumberOfPoints(); ++i ) { tmpVtkPnts->GetPoint(i,PtmpPntVal); PtmpPntVal[2] = PtmpPntVal[2] + (double) tmpZmove; //PtmpPntVal[2] = PtmpPntVal[2] + 1; tmpVtkPnts->SetPoint(i, PtmpPntVal); tmpPolyData->Modified(); } } else if (isCCd && nodeCC == 13) { int tmpTubeSides; bool isTubeSides = this->GetDataNode()->GetPropertyValue("TubeSides",tmpTubeSides); float tmpRadius; bool isRadius = this->GetDataNode()->GetPropertyValue("TubeRadius",tmpRadius); if (!isTubeSides) return; vtkPolyData *tmpPolyData = m_VtkFiberDataMapperGL->GetInput(); m_tubes = vtkTubeFilter::New(); m_tubes->SetInput(tmpPolyData); m_tubes->SidesShareVerticesOn(); m_tubes->SetRadius((double)(tmpRadius)); m_tubes->SetNumberOfSides(tmpTubeSides); m_tubes->Modified(); // m_tubes->Update(); m_vtkTubeMapper->SetInputConnection(m_tubes->GetOutputPort()); m_vtkTubeMapper->ScalarVisibilityOn(); m_vtkTubeMapper->SetScalarModeToUsePointFieldData(); m_vtkTubeMapper->SelectColorArray(""); m_vtkTubeMapper->SelectColorArray("ColorValues"); m_TubeActor->SetMapper(m_vtkTubeMapper); m_TubeActor->GetProperty()->SetOpacity(1); m_TubeActor->GetProperty()->BackfaceCullingOn(); m_FiberAssembly->AddPart(m_TubeActor); m_FiberAssembly->Modified(); } else if (isCCd && nodeCC == 14) { float temprgb[3]; this->GetDataNode()->GetColor( temprgb, NULL ); double trgb[3] = { (double) temprgb[0], (double) temprgb[1], (double) temprgb[2] }; m_TubeActor->GetProperty()->SetColor(trgb); if(m_vtkTubeMapper->GetScalarVisibility()) //can be 0 or 1, for scalarVis On or Off { m_vtkTubeMapper->ScalarVisibilityOff(); } } else if (isCCd && nodeCC == 15) { m_TubeActor->GetProperty()->SetOpacity(0); m_FiberAssembly->RemovePart(m_TubeActor); m_FiberAssembly->Modified(); }else if (isCCd && nodeCC == 16) { float tmpTubeOpacity; bool isTubeOpacity = this->GetDataNode()->GetPropertyValue("TubeOpacity",tmpTubeOpacity); m_TubeActor->GetProperty()->SetOpacity((double) tmpTubeOpacity); m_TubeActor->Modified(); } else if (isCCd && nodeCC == 17) { m_FiberActor->GetProperty()->SetOpacity(0); m_FiberAssembly->RemovePart(m_FiberActor); m_FiberAssembly->Modified(); }else if (isCCd && nodeCC == 18) { m_FiberActor->GetProperty()->SetOpacity(0); m_FiberAssembly->AddPart(m_FiberActor); m_FiberAssembly->Modified(); } //MITK_INFO << m_VtkFiberDataMapperGL->GetArrayName(); /* int displayIndex(0); this->GetDataNode()->GetIntProperty( "DisplayChannel", displayIndex, renderer ); InputImageType *input = const_cast< InputImageType* >( this->GetInput() ); mitk::DiffusionImage *input2 = dynamic_cast< mitk::DiffusionImage* >( input ); input2->SetDisplayIndexForRendering(displayIndex); Superclass::GenerateDataForRenderer(renderer); */ } //template void mitk::FiberBundleMapper3D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { // MITK_INFO << "FiberBundleMapper3D SetDefault Properties(...)"; node->AddProperty( "DisplayChannel", mitk::IntProperty::New( true ), renderer, overwrite ); node->AddProperty( "LineWidth", mitk::IntProperty::New( true ), renderer, overwrite ); node->AddProperty( "ColorCoding", mitk::IntProperty::New( 0 ), renderer, overwrite); node->AddProperty( "VertexOpacity_1", mitk::BoolProperty::New( false ), renderer, overwrite); node->AddProperty( "Set_FA_VertexAlpha", mitk::BoolProperty::New( false ), renderer, overwrite); node->AddProperty( "pointSize", mitk::FloatProperty::New(0.5), renderer, overwrite); node->AddProperty( "setShading", mitk::IntProperty::New(1), renderer, overwrite); node->AddProperty( "Xmove", mitk::IntProperty::New( 0 ), renderer, overwrite); node->AddProperty( "Ymove", mitk::IntProperty::New( 0 ), renderer, overwrite); node->AddProperty( "Zmove", mitk::IntProperty::New( 0 ), renderer, overwrite); node->AddProperty( "RepPoints", mitk::BoolProperty::New( false ), renderer, overwrite); node->AddProperty( "TubeSides", mitk::IntProperty::New( 8 ), renderer, overwrite); node->AddProperty( "TubeRadius", mitk::FloatProperty::New( 0.15 ), renderer, overwrite); node->AddProperty( "TubeOpacity", mitk::FloatProperty::New( 1.0 ), renderer, overwrite); node->AddProperty( "pickable", mitk::BoolProperty::New( true ), renderer, overwrite); Superclass::SetDefaultProperties(node, renderer, overwrite); } vtkProp* mitk::FiberBundleMapper3D::GetVtkProp(mitk::BaseRenderer *renderer) { //MITK_INFO << "FiberBundleMapper3D GetVtkProp(renderer)"; return m_FiberAssembly; } void mitk::FiberBundleMapper3D::ApplyProperties(mitk::BaseRenderer* renderer) { // MITK_INFO << "FiberBundleMapper3D ApplyProperties(renderer)"; } void mitk::FiberBundleMapper3D::UpdateVtkObjects() { // MITK_INFO << "FiberBundleMapper3D UpdateVtkObjects()"; } void mitk::FiberBundleMapper3D::SetVtkMapperImmediateModeRendering(vtkMapper *) { } diff --git a/Modules/DiffusionImaging/Rendering/mitkFiberBundleMapper3D.h b/Modules/DiffusionImaging/Rendering/mitkFiberBundleMapper3D.h index be68501d9d..07cd89400f 100644 --- a/Modules/DiffusionImaging/Rendering/mitkFiberBundleMapper3D.h +++ b/Modules/DiffusionImaging/Rendering/mitkFiberBundleMapper3D.h @@ -1,103 +1,103 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2009-05-12 19:56:03 +0200 (Di, 12 Mai 2009) $ Version: $Revision: 17179 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef FiberBundleMapper3D_H_HEADER_INCLUDED #define FiberBundleMapper3D_H_HEADER_INCLUDED //#include "mitkCommon.h" //#include "mitkBaseRenderer.h" #include "mitkFiberBundle.h" #include #include "mitkVtkMapper3D.h" #include "MitkDiffusionImagingExports.h" //#include "mitkBaseData.h" #include "vtkAppendPolyData.h" #include "vtkOpenGLPolyDataMapper.h" #include "vtkOpenGLActor.h" #include "vtkPropAssembly.h" #include "vtkProperty.h" #include "vtkUnsignedCharArray.h" #include "vtkTubeFilter.h" namespace mitk { //##Documentation //## @brief Mapper for FiberBundles //## @ingroup Mapper // template class MitkDiffusionImaging_EXPORT FiberBundleMapper3D : public VtkMapper3D { public: mitkClassMacro(FiberBundleMapper3D, VtkMapper3D); itkNewMacro(Self); const mitk::FiberBundle* GetInput(); virtual vtkProp *GetVtkProp(mitk::BaseRenderer *renderer); //looks like depricated.. should be replaced bz GetViewProp() static void SetDefaultProperties(DataNode* node, BaseRenderer* renderer = NULL, bool overwrite = false ); virtual void ApplyProperties(mitk::BaseRenderer* renderer); static void SetVtkMapperImmediateModeRendering(vtkMapper *mapper); virtual void GenerateDataForRenderer(mitk::BaseRenderer* renderer); virtual void GenerateData(); - + vtkOpenGLPolyDataMapper* getVtkFiberBundleMapper(); protected: FiberBundleMapper3D(); virtual ~FiberBundleMapper3D(); void UpdateVtkObjects(); vtkAppendPolyData *m_vtkFiberList; //vtkSmartPointer m_vtkFiberList; vtkOpenGLPolyDataMapper *m_VtkFiberDataMapperGL; //vtkPainterPolyDataMapper *m_VtkFiberDataMapperGL; //vtkSmartPointer m_VtkFiberDataMapperGL; //vtkOpenGLPolyDataMapper *m_VtkFiberDataMapper; //vtkSmartPointer m_VtkFiberDataMapper; vtkOpenGLActor *m_FiberActor; //vtkSmartPointer m_FiberActor; vtkTubeFilter *m_tubes; vtkOpenGLActor *m_TubeActor; vtkOpenGLPolyDataMapper *m_vtkTubeMapper; vtkPropAssembly *m_FiberAssembly; }; } // namespace mitk #endif /* FiberBundleMapper3D_H_HEADER_INCLUDED */ diff --git a/Modules/DiffusionImaging/files.cmake b/Modules/DiffusionImaging/files.cmake index f7593f9911..1e86e59231 100644 --- a/Modules/DiffusionImaging/files.cmake +++ b/Modules/DiffusionImaging/files.cmake @@ -1,154 +1,156 @@ SET(CPP_FILES # DicomImport DicomImport/mitkDicomDiffusionImageReader.cpp DicomImport/mitkGroupDiffusionHeadersFilter.cpp DicomImport/mitkDicomDiffusionImageHeaderReader.cpp DicomImport/mitkGEDicomDiffusionImageHeaderReader.cpp DicomImport/mitkPhilipsDicomDiffusionImageHeaderReader.cpp DicomImport/mitkSiemensDicomDiffusionImageHeaderReader.cpp DicomImport/mitkSiemensMosaicDicomDiffusionImageHeaderReader.cpp # DataStructures IODataStructures/mitkDiffusionImagingObjectFactory.cpp # DataStructures -> DWI IODataStructures/DiffusionWeightedImages/mitkDiffusionImageHeaderInformation.cpp IODataStructures/DiffusionWeightedImages/mitkDiffusionImageSource.cpp IODataStructures/DiffusionWeightedImages/mitkNrrdDiffusionImageReader.cpp IODataStructures/DiffusionWeightedImages/mitkNrrdDiffusionImageWriter.cpp IODataStructures/DiffusionWeightedImages/mitkNrrdDiffusionImageIOFactory.cpp IODataStructures/DiffusionWeightedImages/mitkNrrdDiffusionImageWriterFactory.cpp IODataStructures/DiffusionWeightedImages/mitkDiffusionImageSerializer.cpp # DataStructures -> QBall IODataStructures/QBallImages/mitkQBallImageSource.cpp IODataStructures/QBallImages/mitkNrrdQBallImageReader.cpp IODataStructures/QBallImages/mitkNrrdQBallImageWriter.cpp IODataStructures/QBallImages/mitkNrrdQBallImageIOFactory.cpp IODataStructures/QBallImages/mitkNrrdQBallImageWriterFactory.cpp IODataStructures/QBallImages/mitkQBallImage.cpp IODataStructures/QBallImages/mitkQBallImageSerializer.cpp # DataStructures -> Tensor IODataStructures/TensorImages/mitkTensorImageSource.cpp IODataStructures/TensorImages/mitkNrrdTensorImageReader.cpp IODataStructures/TensorImages/mitkNrrdTensorImageWriter.cpp IODataStructures/TensorImages/mitkNrrdTensorImageIOFactory.cpp IODataStructures/TensorImages/mitkNrrdTensorImageWriterFactory.cpp IODataStructures/TensorImages/mitkTensorImage.cpp IODataStructures/TensorImages/mitkTensorImageSerializer.cpp # DataStructures -> FiberBundle IODataStructures/FiberBundle/mitkFiberBundle.cpp IODataStructures/FiberBundle/mitkFiberBundleWriter.cpp IODataStructures/FiberBundle/mitkFiberBundleReader.cpp IODataStructures/FiberBundle/mitkFiberBundleIOFactory.cpp IODataStructures/FiberBundle/mitkFiberBundleWriterFactory.cpp IODataStructures/FiberBundle/mitkFiberBundleSerializer.cpp IODataStructures/FiberBundle/mitkParticle.cpp IODataStructures/FiberBundle/mitkParticleGrid.cpp # DataStructures -> FiberBundleX IODataStructures/FiberBundleX/mitkFiberBundleX.cpp IODataStructures/FiberBundleX/mitkFiberBundleXWriter.cpp IODataStructures/FiberBundleX/mitkFiberBundleXReader.cpp IODataStructures/FiberBundleX/mitkFiberBundleXIOFactory.cpp IODataStructures/FiberBundleX/mitkFiberBundleXWriterFactory.cpp IODataStructures/FiberBundleX/mitkFiberBundleXSerializer.cpp IODataStructures/FiberBundleX/mitkFiberBundleXThreadMonitor.cpp # DataStructures -> PlanarFigureComposite IODataStructures/PlanarFigureComposite/mitkPlanarFigureComposite.cpp # DataStructures -> Tbss IODataStructures/TbssImages/mitkTbssImageSource.cpp IODataStructures/TbssImages/mitkNrrdTbssImageReader.cpp IODataStructures/TbssImages/mitkNrrdTbssImageIOFactory.cpp IODataStructures/TbssImages/mitkTbssImage.cpp IODataStructures/TbssImages/mitkNrrdTbssImageWriter.cpp IODataStructures/TbssImages/mitkNrrdTbssImageWriterFactory.cpp # Rendering Rendering/vtkMaskedProgrammableGlyphFilter.cpp Rendering/mitkCompositeMapper.cpp Rendering/mitkVectorImageVtkGlyphMapper3D.cpp Rendering/vtkOdfSource.cxx Rendering/vtkThickPlane.cxx Rendering/mitkOdfNormalizationMethodProperty.cpp Rendering/mitkOdfScaleByProperty.cpp + Rendering/mitkFiberBundleMapper2D.cpp Rendering/mitkFiberBundleMapper3D.cpp Rendering/mitkFiberBundleXMapper3D.cpp Rendering/mitkFiberBundleXThreadMonitorMapper3D.cpp # Interactions Interactions/mitkFiberBundleInteractor.cpp # Algorithms Algorithms/mitkPartialVolumeAnalysisHistogramCalculator.cpp Algorithms/mitkPartialVolumeAnalysisClusteringCalculator.cpp ) SET(H_FILES # Rendering Rendering/mitkDiffusionImageMapper.h Rendering/mitkOdfVtkMapper2D.h + Rendering/mitkFiberBundleMapper2D.h Rendering/mitkFiberBundleMapper3D.h Rendering/mitkFiberBundleXMapper3D.h Rendering/mitkFiberBundleXThreadMonitorMapper3D.h # Reconstruction Reconstruction/itkDiffusionQballReconstructionImageFilter.h Reconstruction/mitkTeemDiffusionTensor3DReconstructionImageFilter.h Reconstruction/itkAnalyticalDiffusionQballReconstructionImageFilter.h Reconstruction/itkPointShell.h Reconstruction/itkOrientationDistributionFunction.h # IO Datastructures IODataStructures/DiffusionWeightedImages/mitkDiffusionImage.h IODataStructures/FiberBundle/itkSlowPolyLineParametricPath.h IODataStructures/TbssImages/mitkTbssImage.h # DataStructures -> FiberBundleX IODataStructures/FiberBundleX/mitkFiberBundleX.h IODataStructures/FiberBundleX/mitkFiberBundleXWriter.h IODataStructures/FiberBundleX/mitkFiberBundleXReader.h IODataStructures/FiberBundleX/mitkFiberBundleXIOFactory.h IODataStructures/FiberBundleX/mitkFiberBundleXWriterFactory.h IODataStructures/FiberBundleX/mitkFiberBundleXSerializer.h IODataStructures/FiberBundleX/mitkFiberBundleXThreadMonitor.h # Tractography Tractography/itkGibbsTrackingFilter.h # Algorithms Algorithms/itkDiffusionQballGeneralizedFaImageFilter.h Algorithms/itkDiffusionQballPrepareVisualizationImageFilter.h Algorithms/itkTensorDerivedMeasurementsFilter.h Algorithms/itkBrainMaskExtractionImageFilter.h Algorithms/itkB0ImageExtractionImageFilter.h Algorithms/itkTensorImageToDiffusionImageFilter.h Algorithms/itkTensorToL2NormImageFilter.h Algorithms/itkTractsToProbabilityImageFilter.h Algorithms/itkTractsToDWIImageFilter.h Algorithms/itkTractsToFiberEndingsImageFilter.h Algorithms/itkGaussianInterpolateImageFunction.h Algorithms/mitkPartialVolumeAnalysisHistogramCalculator.h Algorithms/mitkPartialVolumeAnalysisClusteringCalculator.h Algorithms/itkDiffusionTensorPrincipleDirectionImageFilter.h Algorithms/itkCartesianToPolarVectorImageFilter.h Algorithms/itkPolarToCartesianVectorImageFilter.h ) SET( TOOL_FILES ) IF(WIN32) ENDIF(WIN32) #MITK_MULTIPLEX_PICTYPE( Algorithms/mitkImageRegistrationMethod-TYPE.cpp )