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 fafb348eb1..3475e9a687 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,1391 +1,1407 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2010-03-31 16:40:27 +0200 (Mi, 31 Mrz 2010) $ Version: $Revision: 21975 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ //=========FOR TESTING========== //random generation, number of points equal requested points // Blueberry application and interaction service #include #include // Qmitk #include "QmitkFiberBundleDeveloperView.h" #include // Qt #include // MITK //===needed when timeSlicedGeometry is null to invoke rendering mechansims ==== #include #include // VTK #include //for randomized FiberStructure #include //for fiberStructure #include //for fiberStructure #include //for geometry //ITK #include //============================================== //======== W O R K E R S ____ S T A R T ======== //============================================== /*=================================================================================== * THIS METHOD IMPLEMENTS THE ACTIONS WHICH SHALL BE EXECUTED by the according THREAD * --generate FiberIDs--*/ QmitkFiberIDWorker::QmitkFiberIDWorker(QThread* hostingThread, Package4WorkingThread itemPackage) : m_itemPackage(itemPackage), m_hostingThread(hostingThread) { } void QmitkFiberIDWorker::run() { if(m_itemPackage.st_Controls->checkBoxMonitorFiberThreads->isChecked()) m_itemPackage.st_fiberThreadMonitorWorker->setThreadStatus(FBX_STATUS_RUNNING); /* MEASUREMENTS AND FANCY GUI EFFECTS * accurate time measurement using ITK timeProbe*/ itk::TimeProbe clock; clock.Start(); //set GUI representation of timer to 0, is essential for correct timer incrementation m_itemPackage.st_Controls->infoTimerGenerateFiberIds->setText(QString::number(0)); m_itemPackage.st_FancyGUITimer1->start(); //do processing m_itemPackage.st_FBX->DoGenerateFiberIds(); /* MEASUREMENTS AND FANCY GUI EFFECTS CLEANUP */ clock.Stop(); m_itemPackage.st_FancyGUITimer1->stop(); m_itemPackage.st_Controls->infoTimerGenerateFiberIds->setText( QString::number(clock.GetTotal()) ); delete m_itemPackage.st_FancyGUITimer1; // fancy timer is not needed anymore m_hostingThread->quit(); } /*=================================================================================== * THIS METHOD IMPLEMENTS THE ACTIONS WHICH SHALL BE EXECUTED by the according THREAD * --do color coding--*/ QmitkFiberColoringWorker::QmitkFiberColoringWorker(QThread* hostingThread, Package4WorkingThread itemPackage) : 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 * 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(); } /*=================================================================================== * THIS METHOD IMPLEMENTS THE ACTIONS WHICH SHALL BE EXECUTED by the according THREAD * --generate random fibers--*/ QmitkFiberGenerateRandomWorker::QmitkFiberGenerateRandomWorker(QThread* hostingThread, Package4WorkingThread itemPackage) : m_itemPackage(itemPackage), m_hostingThread(hostingThread) { } void QmitkFiberGenerateRandomWorker::run() { if(m_itemPackage.st_Controls->checkBoxMonitorFiberThreads->isChecked()) m_itemPackage.st_fiberThreadMonitorWorker->setThreadStatus(FBX_STATUS_RUNNING); /* MEASUREMENTS AND FANCY GUI EFFECTS */ //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) ); } 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 { //set timers m_thtimer_initMonitor = new QTimer; m_thtimer_initMonitor->setInterval(10); m_thtimer_initMonitorSetFinalPosition = new QTimer; m_thtimer_initMonitorSetFinalPosition->setInterval(10); m_thtimer_initMonitorSetMasks = new QTimer; m_thtimer_initMonitorSetFinalPosition->setInterval(10); m_thtimer_threadStarted = new QTimer; m_thtimer_threadStarted->setInterval(50); m_thtimer_threadFinished = new QTimer; m_thtimer_threadFinished->setInterval(50); m_thtimer_threadTerminated = new QTimer; m_thtimer_threadTerminated->setInterval(50); connect (m_thtimer_initMonitor, SIGNAL( timeout()), this, SLOT( fancyMonitorInitialization() ) ); connect ( m_thtimer_initMonitorSetFinalPosition, SIGNAL( timeout() ), this, SLOT( fancyMonitorInitializationFinalPos() ) ); connect ( m_thtimer_initMonitorSetMasks, SIGNAL( timeout() ), this, SLOT( fancyMonitorInitializationMask() ) ); connect (m_thtimer_threadStarted, SIGNAL( timeout()), this, SLOT( fancyTextFading_threadStarted() ) ); connect (m_thtimer_threadFinished, SIGNAL( timeout()), this, SLOT( fancyTextFading_threadFinished() ) ); connect (m_thtimer_threadTerminated, SIGNAL( timeout()), this, SLOT( fancyTextFading_threadTerminated() ) ); //first, the current text shall turn transparent m_decreaseOpacity_threadStarted = true; m_decreaseOpacity_threadFinished = true; m_decreaseOpacity_threadTerminated = true; } void QmitkFiberThreadMonitorWorker::run() { } void QmitkFiberThreadMonitorWorker::initializeMonitor() { //fancy configuration of animation start mitk::Point2D pntOpen; pntOpen[0] = 118; pntOpen[1] = 10; mitk::Point2D headPos; headPos[0] = 19; headPos[1] = 10; mitk::Point2D statusPos; statusPos[0] = 105; statusPos[1] = 23; mitk::Point2D startedPos; startedPos[0] = 68; startedPos[1] = 10; mitk::Point2D finishedPos; finishedPos[0] = 143; finishedPos[1] = 10; mitk::Point2D terminatedPos; terminatedPos[0] = 240; terminatedPos[1] = 10; m_itemPackage.st_FBX_Monitor->setBracketClosePosition(pntOpen); m_itemPackage.st_FBX_Monitor->setBracketOpenPosition(pntOpen); m_itemPackage.st_FBX_Monitor->setHeadingPosition(headPos); m_itemPackage.st_FBX_Monitor->setMaskPosition(headPos); m_itemPackage.st_FBX_Monitor->setStatusPosition(statusPos); m_itemPackage.st_FBX_Monitor->setStartedPosition(startedPos); m_itemPackage.st_FBX_Monitor->setFinishedPosition(finishedPos); m_itemPackage.st_FBX_Monitor->setTerminatedPosition(terminatedPos); m_thtimer_initMonitor->start(); } void QmitkFiberThreadMonitorWorker::setThreadStatus(QString status) { m_itemPackage.st_FBX_Monitor->setStatus(status); m_itemPackage.st_ThreadMonitorDataNode->Modified(); m_itemPackage.st_MultiWidget->RequestUpdate(); } /* Methods to set status of running threads * 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); } } void QmitkFiberThreadMonitorWorker::threadForFiberProcessingFinished() { if(!m_thtimer_threadFinished->isActive()) { m_thtimer_threadFinished->start(); } else { //fast change without fancy stuff int counter = m_itemPackage.st_FBX_Monitor->getFinished(); m_itemPackage.st_FBX_Monitor->setFinished(++counter); } } void QmitkFiberThreadMonitorWorker::threadForFiberProcessingTerminated() { if(!m_thtimer_threadTerminated->isActive()) { m_thtimer_threadTerminated->start(); } else { //fast change without fancy stuff int counter = m_itemPackage.st_FBX_Monitor->getTerminated(); m_itemPackage.st_FBX_Monitor->setTerminated(++counter); } } /* 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 } m_itemPackage.st_ThreadMonitorDataNode->Modified(); m_itemPackage.st_MultiWidget->RequestUpdate(); } } void QmitkFiberThreadMonitorWorker::fancyTextFading_threadFinished() { if (m_decreaseOpacity_threadFinished) { int finishedOpacity = m_itemPackage.st_FBX_Monitor->getFinishedOpacity(); m_itemPackage.st_FBX_Monitor->setFinishedOpacity( --finishedOpacity ); if (finishedOpacity == 0) { int counter = m_itemPackage.st_FBX_Monitor->getFinished(); m_itemPackage.st_FBX_Monitor->setFinished(++counter); m_decreaseOpacity_threadFinished = false; } m_itemPackage.st_ThreadMonitorDataNode->Modified(); m_itemPackage.st_MultiWidget->RequestUpdate(); } else { int finishedOpacity = m_itemPackage.st_FBX_Monitor->getFinishedOpacity(); m_itemPackage.st_FBX_Monitor->setFinishedOpacity( ++finishedOpacity ); if (finishedOpacity >= 10) { m_thtimer_threadFinished->stop(); m_decreaseOpacity_threadFinished = true; //set back to true, cuz next iteration shall decrease opacity as well } m_itemPackage.st_ThreadMonitorDataNode->Modified(); m_itemPackage.st_MultiWidget->RequestUpdate(); } } void QmitkFiberThreadMonitorWorker::fancyTextFading_threadTerminated() { if (m_decreaseOpacity_threadTerminated) { int terminatedOpacity = m_itemPackage.st_FBX_Monitor->getTerminatedOpacity(); m_itemPackage.st_FBX_Monitor->setTerminatedOpacity( --terminatedOpacity ); if (terminatedOpacity == 0) { int counter = m_itemPackage.st_FBX_Monitor->getTerminated(); m_itemPackage.st_FBX_Monitor->setTerminated(++counter); m_decreaseOpacity_threadTerminated = false; } m_itemPackage.st_ThreadMonitorDataNode->Modified(); m_itemPackage.st_MultiWidget->RequestUpdate(); } else { int terminatedOpacity = m_itemPackage.st_FBX_Monitor->getTerminatedOpacity(); m_itemPackage.st_FBX_Monitor->setTerminatedOpacity( ++terminatedOpacity ); if (terminatedOpacity >= 10) { m_thtimer_threadTerminated->stop(); m_decreaseOpacity_threadTerminated = true; //set back to true, cuz next iteration shall decrease opacity as well } m_itemPackage.st_ThreadMonitorDataNode->Modified(); m_itemPackage.st_MultiWidget->RequestUpdate(); } } void QmitkFiberThreadMonitorWorker::fancyMonitorInitialization() { mitk::Point2D pntClose = m_itemPackage.st_FBX_Monitor->getBracketClosePosition(); //possible bottleneck, set pntClose to member mitk::Point2D pntOpen = m_itemPackage.st_FBX_Monitor->getBracketOpenPosition(); //possible bottleneck, set pntClose to member pntClose[0] += m_pixelstepper; pntOpen[0] -= m_pixelstepper; //MITK_INFO << pntClose[0] << " " << pntOpen[0]; m_itemPackage.st_FBX_Monitor->setBracketClosePosition(pntClose); m_itemPackage.st_FBX_Monitor->setBracketOpenPosition(pntOpen); int opacity = m_itemPackage.st_FBX_Monitor->getHeadingOpacity() + 1; if (opacity > 10) opacity = 10; m_itemPackage.st_FBX_Monitor->setHeadingOpacity(opacity); if (pntClose[0] >= m_steppingDistance) { if (m_itemPackage.st_FBX_Monitor->getHeadingOpacity() != 10 ) { m_itemPackage.st_FBX_Monitor->setHeadingOpacity(10); m_itemPackage.st_ThreadMonitorDataNode->Modified(); m_itemPackage.st_MultiWidget->RequestUpdate(); } m_thtimer_initMonitor->stop(); //position them to obt y=25 m_thtimer_initMonitorSetFinalPosition->start(); } m_itemPackage.st_ThreadMonitorDataNode->Modified(); m_itemPackage.st_MultiWidget->RequestUpdate(); } void QmitkFiberThreadMonitorWorker::fancyMonitorInitializationFinalPos() { //get y pos of mitk::Point2D pntClose = m_itemPackage.st_FBX_Monitor->getBracketClosePosition(); mitk::Point2D pntOpen = m_itemPackage.st_FBX_Monitor->getBracketOpenPosition(); mitk::Point2D pntHead = m_itemPackage.st_FBX_Monitor->getHeadingPosition(); pntClose[1] += 5; pntOpen[1] += 5; pntHead[1] += 5; m_itemPackage.st_FBX_Monitor->setBracketClosePosition(pntClose); m_itemPackage.st_FBX_Monitor->setBracketOpenPosition(pntOpen); m_itemPackage.st_FBX_Monitor->setHeadingPosition(pntHead); if (pntClose[1] >= 35) { //35 = y position m_thtimer_initMonitorSetFinalPosition->stop(); //now init mask of labels m_thtimer_initMonitorSetMasks->start(); } m_itemPackage.st_ThreadMonitorDataNode->Modified(); m_itemPackage.st_MultiWidget->RequestUpdate(); } void QmitkFiberThreadMonitorWorker::fancyMonitorInitializationMask() { //increase opacity int opacity = m_itemPackage.st_FBX_Monitor->getMaskOpacity(); opacity++; m_itemPackage.st_FBX_Monitor->setMaskOpacity(opacity); m_itemPackage.st_FBX_Monitor->setStartedOpacity(opacity); m_itemPackage.st_FBX_Monitor->setFinishedOpacity(opacity); m_itemPackage.st_FBX_Monitor->setTerminatedOpacity(opacity); m_itemPackage.st_FBX_Monitor->setStatusOpacity(opacity); if (opacity >=10) { m_thtimer_initMonitorSetMasks->stop(); } m_itemPackage.st_ThreadMonitorDataNode->Modified(); m_itemPackage.st_MultiWidget->RequestUpdate(); } //============================================== //======== W O R K E R S ________ E N D ======== //============================================== // ========= HERE STARTS THE ACTUAL FIBERB2UNDLE DEVELOPER VIEW IMPLEMENTATION ====== const std::string QmitkFiberBundleDeveloperView::VIEW_ID = "org.mitk.views.fiberbundledeveloper"; const std::string id_DataManager = "org.mitk.views.datamanager"; using namespace berry; QmitkFiberBundleDeveloperView::QmitkFiberBundleDeveloperView() : QmitkFunctionality() , m_Controls( 0 ) , m_MultiWidget( NULL ) , m_FiberIDGenerator( NULL) , m_GeneratorFibersRandom( NULL ) , m_fiberMonitorIsOn( false ) { m_hostThread = new QThread; m_threadInProgress = false; } // Destructor QmitkFiberBundleDeveloperView::~QmitkFiberBundleDeveloperView() { //m_FiberBundleX->Delete(); using weakPointer, therefore no delete necessary delete m_hostThread; if (m_FiberIDGenerator != NULL) delete m_FiberIDGenerator; if (m_GeneratorFibersRandom != NULL) delete m_GeneratorFibersRandom; } void QmitkFiberBundleDeveloperView::CreateQtPartControl( QWidget *parent ) { // build up qt view, unless already done in QtDesigner, etc. if ( !m_Controls ) { // create GUI widgets from the Qt Designer's .ui file m_Controls = new Ui::QmitkFiberBundleDeveloperViewControls; m_Controls->setupUi( parent ); /*=========INITIALIZE BUTTON CONFIGURATION ================*/ m_Controls->radioButton_directionX->setEnabled(false); m_Controls->radioButton_directionY->setEnabled(false); m_Controls->radioButton_directionZ->setEnabled(false); m_Controls->buttonGenerateFiberIds->setEnabled(false); m_Controls->buttonGenerateFibers->setEnabled(true); m_Controls->buttonColorFibers->setEnabled(false); m_Controls->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->buttonGetAvailableColorCoding, SIGNAL(clicked()), this, SLOT(DoGatherColorCodings()) ); + 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 */ void QmitkFiberBundleDeveloperView::DoUpdateGenerateFibersWidget() { //get selected radioButton QString fibDirection; //stores the object_name of selected radiobutton QVector::const_iterator i; for (i = m_DirectionRadios.begin(); i != m_DirectionRadios.end(); ++i) { QRadioButton* rdbtn = *i; if (rdbtn->isChecked()) fibDirection = rdbtn->objectName(); } if ( fibDirection == FIB_RADIOBUTTON_DIRECTION_RANDOM ) { // disable radiobuttons if (m_Controls->boxFiberMinLength->isEnabled()) m_Controls->boxFiberMinLength->setEnabled(false); if (m_Controls->labelFiberMinLength->isEnabled()) m_Controls->labelFiberMinLength->setEnabled(false); if (m_Controls->boxFiberMaxLength->isEnabled()) m_Controls->boxFiberMaxLength->setEnabled(false); if (m_Controls->labelFiberMaxLength->isEnabled()) m_Controls->labelFiberMaxLength->setEnabled(false); //enable radiobuttons if (!m_Controls->labelFibersTotal->isEnabled()) m_Controls->labelFibersTotal->setEnabled(true); if (!m_Controls->boxFiberNumbers->isEnabled()) m_Controls->boxFiberNumbers->setEnabled(true); if (!m_Controls->labelDistrRadius->isEnabled()) m_Controls->labelDistrRadius->setEnabled(true); if (!m_Controls->boxDistributionRadius->isEnabled()) m_Controls->boxDistributionRadius->setEnabled(true); } else { // disable radiobuttons if (m_Controls->labelDistrRadius->isEnabled()) m_Controls->labelDistrRadius->setEnabled(false); if (m_Controls->boxDistributionRadius->isEnabled()) m_Controls->boxDistributionRadius->setEnabled(false); //enable radiobuttons if (!m_Controls->labelFibersTotal->isEnabled()) m_Controls->labelFibersTotal->setEnabled(true); if (!m_Controls->boxFiberNumbers->isEnabled()) m_Controls->boxFiberNumbers->setEnabled(true); if (!m_Controls->boxFiberMinLength->isEnabled()) m_Controls->boxFiberMinLength->setEnabled(true); if (!m_Controls->labelFiberMinLength->isEnabled()) m_Controls->labelFiberMinLength->setEnabled(true); if (!m_Controls->boxFiberMaxLength->isEnabled()) m_Controls->boxFiberMaxLength->setEnabled(true); if (!m_Controls->labelFiberMaxLength->isEnabled()) m_Controls->labelFiberMaxLength->setEnabled(true); } } void QmitkFiberBundleDeveloperView::DoGenerateFibers() { // GET SELECTED FIBER DIRECTION QString fibDirection; //stores the object_name of selected radiobutton QVector::const_iterator i; for (i = m_DirectionRadios.begin(); i != m_DirectionRadios.end(); ++i) { QRadioButton* rdbtn = *i; if (rdbtn->isChecked()) fibDirection = rdbtn->objectName(); } // vtkPolyData* output; // FiberPD stores the generated PolyData... going to be generated in thread if ( fibDirection == FIB_RADIOBUTTON_DIRECTION_RANDOM ) { // build polydata with random lines and fibers // output = GenerateVtkFibersRandom(); } else if ( fibDirection == FIB_RADIOBUTTON_DIRECTION_X ) { // build polydata with XDirection fibers //output = GenerateVtkFibersDirectionX(); } else if ( fibDirection == FIB_RADIOBUTTON_DIRECTION_Y ) { // build polydata with YDirection fibers // output = GenerateVtkFibersDirectionY(); } else if ( fibDirection == FIB_RADIOBUTTON_DIRECTION_Z ) { // build polydata with ZDirection fibers // output = GenerateVtkFibersDirectionZ(); } } void QmitkFiberBundleDeveloperView::PutFibersToDataStorage( 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 } /* * Generate polydata of random fibers */ void QmitkFiberBundleDeveloperView::GenerateVtkFibersRandom() { /* ===== TIMER CONFIGURATIONS for visual effect ====== * start and stop is called in Thread */ QTimer *localTimer = new QTimer; // timer must be initialized here, otherwise timer is not fancy enough localTimer->setInterval( 10 ); connect( localTimer, SIGNAL(timeout()), this, SLOT(UpdateGenerateRandomFibersTimer()) ); struct Package4WorkingThread ItemPackageForRandomGenerator; ItemPackageForRandomGenerator.st_FBX = m_FiberBundleX; ItemPackageForRandomGenerator.st_Controls = m_Controls; ItemPackageForRandomGenerator.st_FancyGUITimer1 = localTimer; ItemPackageForRandomGenerator.st_host = this; //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(); } 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(); } void QmitkFiberBundleDeveloperView::BeforeThread_GenerateFibersRandom() { m_threadInProgress = true; if (m_fiberMonitorIsOn){ m_fiberThreadMonitorWorker->threadForFiberProcessingStarted(); //m_fiberThreadMonitorWorker->setThreadStatus(FBX_STATUS_STARTED); } } void QmitkFiberBundleDeveloperView::AfterThread_GenerateFibersRandom() { m_threadInProgress = false; if (m_fiberMonitorIsOn){ m_fiberThreadMonitorWorker->threadForFiberProcessingFinished(); m_fiberThreadMonitorWorker->setThreadStatus(FBX_STATUS_IDLE); } disconnect(m_hostThread, 0, 0, 0); m_hostThread->disconnect(); } vtkSmartPointer QmitkFiberBundleDeveloperView::GenerateVtkFibersDirectionX() { int numOfFibers = m_Controls->boxFiberNumbers->value(); vtkSmartPointer linesCell = vtkSmartPointer::New(); vtkSmartPointer points = vtkSmartPointer::New(); //insert Origin point, this point has index 0 in point array double originX = 0.0; double originY = 0.0; double originZ = 0.0; //after each iteration the origin of the new fiber increases //here you set which direction is affected. double increaseX = 0.0; double increaseY = 1.0; double increaseZ = 0.0; //walk along X axis //length of fibers increases in each iteration for (int i=0; i newFiber = vtkSmartPointer::New(); newFiber->GetPointIds()->SetNumberOfIds(i+2); //create starting point and add it to pointset points->InsertNextPoint(originX + (double)i * increaseX , originY + (double)i * increaseY, originZ + (double)i * increaseZ); //add starting point to fiber newFiber->GetPointIds()->SetId(0,points->GetNumberOfPoints()-1); //insert remaining points for fiber for (int pj=0; pj<=i ; ++pj) { //generate next point on X axis points->InsertNextPoint( originX + (double)pj+1 , originY + (double)i * increaseY, originZ + (double)i * increaseZ ); newFiber->GetPointIds()->SetId(pj+1,points->GetNumberOfPoints()-1); } linesCell->InsertNextCell(newFiber); } vtkSmartPointer PDX = vtkSmartPointer::New(); PDX->SetPoints(points); PDX->SetLines(linesCell); return PDX; } vtkSmartPointer QmitkFiberBundleDeveloperView::GenerateVtkFibersDirectionY() { vtkSmartPointer PDY = vtkSmartPointer::New(); //todo return PDY; } vtkSmartPointer QmitkFiberBundleDeveloperView::GenerateVtkFibersDirectionZ() { vtkSmartPointer PDZ = vtkSmartPointer::New(); //todo return PDZ; } void QmitkFiberBundleDeveloperView::DoColorFibers() { // MITK_INFO << "call fibercoloring in fiberBundleX"; 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(); } } 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(); //necessary?? + 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->addItems(fbxColorCodings); + m_Controls->ddAvailableColorcodings->addItem("---"); + //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 * 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; } void QmitkFiberBundleDeveloperView::UpdateFiberIDTimer() { //MAKE SURE by yourself THAT NOTHING ELSE THAN A NUMBER IS SET IN THAT LABEL QString crntValue = m_Controls->infoTimerGenerateFiberIds->text(); int tmpVal = crntValue.toInt(); m_Controls->infoTimerGenerateFiberIds->setText(QString::number(++tmpVal)); m_Controls->infoTimerGenerateFiberIds->update(); } /* Initialie ID dataset in FiberBundleX */ void QmitkFiberBundleDeveloperView::DoGenerateFiberIDs() { /* ===== TIMER CONFIGURATIONS for visual effect ====== * start and stop is called in Thread */ QTimer *localTimer = new QTimer; // timer must be initialized here, otherwise timer is not fancy enough localTimer->setInterval( 10 ); connect( localTimer, SIGNAL(timeout()), this, SLOT(UpdateFiberIDTimer()) ); // pack items which are needed by thread processing struct Package4WorkingThread FiberIdPackage; FiberIdPackage.st_FBX = m_FiberBundleX; FiberIdPackage.st_FancyGUITimer1 = localTimer; FiberIdPackage.st_Controls = m_Controls; //set element for thread monitoring if (m_fiberMonitorIsOn) FiberIdPackage.st_fiberThreadMonitorWorker = m_fiberThreadMonitorWorker; if (m_threadInProgress) return; //maybe popup window saying, working thread still in progress...pls wait // THREAD CONFIGURATION m_FiberIDGenerator = new QmitkFiberIDWorker(m_hostThread, FiberIdPackage); m_FiberIDGenerator->moveToThread(m_hostThread); connect(m_hostThread, SIGNAL(started()), this, SLOT( BeforeThread_IdGenerate()) ); connect(m_hostThread, SIGNAL(started()), m_FiberIDGenerator, SLOT(run())); connect(m_hostThread, SIGNAL(finished()), this, SLOT(AfterThread_IdGenerate())); connect(m_hostThread, SIGNAL(terminated()), this, SLOT(AfterThread_IdGenerate())); m_hostThread->start(QThread::LowestPriority); // m_Controls->infoTimerGenerateFiberIds->setText(QString::number(clock.GetTotal())); } void QmitkFiberBundleDeveloperView::BeforeThread_IdGenerate() { m_threadInProgress = true; if (m_fiberMonitorIsOn){ m_fiberThreadMonitorWorker->threadForFiberProcessingStarted(); m_fiberThreadMonitorWorker->setThreadStatus(FBX_STATUS_STARTED); } } void QmitkFiberBundleDeveloperView::AfterThread_IdGenerate() { m_threadInProgress = false; if (m_fiberMonitorIsOn){ m_fiberThreadMonitorWorker->threadForFiberProcessingFinished(); m_fiberThreadMonitorWorker->setThreadStatus(FBX_STATUS_IDLE); } disconnect(m_hostThread, 0, 0, 0); m_hostThread->disconnect(); } void QmitkFiberBundleDeveloperView::ResetFiberInfoWidget() { if (m_Controls->infoAnalyseNumOfFibers->isEnabled()) { m_Controls->infoAnalyseNumOfFibers->setText("-"); m_Controls->infoAnalyseNumOfPoints->setText("-"); m_Controls->infoAnalyseNumOfFibers->setEnabled(false); } } void QmitkFiberBundleDeveloperView::FeedFiberInfoWidget() { if (!m_Controls->infoAnalyseNumOfFibers->isEnabled()) m_Controls->infoAnalyseNumOfFibers->setEnabled(true); QString numOfFibers; numOfFibers.setNum( m_FiberBundleX->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 FiberProcessing if (m_Controls->page_FiberProcessing->isVisible()) { if (m_FiberBundleX != NULL) { if (m_Controls->tabColoring->isVisible()){ //show button colorCoding m_Controls->buttonColorFibers->setEnabled(true); MITK_INFO << "Color"; }else if(m_Controls->tabCutting->isVisible()){ // m_Controls->buttonGenerateFiberIds->setEnabled(true); }else if(m_Controls->tabShape->isVisible()){ // m_Controls->buttonSMFibers->setEnabled(true); // m_Controls->buttonVtkDecimatePro->setEnabled(true); // m_Controls->buttonVtkSmoothPD->setEnabled(true); // m_Controls->buttonGenerateTubes->setEnabled(true); } } else { m_Controls->buttonColorFibers->setEnabled(false); m_Controls->buttonGenerateFiberIds->setEnabled(false); m_Controls->buttonSMFibers->setEnabled(false); m_Controls->buttonVtkDecimatePro->setEnabled(false); m_Controls->buttonVtkSmoothPD->setEnabled(false); m_Controls->buttonGenerateTubes->setEnabled(true); } } } void QmitkFiberBundleDeveloperView::FBXDependendGUIElementsConfigurator() { // ==== FIBER PROCESSING ELEMENTS and ALL ELEMENTS WHICH NEED A FBX DATANODE====== // m_Controls->buttonGenerateFiberIds->setEnabled(isVisible); moved to selectionChangedToolBox SelectionChangedToolBox(-1); //set gui elements with respect to active tab, widget, etc. -1 has no effect } void QmitkFiberBundleDeveloperView::DoMonitorFiberThreads(int checkStatus) { //check if in datanode exists already a node of type mitkFiberBundleXThreadMonitor //if not then put node to datastorage //if checkStatus is 1 then start qtimer using fading in starting text in datanode //if checkStatus is 0 then fade out dataNode using qtimer if (checkStatus) { m_fiberMonitorIsOn = true; // Generate Node hosting thread information mitk::FiberBundleXThreadMonitor::Pointer FBXThreadMonitor = mitk::FiberBundleXThreadMonitor::New(); FBXThreadMonitor->SetGeometry(this->GenerateStandardGeometryForMITK()); m_MonitorNode = mitk::DataNode::New(); m_MonitorNode->SetName("FBX_threadMonitor"); m_MonitorNode->SetData(FBXThreadMonitor); m_MonitorNode->SetVisibility(true); m_MonitorNode->SetOpacity(1.0); GetDataStorage()->Add(m_MonitorNode); //following code is needed for rendering text in mitk! without geometry nothing is rendered const mitk::PlaneGeometry * tsgeo = m_MultiWidget->GetTimeNavigationController()->GetCurrentPlaneGeometry(); if (tsgeo == NULL) { /* GetDataStorage()->Modified etc. have no effect, therefore proceed as followed below */ // get all nodes that have not set "includeInBoundingBox" to false mitk::NodePredicateNot::Pointer pred = mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New( "includeInBoundingBox" , mitk::BoolProperty::New(false))); mitk::DataStorage::SetOfObjects::ConstPointer rs = GetDataStorage()->GetSubset(pred); // calculate bounding geometry of these nodes mitk::TimeSlicedGeometry::Pointer bounds = GetDataStorage()->ComputeBoundingGeometry3D(rs); // initialize the views to the bounding geometry mitk::RenderingManager::GetInstance()->InitializeViews(bounds); } else { GetDataStorage()->Modified(); m_MultiWidget->RequestUpdate(); //necessary?? } //__GEOMETRY FOR THREADMONITOR GENERATED /* ====== initialize thread for managing fiberThread information ========= */ m_monitorThread = new QThread; // the package needs datastorage, MonitorDatanode, standardmultiwidget, struct Package4WorkingThread ItemPackageForThreadMonitor; ItemPackageForThreadMonitor.st_DataStorage = GetDataStorage(); ItemPackageForThreadMonitor.st_ThreadMonitorDataNode = m_MonitorNode; ItemPackageForThreadMonitor.st_MultiWidget = m_MultiWidget; ItemPackageForThreadMonitor.st_FBX_Monitor = FBXThreadMonitor; m_fiberThreadMonitorWorker = new QmitkFiberThreadMonitorWorker(m_monitorThread, ItemPackageForThreadMonitor); m_fiberThreadMonitorWorker->moveToThread(m_monitorThread); connect ( m_monitorThread, SIGNAL( started() ), m_fiberThreadMonitorWorker, SLOT( run() ) ); m_monitorThread->start(QThread::LowestPriority); m_fiberThreadMonitorWorker->initializeMonitor();//do some init animation ;-) } else { m_fiberMonitorIsOn = false; m_monitorThread->quit(); //think about outsourcing following lines to quit / terminate slot of thread GetDataStorage()->Remove(m_MonitorNode); GetDataStorage()->Modified(); m_MultiWidget->RequestUpdate(); //necessary?? } } void QmitkFiberBundleDeveloperView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_MultiWidget = &stdMultiWidget; } void QmitkFiberBundleDeveloperView::StdMultiWidgetNotAvailable() { m_MultiWidget = NULL; } /* OnSelectionChanged is registered to SelectionService, therefore no need to implement SelectionService Listener explicitly */ void QmitkFiberBundleDeveloperView::OnSelectionChanged( std::vector nodes ) { /* ==== reset everyhing related to FiberBundleX ====== * - variable m_FiberBundleX * - visualization of analysed fiberbundle */ m_FiberBundleX = NULL; //reset pointer, so that member does not point to depricated locations ResetFiberInfoWidget(); FBXDependendGUIElementsConfigurator(); //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 = 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(); } } } void QmitkFiberBundleDeveloperView::Activated() { MITK_INFO << "FB DevelopersV ACTIVATED()"; } diff --git a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberBundleDeveloperView.h b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberBundleDeveloperView.h index 8e6a05595a..833ef2eacb 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,317 +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; mitk::WeakPointer m_FiberBundleX; // radiobutton groups QVector< QRadioButton* > m_DirectionRadios; QVector< QRadioButton* > m_FARadios; QVector< QRadioButton* > m_GARadios; // Thread based Workers which do some processing of fibers QmitkFiberIDWorker* m_FiberIDGenerator; QmitkFiberGenerateRandomWorker* m_GeneratorFibersRandom; 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/DiffusionImaging/IODataStructures/FiberBundleX/mitkFiberBundleX.cpp b/Modules/DiffusionImaging/IODataStructures/FiberBundleX/mitkFiberBundleX.cpp index ad5b987bb3..ad1bc7267a 100644 --- a/Modules/DiffusionImaging/IODataStructures/FiberBundleX/mitkFiberBundleX.cpp +++ b/Modules/DiffusionImaging/IODataStructures/FiberBundleX/mitkFiberBundleX.cpp @@ -1,408 +1,415 @@ /*========================================================================= 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" /* musthave */ //#include // without geometry, fibers are not rendered #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() { // Memory Management m_FiberPolyData->Delete(); } /* === main input method ==== * 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; } /* === main output method === * 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! " ; -// set current colorcoding to orientationbased if needed - if (m_currentColorCoding != COLORCODING_ORIENTATION_BASED ) { - m_currentColorCoding = (char*) COLORCODING_ORIENTATION_BASED; - m_isModified = true; - } - 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 ; /* 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 */ - m_currentColorCoding = (char*) COLORCODING_ORIENTATION_BASED; + 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(); } 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); availableColorCodings.append(m_FiberPolyData->GetPointData()->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(char* requestedColorCoding) +void mitk::FiberBundleX::SetColorCoding(const char* requestedColorCoding) { - m_currentColorCoding = requestedColorCoding; - m_isModified = true; +// 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; + + } 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 = "---"; +// this->m_isModified = true; + } + } bool mitk::FiberBundleX::isFiberBundleXModified() { return m_isModified; } void mitk::FiberBundleX::setFBXModificationDone() { m_isModified = false; } /* 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 a70efd4ba8..df312ee528 100644 --- a/Modules/DiffusionImaging/IODataStructures/FiberBundleX/mitkFiberBundleX.h +++ b/Modules/DiffusionImaging/IODataStructures/FiberBundleX/mitkFiberBundleX.h @@ -1,128 +1,128 @@ /*========================================================================= 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 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(char*); + void SetColorCoding(const char*); bool isFiberBundleXModified(); void setFBXModificationDone(); /*===FIBERBUNDLE PROCESSING METHODS====*/ void DoColorCodingOrientationbased(); void DoGenerateFiberIds(); /*===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 */ diff --git a/Modules/DiffusionImaging/Rendering/mitkFiberBundleXMapper3D.cpp b/Modules/DiffusionImaging/Rendering/mitkFiberBundleXMapper3D.cpp index cfd6f17e2a..fba72ddc12 100644 --- a/Modules/DiffusionImaging/Rendering/mitkFiberBundleXMapper3D.cpp +++ b/Modules/DiffusionImaging/Rendering/mitkFiberBundleXMapper3D.cpp @@ -1,204 +1,205 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2009-05-12 19:56:03 +0200 (Di, 12 Mai 2009) $ Version: $Revision: 17179 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkFiberBundleXMapper3D.h" #include //#include //#include #include #include #include #include //not essential for mapper #include mitk::FiberBundleXMapper3D::FiberBundleXMapper3D() :m_FiberMapperGLSP(vtkSmartPointer::New()), m_FiberMapperGLWP(vtkOpenGLPolyDataMapper::New()), m_FiberActorSP(vtkSmartPointer::New()), m_FiberActorWP(vtkOpenGLActor::New()), m_FiberAssembly(vtkPropAssembly::New()) { } mitk::FiberBundleXMapper3D::~FiberBundleXMapper3D() { m_FiberAssembly->Delete(); } const mitk::FiberBundleX* mitk::FiberBundleXMapper3D::GetInput() { MITK_INFO << "FiberBundleXxXXMapper3D() GetInput()"; return static_cast ( GetData() ); } /* This method is called once the mapper gets new input, for UI rotation or changes in colorcoding this method is NOT called */ void mitk::FiberBundleXMapper3D::GenerateData() { //MITK_INFO << "GENERATE DATA FOR FBX :)"; //=====timer measurement==== QTime myTimer; myTimer.start(); //========================== // mitk::FiberBundleX::Pointer FBX = dynamic_cast< mitk::FiberBundleX* > (this->GetData()); mitk::FiberBundleX* FBX = dynamic_cast (this->GetData()); if (FBX == NULL) { return; } //todo smartpointer vtkPolyData* FiberData = FBX->GetFiberPolyData(); if (FiberData == NULL) { return; } m_FiberMapperGLSP->SetInput(FiberData); // m_FiberMapperGLWP->SetInput(FiberData); if ( FiberData->GetPointData()->GetNumberOfArrays() > 0 ) { if ( FiberData->GetPointData()->HasArray(FiberBundleX::COLORCODING_ORIENTATION_BASED) ) { m_FiberMapperGLSP->SelectColorArray(FiberBundleX::COLORCODING_ORIENTATION_BASED); // m_FiberMapperGLWP->SelectColorArray(FiberBundleX::COLORCODING_ORIENTATION_BASED); } else { // iterate through polydata array and take the first best -but valid- array //===ToDo=== //check of componentsize as well, if it is not RGB or RGBA (ie. size 3 or 4), then check if it is a scalar // if scalar then create lookuptable for that. } m_FiberMapperGLSP->ScalarVisibilityOn(); // m_FiberMapperGLWP->ScalarVisibilityOn(); m_FiberMapperGLSP->SetScalarModeToUsePointFieldData(); // m_FiberMapperGLWP->SetScalarModeToUsePointFieldData(); } m_FiberActorSP->SetMapper(m_FiberMapperGLSP); // m_FiberActorWP->SetMapper(m_FiberMapperGLWP); m_FiberActorSP->GetProperty()->SetOpacity(1.0); // m_FiberActorWP->GetProperty()->SetOpacity(1.0); - if (FBX->GetCurrentColorCoding() != NULL) + if (FBX->GetCurrentColorCoding() != NULL){ m_FiberMapperGLSP->SelectColorArray(FBX->GetCurrentColorCoding()); - + MITK_INFO << "MapperFBX: " << FBX->GetCurrentColorCoding(); + } m_FiberAssembly->AddPart(m_FiberActorSP); //since this method is called after generating all necessary data for fiber visualization, all modifications are represented so far. FBX->setFBXModificationDone(); //====timer measurement======== MITK_INFO << "Execution Time GenerateData() (nmiliseconds): " << myTimer.elapsed(); //============================= } void mitk::FiberBundleXMapper3D::GenerateDataForRenderer( mitk::BaseRenderer *renderer ) { if ( !this->IsVisible( renderer ) ) { return; } //MITK_INFO << "FiberBundleXxXXMapper3D()DataForRenderer"; //ToDo do update checks mitk::FiberBundleX* FBX = dynamic_cast (this->GetData()); if(FBX->isFiberBundleXModified()) this->GenerateData(); } void mitk::FiberBundleXMapper3D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { // MITK_INFO << "FiberBundleXxXXMapper3D()SetDefaultProperties"; //MITK_INFO << "FiberBundleMapperX3D SetDefault Properties(...)"; // node->AddProperty( "DisplayChannel", mitk::IntProperty::New( true ), renderer, overwrite ); // node->AddProperty( "LineWidth", mitk::IntProperty::New( true ), renderer, overwrite ); // node->AddProperty( "ColorCoding", mitk::IntProperty::New( 0 ), renderer, overwrite); // node->AddProperty( "VertexOpacity_1", mitk::BoolProperty::New( false ), renderer, overwrite); // node->AddProperty( "Set_FA_VertexAlpha", mitk::BoolProperty::New( false ), renderer, overwrite); // node->AddProperty( "pointSize", mitk::FloatProperty::New(0.5), renderer, overwrite); // node->AddProperty( "setShading", mitk::IntProperty::New(1), renderer, overwrite); // node->AddProperty( "Xmove", mitk::IntProperty::New( 0 ), renderer, overwrite); // node->AddProperty( "Ymove", mitk::IntProperty::New( 0 ), renderer, overwrite); // node->AddProperty( "Zmove", mitk::IntProperty::New( 0 ), renderer, overwrite); // node->AddProperty( "RepPoints", mitk::BoolProperty::New( false ), renderer, overwrite); // node->AddProperty( "TubeSides", mitk::IntProperty::New( 8 ), renderer, overwrite); // node->AddProperty( "TubeRadius", mitk::FloatProperty::New( 0.15 ), renderer, overwrite); // node->AddProperty( "TubeOpacity", mitk::FloatProperty::New( 1.0 ), renderer, overwrite); node->AddProperty( "pickable", mitk::BoolProperty::New( true ), renderer, overwrite); Superclass::SetDefaultProperties(node, renderer, overwrite); } vtkProp* mitk::FiberBundleXMapper3D::GetVtkProp(mitk::BaseRenderer *renderer) { //MITK_INFO << "FiberBundleXxXXMapper3D()GetVTKProp"; //this->GenerateData(); return m_FiberAssembly; } void mitk::FiberBundleXMapper3D::ApplyProperties(mitk::BaseRenderer* renderer) { // MITK_INFO << "FiberBundleXXXXMapper3D ApplyProperties(renderer)"; } void mitk::FiberBundleXMapper3D::UpdateVtkObjects() { // MITK_INFO << "FiberBundleXxxXMapper3D UpdateVtkObjects()"; } void mitk::FiberBundleXMapper3D::SetVtkMapperImmediateModeRendering(vtkMapper *) { }