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 941b87dd4d..00525f156a 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,1410 +1,1417 @@ /*========================================================================= - + 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) + : 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 + 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(); - + 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 * --do color coding--*/ QmitkFiberColoringWorker::QmitkFiberColoringWorker(QThread* hostingThread, Package4WorkingThread itemPackage) -: m_itemPackage(itemPackage) -, m_hostingThread(hostingThread) + : m_itemPackage(itemPackage) + , m_hostingThread(hostingThread) { - + } void QmitkFiberColoringWorker::run() { - if(m_itemPackage.st_Controls->checkBoxMonitorFiberThreads->isChecked()) - m_itemPackage.st_fiberThreadMonitorWorker->setThreadStatus(FBX_STATUS_RUNNING); - - /* MEASUREMENTS AND FANCY GUI EFFECTS + 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->infoTimerColorCoding->setText(QString::number(0)); - m_itemPackage.st_FancyGUITimer1->start(); - - //do processing - //TODO check which colorcoding option is checked! - m_itemPackage.st_FBX->DoColorCodingOrientationbased(); - - - /* MEASUREMENTS AND FANCY GUI EFFECTS CLEANUP */ - clock.Stop(); - m_itemPackage.st_FancyGUITimer1->stop(); - m_itemPackage.st_Controls->infoTimerColorCoding->setText( QString::number(clock.GetTotal()) ); - delete m_itemPackage.st_FancyGUITimer1; // fancy timer is not needed anymore - m_hostingThread->quit(); + itk::TimeProbe clock; + clock.Start(); + + //set GUI representation of timer to 0, is essential for correct timer incrementation + m_itemPackage.st_Controls->infoTimerColorCoding->setText(QString::number(0)); + m_itemPackage.st_FancyGUITimer1->start(); + + //do processing + //TODO check which colorcoding option is checked! + m_itemPackage.st_FBX->DoColorCodingOrientationbased(); + + + /* MEASUREMENTS AND FANCY GUI EFFECTS CLEANUP */ + clock.Stop(); + m_itemPackage.st_FancyGUITimer1->stop(); + m_itemPackage.st_Controls->infoTimerColorCoding->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) + : 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 */ - //MAKE SURE by yourself THAT NOTHING ELSE THAN A NUMBER IS SET IN THAT LABEL - 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) ); + if(m_itemPackage.st_Controls->checkBoxMonitorFiberThreads->isChecked()) + m_itemPackage.st_fiberThreadMonitorWorker->setThreadStatus(FBX_STATUS_RUNNING); + + /* MEASUREMENTS AND FANCY GUI EFFECTS */ + //MAKE SURE by yourself THAT NOTHING ELSE THAN A NUMBER IS SET IN THAT LABEL + 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; } - - 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 */ - vtkSmartPointer PDRandom = vtkPolyData::New(); //could also be a standard pointer instead of smartpointer cuz ther is no need to delete because data is managed 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(); - + + // 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 */ + vtkSmartPointer PDRandom = vtkPolyData::New(); //could also be a standard pointer instead of smartpointer cuz ther is no need to delete because data is managed 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 + : 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; - - - - + + + //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(); + //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(); + m_itemPackage.st_FBX_Monitor->setStatus(status); + m_itemPackage.st_ThreadMonitorDataNode->Modified(); + m_itemPackage.st_MultiWidget->RequestUpdate(); } /* Methods to set status of running threads - * Following three methods are usually called - - before a thread starts and + * Following three methods are usually called + - before a thread starts and - a thread is finished or terminated */ void QmitkFiberThreadMonitorWorker::threadForFiberProcessingStarted() { - if(!m_thtimer_threadStarted->isActive()) { - m_thtimer_threadStarted->start(); - } else { - //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); - - } - - + if(!m_thtimer_threadStarted->isActive()) { + m_thtimer_threadStarted->start(); + } else { + //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); - - } - + 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); - - } - + 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); + + } + } /* Helper methods for fancy fading efx for thread monitor */ 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 + + 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(); + } - - 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 + 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(); + } - - 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 + 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(); + } - - 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 ) + + 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) { - m_itemPackage.st_FBX_Monitor->setHeadingOpacity(10); - m_itemPackage.st_ThreadMonitorDataNode->Modified(); - m_itemPackage.st_MultiWidget->RequestUpdate(); + 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_thtimer_initMonitor->stop(); - - //position them to obt y=25 - m_thtimer_initMonitorSetFinalPosition->start(); - } - - m_itemPackage.st_ThreadMonitorDataNode->Modified(); - m_itemPackage.st_MultiWidget->RequestUpdate(); - - + + 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(); - + //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(); - + //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 ) + : QmitkFunctionality() + , m_Controls( 0 ) + , m_MultiWidget( NULL ) + , m_FiberIDGenerator( NULL) + , m_GeneratorFibersRandom( NULL ) + , m_fiberMonitorIsOn( false ) { - m_hostThread = new QThread; - m_threadInProgress = 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; - + //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->ddAvailableColorcodings->setEnabled(false); - - 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->ddAvailableColorcodings, SIGNAL(currentIndexChanged(int)), this, SLOT(SetCurrentColorCoding(int) )); - - 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(); - - + // 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->ddAvailableColorcodings->setEnabled(false); + + 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->ddAvailableColorcodings, SIGNAL(currentIndexChanged(int)), this, SLOT(SetCurrentColorCoding(int) )); + + 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 + * 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); - - } - + //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(); - - } - - + + // 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( vtkSmartPointer threadOutput) { - - MITK_INFO << "lines: " << threadOutput->GetNumberOfLines() << "pnts: " << threadOutput->GetNumberOfPoints(); - //qthread mutex lock - mitk::FiberBundleX::Pointer FB = mitk::FiberBundleX::New(threadOutput); - 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 + + MITK_INFO << "lines: " << threadOutput->GetNumberOfLines() << "pnts: " << threadOutput->GetNumberOfPoints(); + //qthread mutex lock + mitk::FiberBundleX::Pointer FB = mitk::FiberBundleX::New(threadOutput); + 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 ====== + + /* ===== 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; //needed to access method "PutFibersToDataStorage()" - ItemPackageForRandomGenerator.st_pntr_to_Method_PutFibersToDataStorage = &QmitkFiberBundleDeveloperView::PutFibersToDataStorage; //actual functor calling method 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); - + 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; //needed to access method "PutFibersToDataStorage()" + ItemPackageForRandomGenerator.st_pntr_to_Method_PutFibersToDataStorage = &QmitkFiberBundleDeveloperView::PutFibersToDataStorage; //actual functor calling method 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::UpdateColorFibersTimer() { - // Make sure that thread has set according info-label to number! here we do not check if value is numeric! - QString crntValue = m_Controls->infoTimerColorCoding->text(); - int tmpVal = crntValue.toInt(); - m_Controls->infoTimerColorCoding->setText(QString::number(++tmpVal)); - m_Controls->infoTimerColorCoding->update(); + // Make sure that thread has set according info-label to number! here we do not check if value is numeric! + QString crntValue = m_Controls->infoTimerColorCoding->text(); + int tmpVal = crntValue.toInt(); + m_Controls->infoTimerColorCoding->setText(QString::number(++tmpVal)); + m_Controls->infoTimerColorCoding->update(); } void QmitkFiberBundleDeveloperView::UpdateGenerateRandomFibersTimer() { - // Make sure that thread has set according info-label to number! here we do not check if value is numeric! - QString crntValue = m_Controls->infoTimerGenerateFiberBundle->text(); - int tmpVal = crntValue.toInt(); - m_Controls->infoTimerGenerateFiberBundle->setText(QString::number(++tmpVal)); - m_Controls->infoTimerGenerateFiberBundle->update(); - + // Make sure that thread has set according info-label to number! here we do not check if value is numeric! + 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); - } + 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(); - - + 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); + 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); } - - linesCell->InsertNextCell(newFiber); - } - - vtkSmartPointer PDX = vtkSmartPointer::New(); - PDX->SetPoints(points); - PDX->SetLines(linesCell); - return PDX; + + vtkSmartPointer PDX = vtkSmartPointer::New(); + PDX->SetPoints(points); + PDX->SetLines(linesCell); + return PDX; } vtkSmartPointer QmitkFiberBundleDeveloperView::GenerateVtkFibersDirectionY() { - vtkSmartPointer PDY = vtkSmartPointer::New(); - //todo - - - - return PDY; + vtkSmartPointer PDY = vtkSmartPointer::New(); + //todo + + + + return PDY; } vtkSmartPointer QmitkFiberBundleDeveloperView::GenerateVtkFibersDirectionZ() { - vtkSmartPointer PDZ = vtkSmartPointer::New(); - //todo - - - - return PDZ; + vtkSmartPointer PDZ = vtkSmartPointer::New(); + //todo + + + + return PDZ; } void QmitkFiberBundleDeveloperView::DoColorFibers() { - // - MITK_INFO << "call fibercoloring in fiberBundleX"; - QTimer *localTimer = new QTimer; // timer must be initialized here, otherwise timer is not fancy enough - localTimer->setInterval( 10 ); - connect( localTimer, SIGNAL(timeout()), this, SLOT( UpdateColorFibersTimer() ) ); - - // pack items which are needed by thread processing - struct Package4WorkingThread ItemPackageForFiberColoring; - ItemPackageForFiberColoring.st_FBX = m_FiberBundleX; - ItemPackageForFiberColoring.st_FancyGUITimer1 = localTimer; - ItemPackageForFiberColoring.st_Controls = m_Controls; //needed to catch up some selections and set options in GUI - - if (m_fiberMonitorIsOn) - ItemPackageForFiberColoring.st_fiberThreadMonitorWorker = m_fiberThreadMonitorWorker; - - if (m_threadInProgress) - return; //maybe popup window saying, working thread still in progress...pls wait - - m_FiberColoringSlave = new QmitkFiberColoringWorker(m_hostThread, ItemPackageForFiberColoring); - m_FiberColoringSlave->moveToThread(m_hostThread); - connect(m_hostThread, SIGNAL(started()), this, SLOT( BeforeThread_FiberColorCoding()) ); - connect(m_hostThread, SIGNAL(started()), m_FiberColoringSlave, SLOT(run()) ); - connect(m_hostThread, SIGNAL(finished()), this, SLOT(AfterThread_FiberColorCoding())); - connect(m_hostThread, SIGNAL(terminated()), this, SLOT(AfterThread_FiberColorCoding())); - m_hostThread->start(QThread::LowestPriority); - + // + MITK_INFO << "call fibercoloring in fiberBundleX"; + QTimer *localTimer = new QTimer; // timer must be initialized here, otherwise timer is not fancy enough + localTimer->setInterval( 10 ); + connect( localTimer, SIGNAL(timeout()), this, SLOT( UpdateColorFibersTimer() ) ); + + // pack items which are needed by thread processing + struct Package4WorkingThread ItemPackageForFiberColoring; + ItemPackageForFiberColoring.st_FBX = m_FiberBundleX; + ItemPackageForFiberColoring.st_FancyGUITimer1 = localTimer; + ItemPackageForFiberColoring.st_Controls = m_Controls; //needed to catch up some selections and set options in GUI + + if (m_fiberMonitorIsOn) + ItemPackageForFiberColoring.st_fiberThreadMonitorWorker = m_fiberThreadMonitorWorker; + + if (m_threadInProgress) + return; //maybe popup window saying, working thread still in progress...pls wait + + m_FiberColoringSlave = new QmitkFiberColoringWorker(m_hostThread, ItemPackageForFiberColoring); + m_FiberColoringSlave->moveToThread(m_hostThread); + connect(m_hostThread, SIGNAL(started()), this, SLOT( BeforeThread_FiberColorCoding()) ); + connect(m_hostThread, SIGNAL(started()), m_FiberColoringSlave, SLOT(run()) ); + connect(m_hostThread, SIGNAL(finished()), this, SLOT(AfterThread_FiberColorCoding())); + connect(m_hostThread, SIGNAL(terminated()), this, SLOT(AfterThread_FiberColorCoding())); + m_hostThread->start(QThread::LowestPriority); + } void QmitkFiberBundleDeveloperView::BeforeThread_FiberColorCoding() { - m_threadInProgress = true; - if (m_fiberMonitorIsOn){ - m_fiberThreadMonitorWorker->threadForFiberProcessingStarted(); - } + m_threadInProgress = true; + if (m_fiberMonitorIsOn){ + m_fiberThreadMonitorWorker->threadForFiberProcessingStarted(); + } } void QmitkFiberBundleDeveloperView::AfterThread_FiberColorCoding() { - m_threadInProgress = false; - if (m_fiberMonitorIsOn){ - m_fiberThreadMonitorWorker->threadForFiberProcessingFinished(); - m_fiberThreadMonitorWorker->setThreadStatus(FBX_STATUS_IDLE); - } - disconnect(m_hostThread, 0, 0, 0); - m_hostThread->disconnect(); - //update renderer - m_MultiWidget->RequestUpdate(); - - - //update QComboBox(dropDown menu) in view of available ColorCodings - DoGatherColorCodings(); + m_threadInProgress = false; + if (m_fiberMonitorIsOn){ + m_fiberThreadMonitorWorker->threadForFiberProcessingFinished(); + m_fiberThreadMonitorWorker->setThreadStatus(FBX_STATUS_IDLE); + } + disconnect(m_hostThread, 0, 0, 0); + m_hostThread->disconnect(); + //update renderer + m_MultiWidget->RequestUpdate(); + + + //update QComboBox(dropDown menu) in view of available ColorCodings + DoGatherColorCodings(); } void QmitkFiberBundleDeveloperView::DoGatherColorCodings() { QStringList fbxColorCodings = m_FiberBundleX->GetAvailableColorCodings(); //update dropDown Menu //remove all items from menu int ddItems = m_Controls->ddAvailableColorcodings->count(); for(int i=ddItems-1; i>=0; i--) { //note, after each item remove, index in QComboBox is updated, therefore we start from the back which causes less update calculation m_Controls->ddAvailableColorcodings->removeItem(i); } //fill new data into menu m_Controls->ddAvailableColorcodings->addItem("---"); m_Controls->ddAvailableColorcodings->addItems(fbxColorCodings); //highlight current colorcoding QString cc = m_FiberBundleX->GetCurrentColorCoding(); MITK_INFO << "current idx: " << m_Controls->ddAvailableColorcodings->findText(cc); m_Controls->ddAvailableColorcodings->setCurrentIndex( m_Controls->ddAvailableColorcodings->findText(cc) ); } void QmitkFiberBundleDeveloperView::SetCurrentColorCoding(int idx) { QString selectedColorCoding = m_Controls->ddAvailableColorcodings->itemText(idx); m_FiberBundleX->SetColorCoding(selectedColorCoding.toStdString().c_str() ); //QString to char // update rendering m_MultiWidget->RequestUpdate(); } /* === OutSourcedMethod: THIS METHOD GENERATES ESSENTIAL GEOMETRY PARAMETERS FOR THE MITK FRAMEWORK === - * WITHOUT, the rendering mechanism will ignore objects without valid Geometry + * 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 - vtkSmartPointer 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; - - + 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 + vtkSmartPointer 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(); - + //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 ====== + + /* ===== 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())); - + 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); - } + 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(); - + 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); - } + 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->GetFiberPolyData()->GetNumberOfLines() ); - QString numOfPoints; - numOfPoints.setNum( m_FiberBundleX->GetFiberPolyData()->GetNumberOfPoints() ); - - m_Controls->infoAnalyseNumOfFibers->setText( numOfFibers ); - m_Controls->infoAnalyseNumOfPoints->setText( numOfPoints ); + if (!m_Controls->infoAnalyseNumOfFibers->isEnabled()) + m_Controls->infoAnalyseNumOfFibers->setEnabled(true); + + QString numOfFibers; + numOfFibers.setNum( m_FiberBundleX->GetFiberPolyData()->GetNumberOfLines() ); + QString numOfPoints; + numOfPoints.setNum( m_FiberBundleX->GetFiberPolyData()->GetNumberOfPoints() ); + + m_Controls->infoAnalyseNumOfFibers->setText( numOfFibers ); + m_Controls->infoAnalyseNumOfPoints->setText( numOfPoints ); } void QmitkFiberBundleDeveloperView::SelectionChangedToolBox(int idx) { - // show/reset items of selected toolbox page FiberInfo - if (m_Controls->page_FiberInfo->isVisible()) - { - 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 FiberInfo + if (m_Controls->page_FiberInfo->isVisible()) + { + 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); + m_Controls->ddAvailableColorcodings->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->ddAvailableColorcodings->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); + + } } - } - - // 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); - m_Controls->ddAvailableColorcodings->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->ddAvailableColorcodings->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() { - // ==== 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 - + // ==== 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); + //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 { - - GetDataStorage()->Modified(); - m_MultiWidget->RequestUpdate(); //necessary?? + 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?? } - //__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; + m_MultiWidget = &stdMultiWidget; } void QmitkFiberBundleDeveloperView::StdMultiWidgetNotAvailable() { - m_MultiWidget = NULL; + 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 ====== + + /* ==== 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(); //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( "-" ); - m_Controls->infoTimerColorCoding->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 = NULL; //reset pointer, so that member does not point to depricated locations + ResetFiberInfoWidget(); + FBXDependendGUIElementsConfigurator(); //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( "-" ); + m_Controls->infoTimerColorCoding->setText( "-" ); + } + //==================================================== + + + if (nodes.empty()) + return; + + + for( std::vector::iterator it = nodes.begin(); it != nodes.end(); ++it ) { - 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(); - + mitk::DataNode::Pointer node = *it; + + /* CHECKPOINT: FIBERBUNDLE*/ + if( node.IsNotNull() && dynamic_cast(node->GetData()) ) + { + m_FiberBundleX = dynamic_cast(node->GetData()); + if (m_FiberBundleX.IsNull()) + 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(); + + } + /* CHECKPOINT: PLANARFIGURE */ + else if ( node.IsNotNull() && dynamic_cast(node->GetData()) ) + { + m_PlanarFigure = dynamic_cast(node->GetData()); + MITK_INFO << "PF selected"; + + if (m_PlanarFigure.IsNull()) + MITK_INFO << "========ATTENTION=========\n unable to load selected Planarfigure to FiberBundleDeveloper-plugin \n"; + + } + } - - - - - } } void QmitkFiberBundleDeveloperView::Activated() { - - MITK_INFO << "FB DevelopersV 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 833ef2eacb..d1ac4ee061 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,318 +1,318 @@ /*========================================================================= 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) (vtkSmartPointer); //==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 ===================== // ==================================================================== //## Documentation //## This class does the actual work for colorcoding fibers. class QmitkFiberColoringWorker : public QObject { Q_OBJECT public: QmitkFiberColoringWorker( 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(); void DoGatherColorCodings(); void SetCurrentColorCoding(int); //SLOTS FOR THREADS void BeforeThread_IdGenerate(); void AfterThread_IdGenerate(); void BeforeThread_GenerateFibersRandom(); void AfterThread_GenerateFibersRandom(); void BeforeThread_FiberColorCoding(); void AfterThread_FiberColorCoding(); //SLOTS FOR TIMERS void UpdateFiberIDTimer(); void UpdateGenerateRandomFibersTimer(); void UpdateColorFibersTimer(); 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( vtkSmartPointer ); /* METHODS FOR FIBER PROCESSING OR PREPROCESSING */ /* HELPERMETHODS */ mitk::Geometry3D::Pointer GenerateStandardGeometryForMITK(); void ResetFiberInfoWidget(); void FeedFiberInfoWidget(); void FBXDependendGUIElementsConfigurator(); void SetGeneratedFBX(); - //contains the selected FiberBundle - //mitk::FiberBundleX* m_FiberBundleX; + //contains the selected FiberBundle, PlanarFigure mitk::WeakPointer m_FiberBundleX; + mitk::PlanarFigure::Pointer m_PlanarFigure; // 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; QmitkFiberColoringWorker* m_FiberColoringSlave; 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 f35620a1b3..fab6daf3c7 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,952 +1,1027 @@ QmitkFiberBundleDeveloperViewControls 0 0 539 966 Form 12 50 false - 1 + 0 0 0 - 355 + 500 449 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 + + + + Qt::Horizontal + + + + 40 + 20 + + + + - 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 500 403 Fiber Processor - 0 + 2 Colors Generate Fiber Coloring QFrame::StyledPanel QFrame::Raised Orientation based true FA based Colorcode Fibers QFrame::StyledPanel QFrame::Raised QFormLayout::FieldsStayAtSizeHint 10 Timer: 10 - Qt::Horizontal 40 20 Qt::Vertical 20 40 Fiber Color Information Qt::Horizontal 40 20 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 + + + + Step 3 - - - QFormLayout::FieldsStayAtSizeHint - + - - - - 10 - + + + Extract Fibers by ROI + + + + - Timer: + Extract Fibers - - - - - 10 - + + + + QFrame::StyledPanel - - - + + QFrame::Raised + + + + + + 10 + + + + Timer: + + + + + + + + 10 + + + + - + + + + - - - Execute Step1 + + + Step 1 + + + + + Generate Fibers IDs in FBX + + + + + + + Generate Fiber Ids + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + QFormLayout::FieldsStayAtSizeHint + + + + + + 10 + + + + Timer: + + + + + + + + 10 + + + + - + + + + + + + + + + + + + Step 2 + + + + + + Define ROI + + + + 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/FiberBundleX/mitkFiberBundleX.cpp b/Modules/DiffusionImaging/IODataStructures/FiberBundleX/mitkFiberBundleX.cpp index 837669f448..3e10f29150 100644 --- a/Modules/DiffusionImaging/IODataStructures/FiberBundleX/mitkFiberBundleX.cpp +++ b/Modules/DiffusionImaging/IODataStructures/FiberBundleX/mitkFiberBundleX.cpp @@ -1,487 +1,700 @@ /*========================================================================= 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 "mitkFiberBundleX.h" +#include +//#include +#include +#include + /* musthave */ //#include // without geometry, fibers are not rendered + + + #include #include #include #include #include +#include #include +#include +#include // baptize array names const char* mitk::FiberBundleX::COLORCODING_ORIENTATION_BASED = "Color_Orient"; const char* mitk::FiberBundleX::COLORCODING_FA_BASED = "Color_FA"; const char* mitk::FiberBundleX::FIBER_ID_ARRAY = "Fiber_IDs"; mitk::FiberBundleX::FiberBundleX(vtkSmartPointer fiberPolyData ) : m_currentColorCoding(NULL) , m_isModified(false) { //generate geometry of passed polydata if (fiberPolyData == NULL) this->m_FiberPolyData = vtkSmartPointer::New(); else this->m_FiberPolyData = fiberPolyData; this->UpdateFiberGeometry(); } mitk::FiberBundleX::~FiberBundleX() { } /* * set computed fibers from tractography algorithms */ void mitk::FiberBundleX::SetFiberPolyData(vtkSmartPointer fiberPD) { if (fiberPD == NULL) this->m_FiberPolyData = vtkSmartPointer::New(); else this->m_FiberPolyData = fiberPD; m_isModified = true; } /* * return fiberbundle as vtkPolyData * Depending on processing of input fibers, this method returns * the latest processed fibers. */ vtkSmartPointer mitk::FiberBundleX::GetFiberPolyData() { return m_FiberPolyData; } /*=================================== *++++ PROCESSING WITH FIBERS +++++++ ====================================*/ void mitk::FiberBundleX::DoColorCodingOrientationbased() { //===== FOR WRITING A TEST ======================== // colorT size == tupelComponents * tupelElements // compare color results // to cover this code 100% also polydata needed, where colorarray already exists // + one fiber with exactly 1 point // + one fiber with 0 points //================================================= /* make sure that processing colorcoding is only called when necessary */ if ( m_FiberPolyData->GetPointData()->HasArray(COLORCODING_ORIENTATION_BASED) && m_FiberPolyData->GetNumberOfPoints() == m_FiberPolyData->GetPointData()->GetArray(COLORCODING_ORIENTATION_BASED)->GetNumberOfTuples() ) { // fiberstructure is already colorcoded MITK_INFO << " NO NEED TO REGENERATE COLORCODING! " ; return; } /* Finally, execute color calculation */ vtkPoints* extrPoints = m_FiberPolyData->GetPoints(); int numOfPoints = extrPoints->GetNumberOfPoints(); //colors and alpha value for each single point, RGBA = 4 components unsigned char rgba[4] = {0,0,0,0}; int componentSize = sizeof(rgba); vtkUnsignedCharArray * colorsT = vtkUnsignedCharArray::New(); colorsT->Allocate(numOfPoints * componentSize); colorsT->SetNumberOfComponents(componentSize); colorsT->SetName(COLORCODING_ORIENTATION_BASED); /* checkpoint: does polydata contain any fibers */ int numOfFibers = m_FiberPolyData->GetNumberOfLines(); if (numOfFibers < 1) { MITK_INFO << "\n ========= Number of Fibers is 0 and below ========= \n"; return; } /* extract single fibers of fiberBundle */ vtkCellArray* fiberList = m_FiberPolyData->GetLines(); fiberList->InitTraversal(); for (int fi=0; fiGetNextCell(pointsPerFiber, idList); - // MITK_INFO << "Fib#: " << fi << " of " << numOfFibers << " pnts in fiber: " << pointsPerFiber ; + // MITK_INFO << "Fib#: " << fi << " of " << numOfFibers << " pnts in fiber: " << pointsPerFiber ; /* single fiber checkpoints: is number of points valid */ if (pointsPerFiber > 1) { /* operate on points of single fiber */ for (int i=0; i 0) { /* The color value of the current point is influenced by the previous point and next point. */ vnl_vector_fixed< double, 3 > currentPntvtk(extrPoints->GetPoint(idList[i])[0], extrPoints->GetPoint(idList[i])[1],extrPoints->GetPoint(idList[i])[2]); vnl_vector_fixed< double, 3 > nextPntvtk(extrPoints->GetPoint(idList[i+1])[0], extrPoints->GetPoint(idList[i+1])[1], extrPoints->GetPoint(idList[i+1])[2]); vnl_vector_fixed< double, 3 > prevPntvtk(extrPoints->GetPoint(idList[i-1])[0], extrPoints->GetPoint(idList[i-1])[1], extrPoints->GetPoint(idList[i-1])[2]); vnl_vector_fixed< double, 3 > diff1; diff1 = currentPntvtk - nextPntvtk; vnl_vector_fixed< double, 3 > diff2; diff2 = currentPntvtk - prevPntvtk; vnl_vector_fixed< double, 3 > diff; diff = (diff1 - diff2) / 2.0; 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) { /* First point has no previous point, therefore only diff1 is taken */ vnl_vector_fixed< double, 3 > currentPntvtk(extrPoints->GetPoint(idList[i])[0], extrPoints->GetPoint(idList[i])[1],extrPoints->GetPoint(idList[i])[2]); vnl_vector_fixed< double, 3 > nextPntvtk(extrPoints->GetPoint(idList[i+1])[0], extrPoints->GetPoint(idList[i+1])[1], extrPoints->GetPoint(idList[i+1])[2]); vnl_vector_fixed< double, 3 > diff1; diff1 = currentPntvtk - nextPntvtk; 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); } else if (i==pointsPerFiber-1) { /* Last point has no next point, therefore only diff2 is taken */ vnl_vector_fixed< double, 3 > currentPntvtk(extrPoints->GetPoint(idList[i])[0], extrPoints->GetPoint(idList[i])[1],extrPoints->GetPoint(idList[i])[2]); vnl_vector_fixed< double, 3 > prevPntvtk(extrPoints->GetPoint(idList[i-1])[0], extrPoints->GetPoint(idList[i-1])[1], extrPoints->GetPoint(idList[i-1])[2]); vnl_vector_fixed< double, 3 > diff2; diff2 = currentPntvtk - prevPntvtk; 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); } colorsT->InsertTupleValue(idList[i], rgba); } //end for loop } else if (pointsPerFiber == 1) { /* a single point does not define a fiber (use vertex mechanisms instead */ continue; // colorsT->InsertTupleValue(0, rgba); } else { MITK_INFO << "Fiber with 0 points detected... please check your tractography algorithm!" ; continue; } }//end for loop m_FiberPolyData->GetPointData()->AddArray(colorsT); /*========================= - this is more relevant for renderer than for fiberbundleX datastructure - think about sourcing this to a explicit method which coordinates colorcoding */ this->SetColorCoding(COLORCODING_ORIENTATION_BASED); m_isModified = true; -// =========================== + // =========================== //mini test, shall be ported to MITK TESTINGS! if (colorsT->GetSize() != numOfPoints*componentSize) { MITK_INFO << "ALLOCATION ERROR IN INITIATING COLOR ARRAY"; } } void mitk::FiberBundleX::DoGenerateFiberIds() { if (m_FiberPolyData == NULL) return; // for (int i=0; i<10000000; ++i) // { // if(i%500 == 0) // MITK_INFO << i; // } // MITK_INFO << "Generating Fiber Ids"; vtkSmartPointer idFiberFilter = vtkSmartPointer::New(); idFiberFilter->SetInput(m_FiberPolyData); idFiberFilter->CellIdsOn(); // idFiberFilter->PointIdsOn(); // point id's are not needed idFiberFilter->SetIdsArrayName(FIBER_ID_ARRAY); idFiberFilter->FieldDataOn(); idFiberFilter->Update(); m_FiberIdDataSet = idFiberFilter->GetOutput(); MITK_INFO << "Generating Fiber Ids...[done] | " << m_FiberIdDataSet->GetNumberOfCells(); } + +//temporarely include only +#include +//========================== +std::vector mitk::FiberBundleX::DoExtractFiberIds(mitk::PlanarFigure::Pointer pf) +{ + + /* Handle type of planarfigure */ + // if incoming pf is a pfc + mitk::PlanarFigureComposite::Pointer pfcomp= dynamic_cast(pf.GetPointer()); + if (!pfcomp.IsNull()) { + // process requested boolean operation of PFC + } else { + + mitk::PlanarCircle::Pointer circleName = mitk::PlanarCircle::New(); + mitk::PlanarPolygon::Pointer polyName = mitk::PlanarPolygon::New(); + + if (pf->GetNameOfClass() == circleName->GetNameOfClass() ) + { + + mitk::Geometry2D::ConstPointer pfgeometry = pf->GetGeometry2D(); + const mitk::PlaneGeometry* planeGeometry = dynamic_cast (pfgeometry.GetPointer()); + Vector3D planeNormal = planeGeometry->GetNormal(); + planeNormal.Normalize(); + Point3D planeOrigin = planeGeometry->GetOrigin(); + + MITK_INFO << "planeOrigin: " << planeOrigin[0] << " | " << planeOrigin[1] << " | " << planeOrigin[2] << endl; + MITK_INFO << "planeNormal: " << planeNormal[0] << " | " << planeNormal[1] << " | " << planeNormal[2] << endl; + } + + + } + + + + /* init necessary vectors hosting pointIds and FiberIds */ + // contains all pointIds which are crossing the cutting plane + std::vector PointsOnPlane; + + // based on PointsOnPlane, all ROI relevant point IDs are stored here + std::vector PointsInROI; + + // vector which is returned, contains all extracted FiberIds + std::vector FibersInROI; + + + /* Define cutting plane by ROI (PlanarFigure) */ + vtkSmartPointer plane = vtkSmartPointer::New(); + plane->SetOrigin(10.0,5.0,0.0); + plane->SetNormal(0.0,1.0,0.0); + + //same plane but opposite normal direction. so point cloud will be reduced -> better performance + vtkSmartPointer planeR = vtkSmartPointer::New(); + planeR->SetOrigin(10.0,5.0,0.0); + planeR->SetNormal(0.0,-1.0,0.0); + + + /* get all points/fibers cutting the plane */ + vtkSmartPointer clipper = vtkSmartPointer::New(); + clipper->SetInput(m_FiberIdDataSet); + clipper->SetClipFunction(plane); + clipper->GenerateClipScalarsOn(); + clipper->GenerateClippedOutputOn(); + vtkSmartPointer clipperout1 = clipper->GetClippedOutput(); + + /* for some reason clipperoutput is not initialized for futher processing + * so far only writing out clipped polydata provides requested + */ + vtkSmartPointer writerC = vtkSmartPointer::New(); + writerC->SetInput(clipperout1); + writerC->SetFileName("/vtkOutput/Cout1_FbId_clipLineId0+1+2-tests.vtk"); + writerC->SetFileTypeToASCII(); + writerC->Write(); + + + vtkSmartPointer Rclipper = vtkSmartPointer::New(); + Rclipper->SetInput(clipperout1); + Rclipper->SetClipFunction(planeR); + Rclipper->GenerateClipScalarsOn(); + Rclipper->GenerateClippedOutputOn(); + vtkSmartPointer clipperout = Rclipper->GetClippedOutput(); + + + vtkSmartPointer writerC1 = vtkSmartPointer::New(); + writerC1->SetInput(clipperout); + writerC1->SetFileName("/vtkOutput/FbId_clipLineId0+1+2-tests.vtk"); + writerC1->SetFileTypeToASCII(); + writerC1->Write(); + + + /*======STEP 1====== + * extract all points, which are crossing the plane */ + // Scalar values describe the distance between each remaining point to the given plane. Values sorted by point index + vtkSmartPointer distanceList = clipperout->GetPointData()->GetScalars(); + vtkIdType sizeOfList = distanceList->GetNumberOfTuples(); + PointsOnPlane.reserve(sizeOfList); /* use reserve for high-performant push_back, no hidden copy procedures are processed then! + * size of list can be optimized by reducing allocation, but be aware of iterator and vector size*/ + for (int i=0; iGetTuple(i); + std::cout << "distance of point " << i << " : " << distance[0] << std::endl; + + // check if point is on plane. + // 0.01 due to some approximation errors when calculating distance + if (distance[0] >= -0.01 && distance[0] <= 0.01) + { + std::cout << "adding " << i << endl; + PointsOnPlane.push_back(i); //push back in combination with reserve is fastest way to fill vector with various values + } + + } + + // DEBUG print out all interesting points, stop where array starts with value -1. after -1 no more interesting idx are set! + std::vector::iterator rit = PointsOnPlane.begin(); + while (rit != PointsOnPlane.end() ) { + std::cout << "interesting point: " << *rit << " coord: " << clipperout->GetPoint(*rit)[0] << " | " << clipperout->GetPoint(*rit)[1] << " | " << clipperout->GetPoint(*rit)[2] << endl; + rit++; + } + + + + /*=======STEP 2===== + * extract ROI relevant pointIds */ + //ToDo + if( true /*point in ROI*/) + { + PointsInROI = PointsOnPlane; + } + + /*======STEP 3======= + * identify fiberIds for points in ROI */ + //prepare resulting vector + FibersInROI.reserve(PointsInROI.size()); + + vtkCellArray *clipperlines = clipperout->GetLines(); + clipperlines->InitTraversal(); + long numOfLineCells = clipperlines->GetNumberOfCells(); + + // go through resulting "sub"lines which are stored as cells, "i" corresponds to current line id. + for (int i=0, ic=0 ; iGetCell(ic, npts, pts); + + // go through point ids in hosting subline, "j" corresponds to current pointindex in current line i. + for (long j=0; jGetCellData()->HasArray("FB_IDs")) + { + int originalFibId = clipperout->GetCellData()->GetArray("FB_IDs")->GetTuple(i)[0]; + std::cout << "found pointid " << PointsInROI[k] << ": " << clipperout->GetPoint(PointsInROI[k])[0] << " | " << clipperout->GetPoint(PointsInROI[k])[1] << " | " << clipperout->GetPoint(PointsInROI[k])[2] << " in subline: " << i << " which belongs to fiber id: " << originalFibId << "\n" << endl; + + // do something to avoid duplicates + int oldFibInRoiSize = FibersInROI.size(); + if (oldFibInRoiSize != 0) { + + + for (int f=0; f::iterator finIt = FibersInROI.begin(); + while ( finIt != FibersInROI.end() ) { + std::cout << *finIt << endl; + ++finIt; + } + std::cout << "=====================\n"; + +} + void mitk::FiberBundleX::UpdateFiberGeometry() { float min = itk::NumericTraits::min(); float max = itk::NumericTraits::max(); float b[] = {max, min, max, min, max, min}; vtkCellArray* cells = m_FiberPolyData->GetLines(); cells->InitTraversal(); for (int i=0; iGetNumberOfCells(); i++) { vtkCell* cell = m_FiberPolyData->GetCell(i); int p = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); for (int j=0; jGetPoint(j, p); if (p[0]b[1]) b[1]=p[0]; if (p[1]b[3]) b[3]=p[1]; if (p[2]b[5]) b[5]=p[2]; } } // provide some buffer space at borders for(int i=0; i<=4; i+=2){ b[i] -=10; } for(int i=1; i<=5; i+=2){ b[i] +=10; } mitk::Geometry3D::Pointer geometry = mitk::Geometry3D::New(); geometry->SetImageGeometry(true); geometry->SetFloatBounds(b); this->SetGeometry(geometry); } /*============================== *++++ FIBER INFORMATION +++++++ ===============================*/ QStringList mitk::FiberBundleX::GetAvailableColorCodings() { QStringList availableColorCodings; int numColors = m_FiberPolyData->GetPointData()->GetNumberOfArrays(); for(int i=0; iGetPointData()->GetArrayName(i)); } //this controlstructure shall be implemented by the calling method if (availableColorCodings.isEmpty()) MITK_INFO << "no colorcodings available in fiberbundleX"; -// for(int i=0; im_currentColorCoding; } void mitk::FiberBundleX::SetColorCoding(const char* requestedColorCoding) { -// MITK_INFO << "FbX try to set colorCoding: " << requestedColorCoding << " compare with: " << COLORCODING_ORIENTATION_BASED; + // MITK_INFO << "FbX try to set colorCoding: " << requestedColorCoding << " compare with: " << COLORCODING_ORIENTATION_BASED; if(strcmp (COLORCODING_ORIENTATION_BASED,requestedColorCoding) == 0 ) { - this->m_currentColorCoding = (char*) COLORCODING_ORIENTATION_BASED; - this->m_isModified = true; + this->m_currentColorCoding = (char*) COLORCODING_ORIENTATION_BASED; + this->m_isModified = true; } else if(strcmp (COLORCODING_FA_BASED,requestedColorCoding) == 0 ) { this->m_currentColorCoding = (char*) COLORCODING_FA_BASED; this->m_isModified = true; } else { MITK_INFO << "FIBERBUNDLE X: UNKNOWN COLORCODING in FIBERBUNDLEX Datastructure"; this->m_currentColorCoding = "---"; //will cause blank colorcoding of fibers this->m_isModified = true; } } bool mitk::FiberBundleX::isFiberBundleXModified() { return m_isModified; } void mitk::FiberBundleX::setFBXModificationDone() { m_isModified = false; } // Resample fiber to get equidistant points void mitk::FiberBundleX::ResampleFibers(float len) { vtkSmartPointer newPoly = vtkSmartPointer::New(); vtkSmartPointer newCellArray = vtkSmartPointer::New(); vtkSmartPointer newPoints = vtkSmartPointer::New(); vtkSmartPointer vLines = m_FiberPolyData->GetLines(); vLines->InitTraversal(); int numberOfLines = vLines->GetNumberOfCells(); for (int i=0; iGetNextCell ( numPoints, points ); vtkSmartPointer container = vtkSmartPointer::New(); double* point = m_FiberPolyData->GetPoint(points[0]); vtkIdType pointId = newPoints->InsertNextPoint(point); container->GetPointIds()->InsertNextId(pointId); float dtau = 0; int cur_p = 1; itk::Vector dR; float normdR = 0; for (;;) { while (dtau <= len && cur_p < numPoints) { itk::Vector v1; point = m_FiberPolyData->GetPoint(points[cur_p-1]); v1[0] = point[0]; v1[1] = point[1]; v1[2] = point[2]; itk::Vector v2; point = m_FiberPolyData->GetPoint(points[cur_p]); v2[0] = point[0]; v2[1] = point[1]; v2[2] = point[2]; dR = v2 - v1; normdR = std::sqrt(dR.GetSquaredNorm()); dtau += normdR; cur_p++; } if (dtau >= len) { itk::Vector v1; point = m_FiberPolyData->GetPoint(points[cur_p-1]); v1[0] = point[0]; v1[1] = point[1]; v1[2] = point[2]; itk::Vector v2 = v1 - dR*( (dtau-len)/normdR ); pointId = newPoints->InsertNextPoint(v2.GetDataPointer()); container->GetPointIds()->InsertNextId(pointId); } else { point = m_FiberPolyData->GetPoint(points[numPoints-1]); pointId = newPoints->InsertNextPoint(point); container->GetPointIds()->InsertNextId(pointId); break; } dtau = dtau-len; } newCellArray->InsertNextCell(container); } newPoly->SetPoints(newPoints); newPoly->SetLines(newCellArray); m_FiberPolyData = newPoly; UpdateFiberGeometry(); } /* ESSENTIAL IMPLEMENTATION OF SUPERCLASS METHODS */ void mitk::FiberBundleX::UpdateOutputInformation() { } void mitk::FiberBundleX::SetRequestedRegionToLargestPossibleRegion() { } bool mitk::FiberBundleX::RequestedRegionIsOutsideOfTheBufferedRegion() { return false; } bool mitk::FiberBundleX::VerifyRequestedRegion() { return true; } void mitk::FiberBundleX::SetRequestedRegion( itk::DataObject *data ) { } diff --git a/Modules/DiffusionImaging/IODataStructures/FiberBundleX/mitkFiberBundleX.h b/Modules/DiffusionImaging/IODataStructures/FiberBundleX/mitkFiberBundleX.h index 0ee1a6e071..8078771eae 100644 --- a/Modules/DiffusionImaging/IODataStructures/FiberBundleX/mitkFiberBundleX.h +++ b/Modules/DiffusionImaging/IODataStructures/FiberBundleX/mitkFiberBundleX.h @@ -1,129 +1,133 @@ /*========================================================================= 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. =========================================================================*/ /* =============== IMPORTANT TODO =================== * ==== USE vtkSmartPointer<> when necessary ONLY!!!! */ #ifndef _MITK_FiberBundleX_H #define _MITK_FiberBundleX_H //includes for MITK datastructure #include #include "MitkDiffusionImagingExports.h" //includes storing fiberdata #include //may be replaced by class precompile argument #include // may be replaced by class #include // my be replaced by class #include #include +#include + namespace mitk { /** * \brief Base Class for Fiber Bundles; */ class MitkDiffusionImaging_EXPORT FiberBundleX : public BaseData { public: // names of certain arrays (e.g colorcodings, etc.) static const char* COLORCODING_ORIENTATION_BASED; static const char* COLORCODING_FA_BASED; static const char* FIBER_ID_ARRAY; /* friend classes wanna access typedefs ContainerPointType, ContainerTractType, ContainerType */ friend class FiberBundleXWriter; friend class FiberBundleXReader; // ======virtual methods must have====== virtual void UpdateOutputInformation(); virtual void SetRequestedRegionToLargestPossibleRegion(); virtual bool RequestedRegionIsOutsideOfTheBufferedRegion(); virtual bool VerifyRequestedRegion(); virtual void SetRequestedRegion( itk::DataObject *data ); //======================================= mitkClassMacro( FiberBundleX, BaseData ) itkNewMacro( Self ) //custom constructor with passing argument mitkNewMacro1Param(Self, vtkSmartPointer) /*====FIBERBUNDLE I/O METHODS====*/ void SetFiberPolyData(vtkSmartPointer); //set result of tractography algorithm in vtkPolyData format using vtkPolyLines vtkSmartPointer GetFiberPolyData(); void UpdateFiberGeometry(); char* GetCurrentColorCoding(); QStringList GetAvailableColorCodings(); void SetColorCoding(const char*); bool isFiberBundleXModified(); void setFBXModificationDone(); /*===FIBERBUNDLE PROCESSING METHODS====*/ void DoColorCodingOrientationbased(); void DoGenerateFiberIds(); void ResampleFibers(float len); + std::vector DoExtractFiberIds(mitk::PlanarFigure::Pointer ); + /*===FIBERBUNDLE ASSESSMENT METHODS====*/ protected: FiberBundleX( vtkSmartPointer fiberPolyData = NULL ); virtual ~FiberBundleX(); private: // 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) // this variable hosts the smoothed fiber data, this data we generate, therefore a smartpointer structure is recommended // vtkSmartPointer m_FiberPolyData; is depricated // // this variable hosts the original fiber data, no smartpointer needed because who or whatever passes this data to FiberBundleX should use vtkSmartPointer structure vtkSmartPointer m_FiberPolyData; //this is a common pointer because fiberDataStructure gets passed to this class. m_FiberStructureData is destroyed in the destructor then. // this variable contains all additional IDs of Fibers which are needed for efficient fiber manipulation such as extracting etc. vtkSmartPointer m_FiberIdDataSet; char* m_currentColorCoding; //this flag conzerns only visual representation. bool m_isModified; }; } // namespace mitk #endif /* _MITK_FiberBundleX_H */