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 aefb54c38e..93aa768dcf 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,798 +1,783 @@ /*========================================================================= 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 //#include //for fiberStructure //===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() { - //accurate time measurement using ITK timeProbe + /* MEASUREMENTS AND FANCY GUI EFFECTS + * accurate time measurement using ITK timeProbe*/ itk::TimeProbe clock; clock.Start(); - m_itemPackage.st_Controls->infoTimerGenerateFiberIds->setText(QString::number(0)); //set GUI representation of timer to 0 - m_itemPackage.st_idGenerateTimer->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_idGenerateTimer->stop(); //stop fancy Qt-timer in GUI + m_itemPackage.st_FancyGUITimer1->stop(); m_itemPackage.st_Controls->infoTimerGenerateFiberIds->setText( QString::number(clock.GetTotal()) ); - delete m_itemPackage.st_idGenerateTimer; // fancy timer is not needed anymore + 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() { - //accurate time measurement using ITK timeProbe - //itk::TimeProbe clock; - //clock.Start(); - MITK_INFO << "GENERATE RANDOM WORKER .. run()"; - - // 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(); - // - // /*====== checkpoint: compare initialized and required points ============================= INCLUDE IN TEST */ -// if (numOfPoints != pnts->GetNumberOfPoints()) { -// MITK_INFO << "VTK POINT ERROR, WRONG AMOUNT OF GENRERATED POINTS... COULD BE VTK BUG OR BITFLIP DUE TO COSMIC RADIATION!"; -// return ; -// }/* ================================= */ - // - // /* 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; - } - - //=====timer 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 ) - { - 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."; - }/* ====================================================*/ - + /* MEASUREMENTS AND FANCY GUI EFFECTS */ + m_itemPackage.st_Controls->infoTimerGenerateFiberBundle->setText(QString::number(0)); + m_itemPackage.st_FancyGUITimer1->start(); + + //do processing, generateRandomFibers + int numOfFibers = m_itemPackage.st_Controls->boxFiberNumbers->value(); + int distrRadius = m_itemPackage.st_Controls->boxDistributionRadius->value(); + int numOfPoints = numOfFibers * distrRadius; + + std::vector< std::vector > fiberStorage; + for (int i=0; i a; + fiberStorage.push_back( a ); + } + + /* Generate Point Cloud */ + vtkSmartPointer randomPoints = vtkSmartPointer::New(); + randomPoints->SetCenter(0.0, 0.0, 0.0); + randomPoints->SetNumberOfPoints(numOfPoints); + randomPoints->SetRadius(distrRadius); + randomPoints->Update(); + vtkPoints* pnts = randomPoints->GetOutput()->GetPoints(); + + /* ASSIGN EACH POINT TO A RANDOM FIBER */ + srand((unsigned)time(0)); // init randomizer + for (int i=0; iGetNumberOfPoints(); ++i) { + //generate random number between 0 and numOfFibers-1 + int random_integer; + random_integer = (rand()%numOfFibers); - /* HOSTING POLYDATA FOR RANDOM FIBERSTRUCTURE */ - vtkPolyData* PDRandom = vtkPolyData::New(); - PDRandom->SetPoints(pnts); - PDRandom->SetLines(linesCell); + //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()); - //====timer measurement======== - clock.Stop(); - m_itemPackage.st_Controls->infoTimerGenerateFiberBundle->setText( QString::number(clock.GetTotal()) ); - MITK_INFO << "=====Assambling random Fibers to Polydata======\nMean: " << clock.GetMean() << std::endl; - MITK_INFO << "Total: " << clock.GetTotal() << std::endl; - MITK_INFO << "in thread pnts: "<< PDRandom->GetNumberOfPoints() << " in thread lines: " << PDRandom->GetNumberOfLines(); - //============================= + for (unsigned long si=0; siGetPointIds()->SetId( si, singleFiber.at(si) ); + } + linesCell->InsertNextCell(fiber); + } + + /* checkpoint for cellarray allocation */ + if ( (linesCell->GetSize()/pnts->GetNumberOfPoints()) != 2 ) //e.g. size: 12, number of points:6 .... each cell hosts point ids (6 ids) + cell index for each idPoint. 6 * 2 = 12 + { + MITK_INFO << "RANDOM FIBER ALLOCATION CAN NOT BE TRUSTED ANYMORE! Correct leak or remove command: linesCell->Allocate(pnts->GetNumberOfPoints()*2) but be aware of possible loss in performance."; + } + + /* HOSTING POLYDATA FOR RANDOM FIBERSTRUCTURE */ + vtkPolyData* PDRandom = vtkPolyData::New(); //no need to delete because data is needed in datastorage. + PDRandom->SetPoints(pnts); + PDRandom->SetLines(linesCell); - // write random generated fiberstructure to datastorage + // 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); - // clock.Stop(); - // m_itemPackage.st_idGenerateTimer->stop(); //stop fancy Qt-timer in GUI - // m_itemPackage.st_Controls->infoTimerGenerateFiberIds->setText( QString::number(clock.GetTotal()) ); + /* 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(); } -//=================================================================================== - +//============================================== +//======== W O R K E R S ________ E N D ======== +//============================================== // ========= HERE STARTS THE ACTUAL FIBERBUNDLE 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_hostThread = new QThread; m_threadInProgress = false; } // Destructor QmitkFiberBundleDeveloperView::~QmitkFiberBundleDeveloperView() { m_FiberBundleX->Delete(); delete m_hostThread; delete m_FiberIDGenerator; - + } 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);//not yet implemented m_Controls->buttonSMFibers->setEnabled(false);//not yet implemented m_Controls->buttonVtkDecimatePro->setEnabled(false);//not yet implemented m_Controls->buttonVtkSmoothPD->setEnabled(false);//not yet implemented m_Controls->buttonGenerateTubes->setEnabled(false);//not yet implemented connect( m_Controls->buttonGenerateFibers, SIGNAL(clicked()), this, SLOT(DoGenerateFibers()) ); connect( m_Controls->buttonGenerateFiberIds, SIGNAL(pressed()), this, SLOT(DoGenerateFiberIDs()) ); connect( m_Controls->radioButton_directionRandom, SIGNAL(clicked()), this, SLOT(DoUpdateGenerateFibersWidget()) ); connect( m_Controls->radioButton_directionX, SIGNAL(clicked()), this, SLOT(DoUpdateGenerateFibersWidget()) ); connect( m_Controls->radioButton_directionY, SIGNAL(clicked()), this, SLOT(DoUpdateGenerateFibersWidget()) ); connect( m_Controls->radioButton_directionZ, SIGNAL(clicked()), this, SLOT(DoUpdateGenerateFibersWidget()) ); connect( m_Controls->toolBox, SIGNAL(currentChanged ( int ) ), this, SLOT(SelectionChangedToolBox(int)) ); } // Checkpoint for fiber ORIENTATION if ( m_DirectionRadios.empty() ) { m_DirectionRadios.insert(0, m_Controls->radioButton_directionRandom); m_DirectionRadios.insert(1, m_Controls->radioButton_directionX); m_DirectionRadios.insert(2, m_Controls->radioButton_directionY); m_DirectionRadios.insert(3, m_Controls->radioButton_directionZ); } // set GUI elements of FiberGenerator to according configuration DoUpdateGenerateFibersWidget(); } /* THIS METHOD UPDATES ALL GUI ELEMENTS OF QGroupBox DEPENDING ON CURRENTLY SELECTED * RADIO BUTTONS */ void QmitkFiberBundleDeveloperView::DoUpdateGenerateFibersWidget() { //get selected radioButton QString fibDirection; //stores the object_name of selected radiobutton QVector::const_iterator i; for (i = m_DirectionRadios.begin(); i != m_DirectionRadios.end(); ++i) { QRadioButton* rdbtn = *i; if (rdbtn->isChecked()) fibDirection = rdbtn->objectName(); } if ( fibDirection == FIB_RADIOBUTTON_DIRECTION_RANDOM ) { // disable radiobuttons if (m_Controls->boxFiberMinLength->isEnabled()) m_Controls->boxFiberMinLength->setEnabled(false); if (m_Controls->labelFiberMinLength->isEnabled()) m_Controls->labelFiberMinLength->setEnabled(false); if (m_Controls->boxFiberMaxLength->isEnabled()) m_Controls->boxFiberMaxLength->setEnabled(false); if (m_Controls->labelFiberMaxLength->isEnabled()) m_Controls->labelFiberMaxLength->setEnabled(false); //enable radiobuttons if (!m_Controls->labelFibersTotal->isEnabled()) m_Controls->labelFibersTotal->setEnabled(true); if (!m_Controls->boxFiberNumbers->isEnabled()) m_Controls->boxFiberNumbers->setEnabled(true); if (!m_Controls->labelDistrRadius->isEnabled()) m_Controls->labelDistrRadius->setEnabled(true); if (!m_Controls->boxDistributionRadius->isEnabled()) m_Controls->boxDistributionRadius->setEnabled(true); } else { // disable radiobuttons if (m_Controls->labelDistrRadius->isEnabled()) m_Controls->labelDistrRadius->setEnabled(false); if (m_Controls->boxDistributionRadius->isEnabled()) m_Controls->boxDistributionRadius->setEnabled(false); //enable radiobuttons if (!m_Controls->labelFibersTotal->isEnabled()) m_Controls->labelFibersTotal->setEnabled(true); if (!m_Controls->boxFiberNumbers->isEnabled()) m_Controls->boxFiberNumbers->setEnabled(true); if (!m_Controls->boxFiberMinLength->isEnabled()) m_Controls->boxFiberMinLength->setEnabled(true); if (!m_Controls->labelFiberMinLength->isEnabled()) m_Controls->labelFiberMinLength->setEnabled(true); if (!m_Controls->boxFiberMaxLength->isEnabled()) m_Controls->boxFiberMaxLength->setEnabled(true); if (!m_Controls->labelFiberMaxLength->isEnabled()) m_Controls->labelFiberMaxLength->setEnabled(true); } } void QmitkFiberBundleDeveloperView::DoGenerateFibers() { // GET SELECTED FIBER DIRECTION QString fibDirection; //stores the object_name of selected radiobutton QVector::const_iterator i; for (i = m_DirectionRadios.begin(); i != m_DirectionRadios.end(); ++i) { QRadioButton* rdbtn = *i; if (rdbtn->isChecked()) fibDirection = rdbtn->objectName(); } // vtkPolyData* output; // FiberPD stores the generated PolyData... going to be generated in thread if ( fibDirection == FIB_RADIOBUTTON_DIRECTION_RANDOM ) { // build polydata with random lines and fibers // output = GenerateVtkFibersRandom(); } else if ( fibDirection == FIB_RADIOBUTTON_DIRECTION_X ) { // build polydata with XDirection fibers //output = GenerateVtkFibersDirectionX(); } else if ( fibDirection == FIB_RADIOBUTTON_DIRECTION_Y ) { // build polydata with YDirection fibers // output = GenerateVtkFibersDirectionY(); } else if ( fibDirection == FIB_RADIOBUTTON_DIRECTION_Z ) { // build polydata with ZDirection fibers // output = GenerateVtkFibersDirectionZ(); } } void QmitkFiberBundleDeveloperView::PutFibersToDataStorage( vtkPolyData* threadOutput) { MITK_INFO << "YEHAAAAAAAAA WHAT A GREAT DAY!!!!!!"; MITK_INFO << "lines: " << threadOutput->GetNumberOfLines() << "pnts: " << threadOutput->GetNumberOfPoints(); //qthread mutex lock mitk::FiberBundleX::Pointer FB = mitk::FiberBundleX::New(); FB->SetFibers(threadOutput); FB->SetGeometry(this->GenerateStandardGeometryForMITK()); mitk::DataNode::Pointer FBNode; FBNode = mitk::DataNode::New(); FBNode->SetName("FiberBundleX"); FBNode->SetData(FB); FBNode->SetVisibility(true); GetDataStorage()->Add(FBNode); //output->Delete(); const mitk::PlaneGeometry * tsgeo = m_MultiWidget->GetTimeNavigationController()->GetCurrentPlaneGeometry(); if (tsgeo == NULL) { /* GetDataStorage()->Modified etc. have no effect, therefore proceed as followed below */ // get all nodes that have not set "includeInBoundingBox" to false mitk::NodePredicateNot::Pointer pred = mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("includeInBoundingBox" , mitk::BoolProperty::New(false))); mitk::DataStorage::SetOfObjects::ConstPointer rs = GetDataStorage()->GetSubset(pred); // calculate bounding geometry of these nodes mitk::TimeSlicedGeometry::Pointer bounds = GetDataStorage()->ComputeBoundingGeometry3D(rs); // initialize the views to the bounding geometry mitk::RenderingManager::GetInstance()->InitializeViews(bounds); } else { GetDataStorage()->Modified(); m_MultiWidget->RequestUpdate(); //necessary?? } //qthread mutex unlock } /* * Generate polydata of random fibers */ void QmitkFiberBundleDeveloperView::GenerateVtkFibersRandom() { struct Package4WorkingThread ItemPackageForRandomGenerator; ItemPackageForRandomGenerator.st_FBX = m_FiberBundleX; ItemPackageForRandomGenerator.st_Controls = m_Controls; ItemPackageForRandomGenerator.st_host = this; ItemPackageForRandomGenerator.st_pntr_to_Method_PutFibersToDataStorage = &QmitkFiberBundleDeveloperView::PutFibersToDataStorage; - + 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::BeforeThread_GenerateFibersRandom() { } void QmitkFiberBundleDeveloperView::AfterThread_GenerateFibersRandom() { m_threadInProgress = false; 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; } /* === OutSourcedMethod: THIS METHOD GENERATES ESSENTIAL GEOMETRY PARAMETERS FOR THE MITK FRAMEWORK === * WITHOUT, the rendering mechanism will ignore objects without valid Geometry * for each object, MITK requires: ORIGIN, SPACING, TRANSFORM MATRIX, BOUNDING-BOX */ mitk::Geometry3D::Pointer QmitkFiberBundleDeveloperView::GenerateStandardGeometryForMITK() { mitk::Geometry3D::Pointer geometry = mitk::Geometry3D::New(); // generate origin mitk::Point3D origin; origin[0] = 0; origin[1] = 0; origin[2] = 0; geometry->SetOrigin(origin); // generate spacing float spacing[3] = {1,1,1}; geometry->SetSpacing(spacing); // generate identity transform-matrix vtkMatrix4x4* m = vtkMatrix4x4::New(); geometry->SetIndexToWorldTransformByVtkMatrix(m); // generate boundingbox // for an usable bounding-box use gui parameters to estimate the boundingbox float bounds[] = {500, 500, 500, -500, -500, -500}; // GET SELECTED FIBER DIRECTION QString fibDirection; //stores the object_name of selected radiobutton QVector::const_iterator i; for (i = m_DirectionRadios.begin(); i != m_DirectionRadios.end(); ++i) { QRadioButton* rdbtn = *i; if (rdbtn->isChecked()) fibDirection = rdbtn->objectName(); } if ( fibDirection == FIB_RADIOBUTTON_DIRECTION_RANDOM ) { // use information about distribution parameter to calculate bounding box int distrRadius = m_Controls->boxDistributionRadius->value(); bounds[0] = distrRadius; bounds[1] = distrRadius; bounds[2] = distrRadius; bounds[3] = -distrRadius; bounds[4] = -distrRadius; bounds[5] = -distrRadius; } else { // so far only X,Y,Z directions are available MITK_INFO << "_______GEOMETRY ISSUE_____\n***BoundingBox for X, Y, Z fiber directions are not optimized yet!***"; int maxFibLength = m_Controls->boxFiberMaxLength->value(); bounds[0] = maxFibLength; bounds[1] = maxFibLength; bounds[2] = maxFibLength; bounds[3] = -maxFibLength; bounds[4] = -maxFibLength; bounds[5] = -maxFibLength; } geometry->SetFloatBounds(bounds); geometry->SetImageGeometry(true); //?? return geometry; } void QmitkFiberBundleDeveloperView::UpdateFiberIDTimer() { //MAKE SURE by yourself THAT NOTHING ELSE THAN A NUMBER IS SET IN THAT LABEL QString crntValue = m_Controls->infoTimerGenerateFiberIds->text(); int tmpVal = crntValue.toInt(); m_Controls->infoTimerGenerateFiberIds->setText(QString::number(++tmpVal)); m_Controls->infoTimerGenerateFiberIds->update(); } /* Initialie ID dataset in FiberBundleX */ void QmitkFiberBundleDeveloperView::DoGenerateFiberIDs() { /* ===== TIMER CONFIGURATIONS for visual effect ====== * start and stop is called in Thread */ QTimer *localTimer = new QTimer; // timer must be initialized here, otherwise timer is not fancy enough localTimer->setInterval( 10 ); connect( localTimer, SIGNAL(timeout()), this, SLOT(UpdateFiberIDTimer()) ); // pack items which are needed by thread processing struct Package4WorkingThread FiberIdPackage; FiberIdPackage.st_FBX = m_FiberBundleX; - FiberIdPackage.st_idGenerateTimer = localTimer; + FiberIdPackage.st_FancyGUITimer1 = localTimer; FiberIdPackage.st_Controls = m_Controls; - + 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; } void QmitkFiberBundleDeveloperView::AfterThread_IdGenerate() { - + m_threadInProgress = false; disconnect(m_hostThread, 0, 0, 0); m_hostThread->disconnect(); } /* THE WORKER ACCESS THIS METHOD TO PASS GENERATED FIBERBUNDLE * TO DATASTORAGE */ void QmitkFiberBundleDeveloperView::SetGeneratedFBX() { } void QmitkFiberBundleDeveloperView::ResetFiberInfoWidget() { if (m_Controls->infoAnalyseNumOfFibers->isEnabled()) { m_Controls->infoAnalyseNumOfFibers->setText("-"); m_Controls->infoAnalyseNumOfPoints->setText("-"); m_Controls->infoAnalyseNumOfFibers->setEnabled(false); } } void QmitkFiberBundleDeveloperView::FeedFiberInfoWidget() { if (!m_Controls->infoAnalyseNumOfFibers->isEnabled()) m_Controls->infoAnalyseNumOfFibers->setEnabled(true); QString numOfFibers; numOfFibers.setNum( m_FiberBundleX->GetFibers()->GetNumberOfLines() ); QString numOfPoints; numOfPoints.setNum( m_FiberBundleX->GetFibers()->GetNumberOfPoints() ); m_Controls->infoAnalyseNumOfFibers->setText( numOfFibers ); m_Controls->infoAnalyseNumOfPoints->setText( numOfPoints ); } void QmitkFiberBundleDeveloperView::SelectionChangedToolBox(int idx) { MITK_INFO << "printtoolbox: " << idx; if (m_Controls->page_FiberInfo->isVisible() && m_FiberBundleX != NULL) { FeedFiberInfoWidget(); } else { //if infolables are disabled: return //else set info back to - and set label and info to disabled if (!m_Controls->page_FiberInfo->isVisible()) { return; } else { ResetFiberInfoWidget(); } } } void QmitkFiberBundleDeveloperView::FBXDependendGUIElementsConfigurator(bool isVisible) { // ==== FIBER PROCESSING ELEMENTS ====== m_Controls->buttonGenerateFiberIds->setEnabled(isVisible); } void QmitkFiberBundleDeveloperView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_MultiWidget = &stdMultiWidget; } void QmitkFiberBundleDeveloperView::StdMultiWidgetNotAvailable() { m_MultiWidget = NULL; } /* OnSelectionChanged is registered to SelectionService, therefore no need to implement SelectionService Listener explicitly */ void QmitkFiberBundleDeveloperView::OnSelectionChanged( std::vector nodes ) { /* ==== reset everyhing related to FiberBundleX ====== * - variable m_FiberBundleX * - visualization of analysed fiberbundle */ m_FiberBundleX = NULL; //reset pointer, so that member does not point to depricated locations ResetFiberInfoWidget(); FBXDependendGUIElementsConfigurator(false); m_Controls->infoTimerGenerateFiberIds->setText("-"); //set GUI representation of timer to - m_Controls->infoTimerGenerateFiberBundle->setText( "-" ); //==================================================== if (nodes.empty()) return; for( std::vector::iterator it = nodes.begin(); it != nodes.end(); ++it ) { mitk::DataNode::Pointer node = *it; /* CHECKPOINT: FIBERBUNDLE*/ if( node.IsNotNull() && dynamic_cast(node->GetData()) ) { m_FiberBundleX = dynamic_cast(node->GetData()); if (m_FiberBundleX == NULL) MITK_INFO << "========ATTENTION=========\n unable to load selected FiberBundleX to FiberBundleDeveloper-plugin \n"; // ==== FIBERBUNDLE_INFO ELEMENTS ==== if ( m_Controls->page_FiberInfo->isVisible() ) FeedFiberInfoWidget(); // enable FiberBundleX related Gui Elements, such as buttons etc. FBXDependendGUIElementsConfigurator(true); } } } void QmitkFiberBundleDeveloperView::Activated() { MITK_INFO << "FB DevelopersV ACTIVATED()"; } diff --git a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberBundleDeveloperView.h b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberBundleDeveloperView.h index 561cb27911..f8e835573a 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,224 +1,226 @@ /*========================================================================= 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 // Qt #include #include #include // VTK #include #include #include #include #include #include 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_idGenerateTimer; + QTimer* st_FancyGUITimer1; Ui::QmitkFiberBundleDeveloperViewControls* st_Controls; //functors to outdoor methods QmitkFiberBundleDeveloperView* st_host; void (QmitkFiberBundleDeveloperView::*st_pntr_to_Method_PutFibersToDataStorage) (vtkPolyData*); }; // ==================================================================== // ============= 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: //mitk::FiberBundleX* m_FBX; 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: //mitk::FiberBundleX* m_FBX; Package4WorkingThread m_itemPackage; QThread* m_hostingThread; }; // ========= 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 UpdateFiberIDTimer(); void SelectionChangedToolBox(int); //SLOTS FOR THREADS void BeforeThread_IdGenerate(); void AfterThread_IdGenerate(); void BeforeThread_GenerateFibersRandom(); void AfterThread_GenerateFibersRandom(); protected: /// \brief called by QmitkFunctionality when DataManager's selection has changed virtual void OnSelectionChanged( std::vector nodes ); Ui::QmitkFiberBundleDeveloperViewControls* m_Controls; QmitkStdMultiWidget* m_MultiWidget; private: /* METHODS GENERATING FIBERSTRUCTURES */ void GenerateVtkFibersRandom(); vtkSmartPointer GenerateVtkFibersDirectionX(); vtkSmartPointer GenerateVtkFibersDirectionY(); vtkSmartPointer GenerateVtkFibersDirectionZ(); void PutFibersToDataStorage( vtkPolyData* ); /* METHODS FOR FIBER PROCESSING OR PREPROCESSING */ /* HELPERMETHODS */ mitk::Geometry3D::Pointer GenerateStandardGeometryForMITK(); void ResetFiberInfoWidget(); void FeedFiberInfoWidget(); void FBXDependendGUIElementsConfigurator(bool); void SetGeneratedFBX(); //contains the selected FiberBundle mitk::FiberBundleX* m_FiberBundleX; // radiobutton groups QVector< QRadioButton* > m_DirectionRadios; QVector< QRadioButton* > m_FARadios; QVector< QRadioButton* > m_GARadios; // Thread based Workers which do some processing of fibers QmitkFiberIDWorker * m_FiberIDGenerator; QmitkFiberGenerateRandomWorker * m_GeneratorFibersRandom; QThread * m_hostThread; bool m_threadInProgress; }; #endif // _QMITKFIBERTRACKINGVIEW_H_INCLUDED