diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fde9427 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +Modules/FiberDissection/Interactor/mitkStreamlineInteractor (copy).cpp diff --git a/Modules/DiffusionCore/IODataStructures/mitkFiberBundle.cpp b/Modules/DiffusionCore/IODataStructures/mitkFiberBundle.cpp index 828d2a6..db6cc0a 100644 --- a/Modules/DiffusionCore/IODataStructures/mitkFiberBundle.cpp +++ b/Modules/DiffusionCore/IODataStructures/mitkFiberBundle.cpp @@ -1,2847 +1,2908 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkFiberBundle.h" #include <mitkPlanarCircle.h> #include <mitkPlanarPolygon.h> #include <mitkPlanarFigureComposite.h> #include <mitkDiffusionFunctionCollection.h> #include <mitkPixelTypeMultiplex.h> #include <vtkPointData.h> #include <vtkDataArray.h> #include <vtkUnsignedCharArray.h> #include <vtkPolyLine.h> #include <vtkCellArray.h> #include <vtkCellData.h> #include <vtkIdFilter.h> #include <vtkClipPolyData.h> #include <vtkPlane.h> #include <vtkDoubleArray.h> #include <vtkKochanekSpline.h> #include <vtkParametricFunctionSource.h> #include <vtkParametricSpline.h> #include <vtkPolygon.h> #include <vtkCleanPolyData.h> #include <boost/timer/progress_display.hpp> #include <vtkTransformPolyDataFilter.h> #include <mitkTransferFunction.h> #include <vtkLookupTable.h> #include <mitkLookupTable.h> #include <vtkCardinalSpline.h> #include <vtkAppendPolyData.h> #include <random> #include <algorithm> const char* mitk::FiberBundle::FIBER_ID_ARRAY = "Fiber_IDs"; mitk::FiberBundle::FiberBundle( vtkPolyData* fiberPolyData ) : m_NumFibers(0) { m_TrackVisHeader.hdr_size = 0; m_FiberWeights = vtkSmartPointer<vtkFloatArray>::New(); m_FiberWeights->SetName("FIBER_WEIGHTS"); m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New(); if (fiberPolyData != nullptr) m_FiberPolyData = fiberPolyData; else { this->m_FiberPolyData->SetPoints(vtkSmartPointer<vtkPoints>::New()); this->m_FiberPolyData->SetLines(vtkSmartPointer<vtkCellArray>::New()); } this->UpdateFiberGeometry(); this->GenerateFiberIds(); this->ColorFibersByOrientation(); } mitk::FiberBundle::~FiberBundle() { } mitk::FiberBundle::Pointer mitk::FiberBundle::GetDeepCopy() { mitk::FiberBundle::Pointer newFib = mitk::FiberBundle::New(m_FiberPolyData); newFib->SetFiberColors(this->m_FiberColors); newFib->SetFiberWeights(this->m_FiberWeights); newFib->SetTrackVisHeader(this->GetTrackVisHeader()); return newFib; } vtkSmartPointer<vtkPolyData> mitk::FiberBundle::GeneratePolyDataByIds(std::vector<unsigned int> fiberIds, vtkSmartPointer<vtkFloatArray> weights) { vtkSmartPointer<vtkPolyData> newFiberPolyData = vtkSmartPointer<vtkPolyData>::New(); vtkSmartPointer<vtkCellArray> newLineSet = vtkSmartPointer<vtkCellArray>::New(); vtkSmartPointer<vtkPoints> newPointSet = vtkSmartPointer<vtkPoints>::New(); weights->SetNumberOfValues(fiberIds.size()); int counter = 0; auto finIt = fiberIds.begin(); while ( finIt != fiberIds.end() ) { if (*finIt>GetNumFibers()){ MITK_INFO << "FiberID can not be negative or >NumFibers!!! check id Extraction!" << *finIt; break; } vtkSmartPointer<vtkCell> fiber = m_FiberIdDataSet->GetCell(*finIt);//->DeepCopy(fiber); vtkSmartPointer<vtkPoints> fibPoints = fiber->GetPoints(); vtkSmartPointer<vtkPolyLine> newFiber = vtkSmartPointer<vtkPolyLine>::New(); newFiber->GetPointIds()->SetNumberOfIds( fibPoints->GetNumberOfPoints() ); for(int i=0; i<fibPoints->GetNumberOfPoints(); i++) { newFiber->GetPointIds()->SetId(i, newPointSet->GetNumberOfPoints()); newPointSet->InsertNextPoint(fibPoints->GetPoint(i)[0], fibPoints->GetPoint(i)[1], fibPoints->GetPoint(i)[2]); } weights->InsertValue(counter, this->GetFiberWeight(*finIt)); newLineSet->InsertNextCell(newFiber); ++finIt; ++counter; } newFiberPolyData->SetPoints(newPointSet); newFiberPolyData->SetLines(newLineSet); return newFiberPolyData; } // merge two fiber bundles mitk::FiberBundle::Pointer mitk::FiberBundle::AddBundles(std::vector< mitk::FiberBundle::Pointer > fibs) { vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New(); vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New(); vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New(); // add current fiber bundle vtkSmartPointer<vtkFloatArray> weights = vtkSmartPointer<vtkFloatArray>::New(); auto num_weights = this->GetNumFibers(); for (auto fib : fibs) num_weights += fib->GetNumFibers(); weights->SetNumberOfValues(num_weights); unsigned int counter = 0; for (unsigned int i=0; i<m_FiberPolyData->GetNumberOfCells(); ++i) { vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); for (unsigned int j=0; j<numPoints; ++j) { double p[3]; points->GetPoint(j, p); vtkIdType id = vNewPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } weights->InsertValue(counter, this->GetFiberWeight(i)); vNewLines->InsertNextCell(container); counter++; } for (auto fib : fibs) { // add new fiber bundle for (unsigned int i=0; i<fib->GetFiberPolyData()->GetNumberOfCells(); i++) { vtkCell* cell = fib->GetFiberPolyData()->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); for (unsigned int j=0; j<numPoints; j++) { double p[3]; points->GetPoint(j, p); vtkIdType id = vNewPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } weights->InsertValue(counter, fib->GetFiberWeight(i)); vNewLines->InsertNextCell(container); counter++; } } // initialize PolyData vNewPolyData->SetPoints(vNewPoints); vNewPolyData->SetLines(vNewLines); // initialize fiber bundle mitk::FiberBundle::Pointer newFib = mitk::FiberBundle::New(vNewPolyData); newFib->SetFiberWeights(weights); return newFib; } // merge two fiber bundles mitk::FiberBundle::Pointer mitk::FiberBundle::AddBundle(mitk::FiberBundle* fib) { if (fib==nullptr) return this->GetDeepCopy(); MITK_INFO << "Adding fibers"; vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New(); vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New(); vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New(); // add current fiber bundle vtkSmartPointer<vtkFloatArray> weights = vtkSmartPointer<vtkFloatArray>::New(); weights->SetNumberOfValues(this->GetNumFibers()+fib->GetNumFibers()); unsigned int counter = 0; for (unsigned int i=0; i<m_FiberPolyData->GetNumberOfCells(); i++) { vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); for (unsigned int j=0; j<numPoints; j++) { double p[3]; points->GetPoint(j, p); vtkIdType id = vNewPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } weights->InsertValue(counter, this->GetFiberWeight(i)); vNewLines->InsertNextCell(container); counter++; } // add new fiber bundle for (unsigned int i=0; i<fib->GetFiberPolyData()->GetNumberOfCells(); i++) { vtkCell* cell = fib->GetFiberPolyData()->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); for (unsigned int j=0; j<numPoints; j++) { double p[3]; points->GetPoint(j, p); vtkIdType id = vNewPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } weights->InsertValue(counter, fib->GetFiberWeight(i)); vNewLines->InsertNextCell(container); counter++; } // initialize PolyData vNewPolyData->SetPoints(vNewPoints); vNewPolyData->SetLines(vNewLines); // initialize fiber bundle mitk::FiberBundle::Pointer newFib = mitk::FiberBundle::New(vNewPolyData); newFib->SetFiberWeights(weights); return newFib; } // Only retain fibers with a weight larger than the specified threshold mitk::FiberBundle::Pointer mitk::FiberBundle::FilterByWeights(float weight_thr, bool invert) { vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New(); vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New(); vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New(); std::vector<float> weights; for (unsigned int i=0; i<this->GetNumFibers(); i++) { if ( (invert && this->GetFiberWeight(i)>weight_thr) || (!invert && this->GetFiberWeight(i)<=weight_thr)) continue; vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); for (int j=0; j<numPoints; j++) { double p[3]; points->GetPoint(j, p); vtkIdType id = vNewPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } vNewLines->InsertNextCell(container); weights.push_back(this->GetFiberWeight(i)); } // initialize PolyData vNewPolyData->SetPoints(vNewPoints); vNewPolyData->SetLines(vNewLines); // initialize fiber bundle mitk::FiberBundle::Pointer newFib = mitk::FiberBundle::New(vNewPolyData); for (unsigned int i=0; i<weights.size(); ++i) newFib->SetFiberWeight(i, weights.at(i)); newFib->SetTrackVisHeader(this->GetTrackVisHeader()); return newFib; } // Only retain a subsample of the fibers mitk::FiberBundle::Pointer mitk::FiberBundle::SubsampleFibers(float factor, bool random_seed) { vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New(); vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New(); vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New(); unsigned int new_num_fibs = static_cast<unsigned int>(std::round(this->GetNumFibers()*factor)); MITK_INFO << "Subsampling fibers with factor " << factor << "(" << new_num_fibs << "/" << this->GetNumFibers() << ")"; // add current fiber bundle vtkSmartPointer<vtkFloatArray> weights = vtkSmartPointer<vtkFloatArray>::New(); weights->SetNumberOfValues(new_num_fibs); std::vector< unsigned int > ids; for (unsigned int i=0; i<this->GetNumFibers(); i++) ids.push_back(i); if (random_seed) std::srand(static_cast<unsigned int>(std::time(nullptr))); else std::srand(0); std::random_device rd; std::mt19937 g(rd()); std::shuffle(ids.begin(), ids.end(), g); unsigned int counter = 0; for (unsigned int i=0; i<new_num_fibs; i++) { vtkCell* cell = m_FiberPolyData->GetCell(ids.at(i)); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); for (int j=0; j<numPoints; j++) { double p[3]; points->GetPoint(j, p); vtkIdType id = vNewPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } weights->InsertValue(counter, this->GetFiberWeight(ids.at(i))); vNewLines->InsertNextCell(container); counter++; } // initialize PolyData vNewPolyData->SetPoints(vNewPoints); vNewPolyData->SetLines(vNewLines); // initialize fiber bundle mitk::FiberBundle::Pointer newFib = mitk::FiberBundle::New(vNewPolyData); newFib->SetFiberWeights(weights); newFib->SetTrackVisHeader(this->GetTrackVisHeader()); return newFib; } // subtract two fiber bundles mitk::FiberBundle::Pointer mitk::FiberBundle::SubtractBundle(mitk::FiberBundle* fib) { if (fib==nullptr) return this->GetDeepCopy(); MITK_INFO << "Subtracting fibers"; vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New(); vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New(); vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New(); std::vector< std::vector< itk::Point<float, 3> > > points1; for(unsigned int i=0; i<m_NumFibers; i++ ) { vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); if (points==nullptr || numPoints<=0) continue; itk::Point<float, 3> start = mitk::imv::GetItkPoint(points->GetPoint(0)); itk::Point<float, 3> end = mitk::imv::GetItkPoint(points->GetPoint(numPoints-1)); points1.push_back( {start, end} ); } std::vector< std::vector< itk::Point<float, 3> > > points2; for(unsigned int i=0; i<fib->GetNumFibers(); i++ ) { vtkCell* cell = fib->GetFiberPolyData()->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); if (points==nullptr || numPoints<=0) continue; itk::Point<float, 3> start =mitk::imv::GetItkPoint(points->GetPoint(0)); itk::Point<float, 3> end =mitk::imv::GetItkPoint(points->GetPoint(numPoints-1)); points2.push_back( {start, end} ); } // int progress = 0; std::vector< int > ids; #pragma omp parallel for for (int i=0; i<static_cast<int>(points1.size()); i++) { bool match = false; for (unsigned int j=0; j<points2.size(); j++) { auto v1 = points1.at(static_cast<unsigned int>(i)); auto v2 = points2.at(j); float dist=0; for (unsigned int c=0; c<v1.size(); c++) { float d = v1[c][0]-v2[c][0]; dist += d*d; d = v1[c][1]-v2[c][1]; dist += d*d; d = v1[c][2]-v2[c][2]; dist += d*d; } dist /= v1.size(); if (dist<0.000001f) { match = true; break; } dist=0; for (unsigned int c=0; c<v1.size(); c++) { float d = v1[v1.size()-1-c][0]-v2[c][0]; dist += d*d; d = v1[v1.size()-1-c][1]-v2[c][1]; dist += d*d; d = v1[v1.size()-1-c][2]-v2[c][2]; dist += d*d; } dist /= v1.size(); if (dist<0.000001f) { match = true; break; } } #pragma omp critical if (!match) ids.push_back(i); } for( int i : ids ) { vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); if (points==nullptr || numPoints<=0) continue; vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); for( int j=0; j<numPoints; j++) { vtkIdType id = vNewPoints->InsertNextPoint(points->GetPoint(j)); container->GetPointIds()->InsertNextId(id); } vNewLines->InsertNextCell(container); } if(vNewLines->GetNumberOfCells()==0) return mitk::FiberBundle::New(); // initialize PolyData vNewPolyData->SetPoints(vNewPoints); vNewPolyData->SetLines(vNewLines); // initialize fiber bundle return mitk::FiberBundle::New(vNewPolyData); } /* * set PolyData (additional flag to recompute fiber geometry, default = true) */ void mitk::FiberBundle::SetFiberPolyData(vtkSmartPointer<vtkPolyData> fiberPD, bool updateGeometry) { if (fiberPD == nullptr) this->m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New(); else { m_FiberPolyData->CopyStructure(fiberPD); // m_FiberPolyData->DeepCopy(fiberPD); } m_NumFibers = static_cast<unsigned int>(m_FiberPolyData->GetNumberOfLines()); if (updateGeometry) UpdateFiberGeometry(); GenerateFiberIds(); ColorFibersByOrientation(); } /* * return vtkPolyData */ vtkSmartPointer<vtkPolyData> mitk::FiberBundle::GetFiberPolyData() const { return m_FiberPolyData; } void mitk::FiberBundle::ColorFibersByLength(bool opacity, bool weight_fibers, mitk::LookupTable::LookupTableType type) { if (m_MaxFiberLength<=0) return; auto numOfPoints = this->GetNumberOfPoints(); //colors and alpha value for each single point, RGBA = 4 components unsigned char rgba[4] = {0,0,0,0}; m_FiberColors = vtkSmartPointer<vtkUnsignedCharArray>::New(); m_FiberColors->Allocate(numOfPoints * 4); m_FiberColors->SetNumberOfComponents(4); m_FiberColors->SetName("FIBER_COLORS"); auto numOfFibers = m_FiberPolyData->GetNumberOfLines(); if (numOfFibers < 1) return; mitk::LookupTable::Pointer mitkLookup = mitk::LookupTable::New(); mitkLookup->SetType(type); if (type!=mitk::LookupTable::MULTILABEL) mitkLookup->GetVtkLookupTable()->SetTableRange(m_MinFiberLength, m_MaxFiberLength); unsigned int count = 0; for (unsigned int i=0; i<m_FiberPolyData->GetNumberOfCells(); i++) { vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); float l = m_FiberLengths.at(i)/m_MaxFiberLength; double color[3]; mitkLookup->GetColor(m_FiberLengths.at(i), color); for (int j=0; j<numPoints; j++) { rgba[0] = static_cast<unsigned char>(255.0 * color[0]); rgba[1] = static_cast<unsigned char>(255.0 * color[1]); rgba[2] = static_cast<unsigned char>(255.0 * color[2]); if (opacity) rgba[3] = static_cast<unsigned char>(255.0f * l); else rgba[3] = static_cast<unsigned char>(255.0); m_FiberColors->InsertTypedTuple(cell->GetPointId(j), rgba); count++; } if (weight_fibers) this->SetFiberWeight(i, m_FiberLengths.at(i)); } m_UpdateTime3D.Modified(); m_UpdateTime2D.Modified(); } void mitk::FiberBundle::ColorSinglePoint(int f_idx, int p_idx, double rgb[3]) { // vtkPoints* extrPoints = m_FiberPolyData->GetPoints(); // vtkIdType numOfPoints = 0; // if (extrPoints!=nullptr) // numOfPoints = extrPoints->GetNumberOfPoints(); // //colors and alpha value for each single point, RGBA = 4 components unsigned char rgba[4] = {0,0,0,0}; // m_FiberColors = vtkSmartPointer<vtkUnsignedCharArray>::New(); // m_FiberColors->Allocate(numOfPoints * 4); // m_FiberColors->SetNumberOfComponents(4); // m_FiberColors->SetName("FIBER_COLORS"); // auto numOfFibers = m_FiberPolyData->GetNumberOfLines(); // if (numOfFibers < 1) // return; // /* extract single fibers of fiberBundle */ // vtkCellArray* fiberList = m_FiberPolyData->GetLines(); // fiberList->InitTraversal(); // for (int fi=0; fi<numOfFibers; ++fi) // { // vtkIdType* idList; // contains the point id's of the line // vtkIdType num_points; // number of points for current line //// fiberList->GetNextCell(num_points, idList); // fiberList->GetCell(f_idx, num_points, idList); vtkCell* cell = m_FiberPolyData->GetCell(f_idx); // /* single fiber checkpoints: is number of points valid */ // if (p_idx < num_points) // { rgba[0] = static_cast<unsigned char>(255.0 * rgb[0]); rgba[1] = static_cast<unsigned char>(255.0 * rgb[1]); rgba[2] = static_cast<unsigned char>(255.0 * rgb[2]); rgba[3] = 255; m_FiberColors->InsertTypedTuple(cell->GetPointId(p_idx), rgba); // } // } m_UpdateTime3D.Modified(); m_UpdateTime2D.Modified(); } void mitk::FiberBundle::ColorFibersByOrientation() { //===== 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 //================================================= vtkPoints* extrPoints = m_FiberPolyData->GetPoints(); vtkIdType numOfPoints = 0; if (extrPoints!=nullptr) numOfPoints = extrPoints->GetNumberOfPoints(); //colors and alpha value for each single point, RGBA = 4 components unsigned char rgba[4] = {0,0,0,0}; m_FiberColors = vtkSmartPointer<vtkUnsignedCharArray>::New(); m_FiberColors->Allocate(numOfPoints * 4); m_FiberColors->SetNumberOfComponents(4); m_FiberColors->SetName("FIBER_COLORS"); auto numOfFibers = m_FiberPolyData->GetNumberOfLines(); if (numOfFibers < 1) return; /* extract single fibers of fiberBundle */ vtkCellArray* fiberList = m_FiberPolyData->GetLines(); fiberList->InitTraversal(); for (int fi=0; fi<numOfFibers; ++fi) { vtkIdType const* idList; // contains the point id's of the line vtkIdType pointsPerFiber; // number of points for current line fiberList->GetNextCell(pointsPerFiber, idList); /* single fiber checkpoints: is number of points valid */ if (pointsPerFiber > 1) { /* operate on points of single fiber */ for (int i=0; i <pointsPerFiber; ++i) { /* process all points elastV[0]ept starting and endpoint for calculating color value take current point, previous point and next point */ if (i<pointsPerFiber-1 && 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] = static_cast<unsigned char>(255.0 * std::fabs(diff[0])); rgba[1] = static_cast<unsigned char>(255.0 * std::fabs(diff[1])); rgba[2] = static_cast<unsigned char>(255.0 * std::fabs(diff[2])); rgba[3] = static_cast<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] = static_cast<unsigned char>(255.0 * std::fabs(diff1[0])); rgba[1] = static_cast<unsigned char>(255.0 * std::fabs(diff1[1])); rgba[2] = static_cast<unsigned char>(255.0 * std::fabs(diff1[2])); rgba[3] = static_cast<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] = static_cast<unsigned char>(255.0 * std::fabs(diff2[0])); rgba[1] = static_cast<unsigned char>(255.0 * std::fabs(diff2[1])); rgba[2] = static_cast<unsigned char>(255.0 * std::fabs(diff2[2])); rgba[3] = static_cast<unsigned char>(255.0); } m_FiberColors->InsertTypedTuple(idList[i], rgba); } } else if (pointsPerFiber == 1) { /* a single point does not define a fiber (use vertex mechanisms instead */ continue; } else { MITK_DEBUG << "Fiber with 0 points detected... please check your tractography algorithm!" ; continue; } } m_UpdateTime3D.Modified(); m_UpdateTime2D.Modified(); } void mitk::FiberBundle::ColorFibersByCurvature(bool opacity, bool weight_fibers, mitk::LookupTable::LookupTableType type) { double window = 5; //colors and alpha value for each single point, RGBA = 4 components unsigned char rgba[4] = {0,0,0,0}; m_FiberColors = vtkSmartPointer<vtkUnsignedCharArray>::New(); m_FiberColors->Allocate(m_FiberPolyData->GetNumberOfPoints() * 4); m_FiberColors->SetNumberOfComponents(4); m_FiberColors->SetName("FIBER_COLORS"); std::vector< double > values; double min = 1; double max = 0; MITK_INFO << "Coloring fibers by curvature"; boost::timer::progress_display disp(static_cast<unsigned long>(m_FiberPolyData->GetNumberOfCells())); for (int i=0; i<m_FiberPolyData->GetNumberOfCells(); i++) { ++disp; vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); double mean_curv = 0; // calculate curvatures for (int j=0; j<numPoints; j++) { double dist = 0; int c = j; std::vector< vnl_vector_fixed< double, 3 > > vectors; vnl_vector_fixed< double, 3 > meanV; meanV.fill(0.0); while(dist<window/2 && c>1) { double p1[3]; points->GetPoint(c-1, p1); double p2[3]; points->GetPoint(c, p2); vnl_vector_fixed< double, 3 > v; v[0] = p2[0]-p1[0]; v[1] = p2[1]-p1[1]; v[2] = p2[2]-p1[2]; dist += v.magnitude(); v.normalize(); vectors.push_back(v); meanV += v; c--; } c = j; dist = 0; while(dist<window/2 && c<numPoints-1) { double p1[3]; points->GetPoint(c, p1); double p2[3]; points->GetPoint(c+1, p2); vnl_vector_fixed< double, 3 > v; v[0] = p2[0]-p1[0]; v[1] = p2[1]-p1[1]; v[2] = p2[2]-p1[2]; dist += v.magnitude(); v.normalize(); vectors.push_back(v); meanV += v; c++; } meanV.normalize(); double dev = 0; for (unsigned int c=0; c<vectors.size(); c++) { double angle = dot_product(meanV, vectors.at(c)); if (angle>1.0) angle = 1.0; if (angle<-1.0) angle = -1.0; dev += acos(angle)*180/itk::Math::pi; } if (vectors.size()>0) dev /= vectors.size(); if (weight_fibers) mean_curv += dev; dev = 1.0-dev/180.0; values.push_back(dev); if (dev<min) min = dev; if (dev>max) max = dev; } if (weight_fibers) this->SetFiberWeight(i, mean_curv/numPoints); } mitk::LookupTable::Pointer mitkLookup = mitk::LookupTable::New(); mitkLookup->SetType(type); if (type!=mitk::LookupTable::MULTILABEL) mitkLookup->GetVtkLookupTable()->SetTableRange(min, max); unsigned int count = 0; for (int i=0; i<m_FiberPolyData->GetNumberOfCells(); i++) { vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); for (int j=0; j<numPoints; j++) { double color[3]; double dev = values.at(count); mitkLookup->GetColor(dev, color); rgba[0] = static_cast<unsigned char>(255.0 * color[0]); rgba[1] = static_cast<unsigned char>(255.0 * color[1]); rgba[2] = static_cast<unsigned char>(255.0 * color[2]); if (opacity) rgba[3] = static_cast<unsigned char>(255.0f * dev/max); else rgba[3] = static_cast<unsigned char>(255.0); m_FiberColors->InsertTypedTuple(cell->GetPointId(j), rgba); count++; } } m_UpdateTime3D.Modified(); m_UpdateTime2D.Modified(); } void mitk::FiberBundle::SetFiberOpacity(vtkDoubleArray* FAValArray) { for(long i=0; i<m_FiberColors->GetNumberOfTuples(); i++) { double faValue = FAValArray->GetValue(i); faValue = faValue * 255.0; m_FiberColors->SetComponent(i,3, static_cast<unsigned char>(faValue) ); } m_UpdateTime3D.Modified(); m_UpdateTime2D.Modified(); } void mitk::FiberBundle::ResetFiberOpacity() { for(long i=0; i<m_FiberColors->GetNumberOfTuples(); i++) m_FiberColors->SetComponent(i,3, 255.0 ); m_UpdateTime3D.Modified(); m_UpdateTime2D.Modified(); } void mitk::FiberBundle::ColorFibersByScalarMap(mitk::Image::Pointer FAimage, bool opacity, bool weight_fibers, mitk::LookupTable::LookupTableType type, double max_cap, bool interpolate) { if (FAimage->GetPixelType().GetComponentTypeAsString()=="unsigned char" || FAimage->GetPixelType().GetComponentTypeAsString()=="char" || FAimage->GetPixelType().GetComponentTypeAsString()=="long" || FAimage->GetPixelType().GetComponentTypeAsString()=="unsigned long" || FAimage->GetPixelType().GetComponentTypeAsString()=="short" || FAimage->GetPixelType().GetComponentTypeAsString()=="unsigned short" || FAimage->GetPixelType().GetComponentTypeAsString()=="unsigned int" || FAimage->GetPixelType().GetComponentTypeAsString()=="int") { typedef itk::Image<int, 3> ImageType; ImageType::Pointer itkImage = ImageType::New(); CastToItkImage(FAimage, itkImage); ColorFibersByScalarMap<int>(itkImage, opacity, weight_fibers, type, max_cap, interpolate ); } else { typedef itk::Image<float, 3> ImageType; ImageType::Pointer itkImage = ImageType::New(); CastToItkImage(FAimage, itkImage); ColorFibersByScalarMap<float>(itkImage, opacity, weight_fibers, type, max_cap, interpolate ); } m_UpdateTime3D.Modified(); m_UpdateTime2D.Modified(); } template <typename TPixel> void mitk::FiberBundle::ColorFibersByScalarMap(typename itk::Image<TPixel, 3>::Pointer image, bool opacity, bool weight_fibers, mitk::LookupTable::LookupTableType type, double max_cap, bool interpolate) { m_FiberColors = vtkSmartPointer<vtkUnsignedCharArray>::New(); m_FiberColors->Allocate(m_FiberPolyData->GetNumberOfPoints() * 4); m_FiberColors->SetNumberOfComponents(4); m_FiberColors->SetName("FIBER_COLORS"); unsigned char rgba[4] = {0,0,0,0}; vtkPoints* pointSet = m_FiberPolyData->GetPoints(); if (type==mitk::LookupTable::MULTILABEL) interpolate = false; auto interpolator = itk::LinearInterpolateImageFunction< itk::Image<TPixel, 3>, float >::New(); interpolator->SetInputImage(image); double min = 999999; double max = -999999; for (unsigned int i=0; i<m_NumFibers; i++) { vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); double mean_val = 0; for (int j=0; j<numPoints; j++) { double p[3]; points->GetPoint(j, p); auto pixelValue = mitk::imv::GetImageValue<TPixel>(mitk::imv::GetItkPoint(p), interpolate, interpolator); if (pixelValue>max) max = pixelValue; if (pixelValue<min) min = pixelValue; if (weight_fibers) mean_val += pixelValue; } if (weight_fibers) this->SetFiberWeight(i, mean_val/numPoints); } mitk::LookupTable::Pointer mitkLookup = mitk::LookupTable::New(); mitkLookup->SetType(type); if (type!=mitk::LookupTable::MULTILABEL) mitkLookup->GetVtkLookupTable()->SetTableRange(min, max*max_cap); for(long i=0; i<m_FiberPolyData->GetNumberOfPoints(); ++i) { itk::Point<float, 3> px; px[0] = pointSet->GetPoint(i)[0]; px[1] = pointSet->GetPoint(i)[1]; px[2] = pointSet->GetPoint(i)[2]; auto pixelValue = mitk::imv::GetImageValue<TPixel>(px, interpolate, interpolator); double color[3]; mitkLookup->GetColor(pixelValue, color); rgba[0] = static_cast<unsigned char>(255.0 * color[0]); rgba[1] = static_cast<unsigned char>(255.0 * color[1]); rgba[2] = static_cast<unsigned char>(255.0 * color[2]); if (opacity) rgba[3] = static_cast<unsigned char>(255.0 * pixelValue); else rgba[3] = static_cast<unsigned char>(255.0); m_FiberColors->InsertTypedTuple(i, rgba); } m_UpdateTime3D.Modified(); m_UpdateTime2D.Modified(); } void mitk::FiberBundle::ColorFibersByFiberWeights(bool opacity, mitk::LookupTable::LookupTableType type) { m_FiberColors = vtkSmartPointer<vtkUnsignedCharArray>::New(); m_FiberColors->Allocate(m_FiberPolyData->GetNumberOfPoints() * 4); m_FiberColors->SetNumberOfComponents(4); m_FiberColors->SetName("FIBER_COLORS"); unsigned char rgba[4] = {0,0,0,0}; unsigned int counter = 0; float max = -999999; float min = 999999; for (unsigned int i=0; i<m_NumFibers; i++) { float weight = this->GetFiberWeight(i); if (weight>max) max = weight; if (weight<min) min = weight; } if (fabs(max-min)<0.00001f) { max = 1; min = 0; } mitk::LookupTable::Pointer mitkLookup = mitk::LookupTable::New(); mitkLookup->SetType(type); if (type!=mitk::LookupTable::MULTILABEL) mitkLookup->GetVtkLookupTable()->SetTableRange(min, max); for (unsigned int i=0; i<m_NumFibers; i++) { vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); auto weight = this->GetFiberWeight(i); double color[3]; mitkLookup->GetColor(weight, color); for (int j=0; j<numPoints; j++) { rgba[0] = static_cast<unsigned char>(255.0 * color[0]); rgba[1] = static_cast<unsigned char>(255.0 * color[1]); rgba[2] = static_cast<unsigned char>(255.0 * color[2]); if (opacity) rgba[3] = static_cast<unsigned char>(255.0f * weight/max); else rgba[3] = static_cast<unsigned char>(255.0); m_FiberColors->InsertTypedTuple(counter, rgba); counter++; } } m_UpdateTime3D.Modified(); m_UpdateTime2D.Modified(); } +void mitk::FiberBundle::SetSingleFiberColor(float r, float g, float b, unsigned int cellId, float alpha) +{ +// if (m_FiberColors==nullptr) + m_FiberColors = vtkSmartPointer<vtkUnsignedCharArray>::New(); + m_FiberColors->Allocate(m_FiberPolyData->GetNumberOfPoints() * 4); + m_FiberColors->SetNumberOfComponents(4); + m_FiberColors->SetName("FIBER_COLORS"); + +// MITK_INFO << color->GetNumberOfTuples(); +// MITK_INFO << m_FiberColors->GetNumberOfTuples(); + + unsigned char rgba[4] = {0,0,0,0}; + unsigned int counter = 0; + + + for (unsigned int i=0; i<m_FiberPolyData->GetNumberOfCells(); i++) + { + vtkCell* cell = m_FiberPolyData->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + + if (i==cellId) + { + for (int j=0; j<numPoints; j++) + { + rgba[0] = static_cast<unsigned char>(r); + rgba[1] = static_cast<unsigned char>(b); + rgba[2] = static_cast<unsigned char>(g); + rgba[3] = static_cast<unsigned char>(alpha); +// m_FiberColors->InsertTypedTuple(j, rgba); + + m_FiberColors->InsertTypedTuple(counter, rgba); + counter++; + } + } + else { + for (int j=0; j<numPoints; j++) + { + rgba[0] = static_cast<unsigned char>(255); + rgba[1] = static_cast<unsigned char>(255); + rgba[2] = static_cast<unsigned char>(255); + rgba[3] = static_cast<unsigned char>(alpha); +// m_FiberColors->InsertTypedTuple(j, rgba); + + m_FiberColors->InsertTypedTuple(counter, rgba); + counter++; + } + } + + } + +// MITK_INFO << m_FiberColors->GetNumberOfTuples(); + m_UpdateTime3D.Modified(); + m_UpdateTime2D.Modified(); +} + void mitk::FiberBundle::SetFiberColors(float r, float g, float b, float alpha) { m_FiberColors = vtkSmartPointer<vtkUnsignedCharArray>::New(); m_FiberColors->Allocate(m_FiberPolyData->GetNumberOfPoints() * 4); m_FiberColors->SetNumberOfComponents(4); m_FiberColors->SetName("FIBER_COLORS"); unsigned char rgba[4] = {0,0,0,0}; for(long i=0; i<m_FiberPolyData->GetNumberOfPoints(); ++i) { rgba[0] = static_cast<unsigned char>(r); rgba[1] = static_cast<unsigned char>(g); rgba[2] = static_cast<unsigned char>(b); rgba[3] = static_cast<unsigned char>(alpha); m_FiberColors->InsertTypedTuple(i, rgba); } m_UpdateTime3D.Modified(); m_UpdateTime2D.Modified(); } void mitk::FiberBundle::GenerateFiberIds() { if (m_FiberPolyData == nullptr) return; vtkSmartPointer<vtkIdFilter> idFiberFilter = vtkSmartPointer<vtkIdFilter>::New(); idFiberFilter->SetInputData(m_FiberPolyData); idFiberFilter->CellIdsOn(); // idFiberFilter->PointIdsOn(); // point id's are not needed idFiberFilter->SetCellIdsArrayName(FIBER_ID_ARRAY); idFiberFilter->FieldDataOn(); idFiberFilter->Update(); m_FiberIdDataSet = idFiberFilter->GetOutput(); } float mitk::FiberBundle::GetNumEpFractionInMask(ItkUcharImgType* mask, bool different_label) { vtkSmartPointer<vtkPolyData> PolyData = m_FiberPolyData; MITK_INFO << "Calculating EP-Fraction"; boost::timer::progress_display disp(m_NumFibers); unsigned int in_mask = 0; for (unsigned int i=0; i<m_NumFibers; i++) { ++disp; vtkCell* cell = PolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); itk::Point<float, 3> startVertex =mitk::imv::GetItkPoint(points->GetPoint(0)); itk::Index<3> startIndex; mask->TransformPhysicalPointToIndex(startVertex, startIndex); itk::Point<float, 3> endVertex =mitk::imv::GetItkPoint(points->GetPoint(numPoints-1)); itk::Index<3> endIndex; mask->TransformPhysicalPointToIndex(endVertex, endIndex); if (mask->GetLargestPossibleRegion().IsInside(startIndex) && mask->GetLargestPossibleRegion().IsInside(endIndex)) { float v1 = mask->GetPixel(startIndex); if (v1 < 0.5f) continue; float v2 = mask->GetPixel(startIndex); if (v2 < 0.5f) continue; if (!different_label) ++in_mask; else if (fabs(v1-v2)>0.00001f) ++in_mask; } } return float(in_mask)/m_NumFibers; } std::tuple<float, float> mitk::FiberBundle::GetDirectionalOverlap(ItkUcharImgType* mask, mitk::PeakImage::ItkPeakImageType* peak_image) { vtkSmartPointer<vtkPolyData> PolyData = m_FiberPolyData; MITK_INFO << "Calculating overlap"; auto spacing = mask->GetSpacing(); boost::timer::progress_display disp(m_NumFibers); double length_sum = 0; double in_mask_length = 0; double aligned_length = 0; for (unsigned int i=0; i<m_NumFibers; i++) { ++disp; vtkCell* cell = PolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); for (int j=0; j<numPoints-1; j++) { itk::Point<float, 3> startVertex =mitk::imv::GetItkPoint(points->GetPoint(j)); itk::Index<3> startIndex; itk::ContinuousIndex<float, 3> startIndexCont; mask->TransformPhysicalPointToIndex(startVertex, startIndex); mask->TransformPhysicalPointToContinuousIndex(startVertex, startIndexCont); itk::Point<float, 3> endVertex =mitk::imv::GetItkPoint(points->GetPoint(j + 1)); itk::Index<3> endIndex; itk::ContinuousIndex<float, 3> endIndexCont; mask->TransformPhysicalPointToIndex(endVertex, endIndex); mask->TransformPhysicalPointToContinuousIndex(endVertex, endIndexCont); vnl_vector_fixed< float, 3 > fdir; fdir[0] = endVertex[0] - startVertex[0]; fdir[1] = endVertex[1] - startVertex[1]; fdir[2] = endVertex[2] - startVertex[2]; fdir.normalize(); std::vector< std::pair< itk::Index<3>, double > > segments = mitk::imv::IntersectImage(spacing, startIndex, endIndex, startIndexCont, endIndexCont); for (std::pair< itk::Index<3>, double > segment : segments) { if ( mask->GetLargestPossibleRegion().IsInside(segment.first) && mask->GetPixel(segment.first) > 0 ) { in_mask_length += segment.second; mitk::PeakImage::ItkPeakImageType::IndexType idx4; idx4[0] = segment.first[0]; idx4[1] = segment.first[1]; idx4[2] = segment.first[2]; vnl_vector_fixed< float, 3 > peak; idx4[3] = 0; peak[0] = peak_image->GetPixel(idx4); idx4[3] = 1; peak[1] = peak_image->GetPixel(idx4); idx4[3] = 2; peak[2] = peak_image->GetPixel(idx4); if (std::isnan(peak[0]) || std::isnan(peak[1]) || std::isnan(peak[2]) || peak.magnitude()<0.0001f) continue; peak.normalize(); double f = 1.0 - std::acos(std::fabs(static_cast<double>(dot_product(fdir, peak)))) * 2.0/itk::Math::pi; aligned_length += segment.second * f; } length_sum += segment.second; } } } if (length_sum<=0.0001) { MITK_INFO << "Fiber length sum is zero!"; return std::make_tuple(0,0); } return std::make_tuple(aligned_length/length_sum, in_mask_length/length_sum); } float mitk::FiberBundle::GetOverlap(ItkUcharImgType* mask) { vtkSmartPointer<vtkPolyData> PolyData = m_FiberPolyData; MITK_INFO << "Calculating overlap"; auto spacing = mask->GetSpacing(); boost::timer::progress_display disp(m_NumFibers); double length_sum = 0; double in_mask_length = 0; for (unsigned int i=0; i<m_NumFibers; i++) { ++disp; vtkCell* cell = PolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); for (int j=0; j<numPoints-1; j++) { itk::Point<float, 3> startVertex =mitk::imv::GetItkPoint(points->GetPoint(j)); itk::Index<3> startIndex; itk::ContinuousIndex<float, 3> startIndexCont; mask->TransformPhysicalPointToIndex(startVertex, startIndex); mask->TransformPhysicalPointToContinuousIndex(startVertex, startIndexCont); itk::Point<float, 3> endVertex =mitk::imv::GetItkPoint(points->GetPoint(j + 1)); itk::Index<3> endIndex; itk::ContinuousIndex<float, 3> endIndexCont; mask->TransformPhysicalPointToIndex(endVertex, endIndex); mask->TransformPhysicalPointToContinuousIndex(endVertex, endIndexCont); std::vector< std::pair< itk::Index<3>, double > > segments = mitk::imv::IntersectImage(spacing, startIndex, endIndex, startIndexCont, endIndexCont); for (std::pair< itk::Index<3>, double > segment : segments) { if ( mask->GetLargestPossibleRegion().IsInside(segment.first) && mask->GetPixel(segment.first) > 0 ) in_mask_length += segment.second; length_sum += segment.second; } } } if (length_sum<=0.000001) { MITK_INFO << "Fiber length sum is zero!"; return 0; } return static_cast<float>(in_mask_length/length_sum); } mitk::FiberBundle::Pointer mitk::FiberBundle::RemoveFibersOutside(ItkUcharImgType* mask, bool invert) { vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New(); vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New(); std::vector< float > fib_weights; MITK_INFO << "Cutting fibers"; boost::timer::progress_display disp(m_NumFibers); for (unsigned int i=0; i<m_NumFibers; i++) { ++disp; vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); int newNumPoints = 0; if (numPoints>1) { for (int j=0; j<numPoints; j++) { itk::Point<float, 3> itkP =mitk::imv::GetItkPoint(points->GetPoint(j)); itk::Index<3> idx; mask->TransformPhysicalPointToIndex(itkP, idx); bool inside = false; if ( mask->GetLargestPossibleRegion().IsInside(idx) && mask->GetPixel(idx)!=0 ) inside = true; if (inside && !invert) { vtkIdType id = vtkNewPoints->InsertNextPoint(itkP.GetDataPointer()); container->GetPointIds()->InsertNextId(id); newNumPoints++; } else if ( !inside && invert ) { vtkIdType id = vtkNewPoints->InsertNextPoint(itkP.GetDataPointer()); container->GetPointIds()->InsertNextId(id); newNumPoints++; } else if (newNumPoints>1) { fib_weights.push_back(this->GetFiberWeight(i)); vtkNewCells->InsertNextCell(container); newNumPoints = 0; container = vtkSmartPointer<vtkPolyLine>::New(); } else { newNumPoints = 0; container = vtkSmartPointer<vtkPolyLine>::New(); } } if (newNumPoints>1) { fib_weights.push_back(this->GetFiberWeight(i)); vtkNewCells->InsertNextCell(container); } } } vtkSmartPointer<vtkFloatArray> newFiberWeights = vtkSmartPointer<vtkFloatArray>::New(); newFiberWeights->SetName("FIBER_WEIGHTS"); newFiberWeights->SetNumberOfValues(static_cast<vtkIdType>(fib_weights.size())); if (vtkNewCells->GetNumberOfCells()<=0) return nullptr; for (unsigned int i=0; i<newFiberWeights->GetNumberOfValues(); i++) newFiberWeights->SetValue(i, fib_weights.at(i)); // vtkSmartPointer<vtkUnsignedCharArray> newFiberColors = vtkSmartPointer<vtkUnsignedCharArray>::New(); // newFiberColors->Allocate(m_FiberPolyData->GetNumberOfPoints() * 4); // newFiberColors->SetNumberOfComponents(4); // newFiberColors->SetName("FIBER_COLORS"); // unsigned char rgba[4] = {0,0,0,0}; // for(long i=0; i<m_FiberPolyData->GetNumberOfPoints(); ++i) // { // rgba[0] = (unsigned char) r; // rgba[1] = (unsigned char) g; // rgba[2] = (unsigned char) b; // rgba[3] = (unsigned char) alpha; // m_FiberColors->InsertTypedTuple(i, rgba); // } vtkSmartPointer<vtkPolyData> newPolyData = vtkSmartPointer<vtkPolyData>::New(); newPolyData->SetPoints(vtkNewPoints); newPolyData->SetLines(vtkNewCells); mitk::FiberBundle::Pointer newFib = mitk::FiberBundle::New(newPolyData); newFib->SetFiberWeights(newFiberWeights); // newFib->Compress(0.1); newFib->SetTrackVisHeader(this->GetTrackVisHeader()); return newFib; } mitk::FiberBundle::Pointer mitk::FiberBundle::ExtractFiberSubset(DataNode* roi, DataStorage* storage) { if (roi==nullptr || !(dynamic_cast<PlanarFigure*>(roi->GetData()) || dynamic_cast<PlanarFigureComposite*>(roi->GetData())) ) return nullptr; std::vector<unsigned int> tmp = ExtractFiberIdSubset(roi, storage); if (tmp.size()<=0) return mitk::FiberBundle::New(); vtkSmartPointer<vtkFloatArray> weights = vtkSmartPointer<vtkFloatArray>::New(); vtkSmartPointer<vtkPolyData> pTmp = GeneratePolyDataByIds(tmp, weights); mitk::FiberBundle::Pointer fib = mitk::FiberBundle::New(pTmp); fib->SetFiberWeights(weights); fib->SetTrackVisHeader(this->GetTrackVisHeader()); return fib; } std::vector<unsigned int> mitk::FiberBundle::ExtractFiberIdSubset(DataNode *roi, DataStorage* storage) { std::vector<unsigned int> result; if (roi==nullptr || roi->GetData()==nullptr) return result; mitk::PlanarFigureComposite::Pointer pfc = dynamic_cast<mitk::PlanarFigureComposite*>(roi->GetData()); if (!pfc.IsNull()) // handle composite { DataStorage::SetOfObjects::ConstPointer children = storage->GetDerivations(roi); if (children->size()==0) return result; switch (pfc->getOperationType()) { case 0: // AND { MITK_INFO << "AND"; result = this->ExtractFiberIdSubset(children->ElementAt(0), storage); std::vector<unsigned int>::iterator it; for (unsigned int i=1; i<children->Size(); ++i) { std::vector<unsigned int> inRoi = this->ExtractFiberIdSubset(children->ElementAt(i), storage); std::vector<unsigned int> rest(std::min(result.size(),inRoi.size())); it = std::set_intersection(result.begin(), result.end(), inRoi.begin(), inRoi.end(), rest.begin() ); rest.resize( static_cast<unsigned int>(it - rest.begin()) ); result = rest; } break; } case 1: // OR { MITK_INFO << "OR"; result = ExtractFiberIdSubset(children->ElementAt(0), storage); std::vector<unsigned int>::iterator it; for (unsigned int i=1; i<children->Size(); ++i) { it = result.end(); std::vector<unsigned int> inRoi = ExtractFiberIdSubset(children->ElementAt(i), storage); result.insert(it, inRoi.begin(), inRoi.end()); } // remove duplicates sort(result.begin(), result.end()); it = unique(result.begin(), result.end()); result.resize( static_cast<unsigned int>(it - result.begin()) ); break; } case 2: // NOT { MITK_INFO << "NOT"; for(unsigned int i=0; i<this->GetNumFibers(); i++) result.push_back(i); std::vector<unsigned int>::iterator it; for (unsigned int i=0; i<children->Size(); ++i) { std::vector<unsigned int> inRoi = ExtractFiberIdSubset(children->ElementAt(i), storage); std::vector<unsigned int> rest(result.size()-inRoi.size()); it = std::set_difference(result.begin(), result.end(), inRoi.begin(), inRoi.end(), rest.begin() ); rest.resize( static_cast<unsigned int>(it - rest.begin()) ); result = rest; } break; } } } else if ( dynamic_cast<mitk::PlanarFigure*>(roi->GetData()) ) // actual extraction { if ( dynamic_cast<mitk::PlanarPolygon*>(roi->GetData()) ) { mitk::PlanarFigure::Pointer planarPoly = dynamic_cast<mitk::PlanarFigure*>(roi->GetData()); //create vtkPolygon using controlpoints from planarFigure polygon vtkSmartPointer<vtkPolygon> polygonVtk = vtkSmartPointer<vtkPolygon>::New(); for (unsigned int i=0; i<planarPoly->GetNumberOfControlPoints(); ++i) { itk::Point<double,3> p = planarPoly->GetWorldControlPoint(i); vtkIdType id = polygonVtk->GetPoints()->InsertNextPoint(p[0], p[1], p[2] ); polygonVtk->GetPointIds()->InsertNextId(id); } MITK_INFO << "Extracting with polygon"; boost::timer::progress_display disp(m_NumFibers); for (unsigned int i=0; i<m_NumFibers; i++) { ++disp ; vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); for (int j=0; j<numPoints-1; j++) { // Inputs double p1[3] = {0,0,0}; points->GetPoint(j, p1); double p2[3] = {0,0,0}; points->GetPoint(j+1, p2); double tolerance = 0.001; // Outputs double t = 0; // Parametric coordinate of intersection (0 (corresponding to p1) to 1 (corresponding to p2)) double x[3] = {0,0,0}; // The coordinate of the intersection double pcoords[3] = {0,0,0}; int subId = 0; int iD = polygonVtk->IntersectWithLine(p1, p2, tolerance, t, x, pcoords, subId); if (iD!=0) { result.push_back(i); break; } } } } else if ( dynamic_cast<mitk::PlanarCircle*>(roi->GetData()) ) { mitk::PlanarFigure::Pointer planarFigure = dynamic_cast<mitk::PlanarFigure*>(roi->GetData()); Vector3D planeNormal = planarFigure->GetPlaneGeometry()->GetNormal(); planeNormal.Normalize(); //calculate circle radius mitk::Point3D V1w = planarFigure->GetWorldControlPoint(0); //centerPoint mitk::Point3D V2w = planarFigure->GetWorldControlPoint(1); //radiusPoint double radius = V1w.EuclideanDistanceTo(V2w); radius *= radius; MITK_INFO << "Extracting with circle"; boost::timer::progress_display disp(m_NumFibers); for (unsigned int i=0; i<m_NumFibers; i++) { ++disp ; vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); for (int j=0; j<numPoints-1; j++) { // Inputs double p1[3] = {0,0,0}; points->GetPoint(j, p1); double p2[3] = {0,0,0}; points->GetPoint(j+1, p2); // Outputs double t = 0; // Parametric coordinate of intersection (0 (corresponding to p1) to 1 (corresponding to p2)) double x[3] = {0,0,0}; // The coordinate of the intersection int iD = vtkPlane::IntersectWithLine(p1,p2,planeNormal.GetDataPointer(),V1w.GetDataPointer(),t,x); if (iD!=0) { double dist = (x[0]-V1w[0])*(x[0]-V1w[0])+(x[1]-V1w[1])*(x[1]-V1w[1])+(x[2]-V1w[2])*(x[2]-V1w[2]); if( dist <= radius) { result.push_back(i); break; } } } } } return result; } return result; } void mitk::FiberBundle::UpdateFiberGeometry() { vtkSmartPointer<vtkCleanPolyData> cleaner = vtkSmartPointer<vtkCleanPolyData>::New(); cleaner->SetInputData(m_FiberPolyData); cleaner->PointMergingOff(); cleaner->Update(); m_FiberPolyData = cleaner->GetOutput(); m_FiberLengths.clear(); m_MeanFiberLength = 0; m_MedianFiberLength = 0; m_LengthStDev = 0; m_NumFibers = static_cast<unsigned int>(m_FiberPolyData->GetNumberOfCells()); if (m_FiberColors==nullptr || m_FiberColors->GetNumberOfTuples()!=m_FiberPolyData->GetNumberOfPoints()) this->ColorFibersByOrientation(); if (m_FiberWeights->GetNumberOfValues()!=m_NumFibers) { m_FiberWeights = vtkSmartPointer<vtkFloatArray>::New(); m_FiberWeights->SetName("FIBER_WEIGHTS"); m_FiberWeights->SetNumberOfValues(m_NumFibers); this->SetFiberWeights(1); } if (m_NumFibers<=0) // no fibers present; apply default geometry { m_MinFiberLength = 0; m_MaxFiberLength = 0; mitk::Geometry3D::Pointer geometry = mitk::Geometry3D::New(); geometry->SetImageGeometry(false); float b[] = {0, 1, 0, 1, 0, 1}; geometry->SetFloatBounds(b); SetGeometry(geometry); return; } double b[6]; m_FiberPolyData->GetBounds(b); // calculate statistics for (int i=0; i<m_FiberPolyData->GetNumberOfCells(); i++) { vtkCell* cell = m_FiberPolyData->GetCell(i); auto p = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); float length = 0; for (int j=0; j<p-1; j++) { double p1[3]; points->GetPoint(j, p1); double p2[3]; points->GetPoint(j+1, p2); double dist = std::sqrt((p1[0]-p2[0])*(p1[0]-p2[0])+(p1[1]-p2[1])*(p1[1]-p2[1])+(p1[2]-p2[2])*(p1[2]-p2[2])); length += static_cast<float>(dist); } m_FiberLengths.push_back(length); m_MeanFiberLength += length; if (i==0) { m_MinFiberLength = length; m_MaxFiberLength = length; } else { if (length<m_MinFiberLength) m_MinFiberLength = length; if (length>m_MaxFiberLength) m_MaxFiberLength = length; } } m_MeanFiberLength /= m_NumFibers; std::vector< float > sortedLengths = m_FiberLengths; std::sort(sortedLengths.begin(), sortedLengths.end()); for (unsigned int i=0; i<m_NumFibers; i++) m_LengthStDev += (m_MeanFiberLength-sortedLengths.at(i))*(m_MeanFiberLength-sortedLengths.at(i)); if (m_NumFibers>1) m_LengthStDev /= (m_NumFibers-1); else m_LengthStDev = 0; m_LengthStDev = std::sqrt(m_LengthStDev); m_MedianFiberLength = sortedLengths.at(m_NumFibers/2); mitk::Geometry3D::Pointer geometry = mitk::Geometry3D::New(); geometry->SetFloatBounds(b); this->SetGeometry(geometry); GetTrackVisHeader(); m_UpdateTime3D.Modified(); m_UpdateTime2D.Modified(); } float mitk::FiberBundle::GetFiberWeight(unsigned int fiber) const { return m_FiberWeights->GetValue(fiber); } void mitk::FiberBundle::SetFiberWeights(float newWeight) { for (int i=0; i<m_FiberWeights->GetNumberOfValues(); i++) m_FiberWeights->SetValue(i, newWeight); } void mitk::FiberBundle::SetFiberWeights(vtkSmartPointer<vtkFloatArray> weights) { if (m_NumFibers!=weights->GetNumberOfValues()) { MITK_INFO << "Weights array not equal to number of fibers! " << weights->GetNumberOfValues() << " vs " << m_NumFibers; return; } for (int i=0; i<weights->GetNumberOfValues(); i++) m_FiberWeights->SetValue(i, weights->GetValue(i)); m_FiberWeights->SetName("FIBER_WEIGHTS"); } void mitk::FiberBundle::SetFiberWeight(unsigned int fiber, float weight) { m_FiberWeights->SetValue(fiber, weight); } void mitk::FiberBundle::SetFiberColors(vtkSmartPointer<vtkUnsignedCharArray> fiberColors) { for(long i=0; i<m_FiberPolyData->GetNumberOfPoints(); ++i) { unsigned char source[4] = {0,0,0,0}; fiberColors->GetTypedTuple(i, source); unsigned char target[4] = {0,0,0,0}; target[0] = source[0]; target[1] = source[1]; target[2] = source[2]; target[3] = source[3]; m_FiberColors->InsertTypedTuple(i, target); } m_UpdateTime3D.Modified(); m_UpdateTime2D.Modified(); } itk::Matrix< double, 3, 3 > mitk::FiberBundle::TransformMatrix(itk::Matrix< double, 3, 3 > m, double rx, double ry, double rz) { rx = rx*itk::Math::pi/180; ry = ry*itk::Math::pi/180; rz = rz*itk::Math::pi/180; itk::Matrix< double, 3, 3 > rotX; rotX.SetIdentity(); rotX[1][1] = cos(rx); rotX[2][2] = rotX[1][1]; rotX[1][2] = -sin(rx); rotX[2][1] = -rotX[1][2]; itk::Matrix< double, 3, 3 > rotY; rotY.SetIdentity(); rotY[0][0] = cos(ry); rotY[2][2] = rotY[0][0]; rotY[0][2] = sin(ry); rotY[2][0] = -rotY[0][2]; itk::Matrix< double, 3, 3 > rotZ; rotZ.SetIdentity(); rotZ[0][0] = cos(rz); rotZ[1][1] = rotZ[0][0]; rotZ[0][1] = -sin(rz); rotZ[1][0] = -rotZ[0][1]; itk::Matrix< double, 3, 3 > rot = rotZ*rotY*rotX; m = rot*m; return m; } void mitk::FiberBundle::TransformFibers(itk::ScalableAffineTransform< mitk::ScalarType >::Pointer transform) { vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New(); vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New(); for (unsigned int i=0; i<m_NumFibers; i++) { vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); for (int j=0; j<numPoints; j++) { itk::Point<float, 3> p =mitk::imv::GetItkPoint(points->GetPoint(j)); p = transform->TransformPoint(p); vtkIdType id = vtkNewPoints->InsertNextPoint(p.GetDataPointer()); container->GetPointIds()->InsertNextId(id); } vtkNewCells->InsertNextCell(container); } m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New(); m_FiberPolyData->SetPoints(vtkNewPoints); m_FiberPolyData->SetLines(vtkNewCells); this->SetFiberPolyData(m_FiberPolyData, true); } void mitk::FiberBundle::TransformFibers(double rx, double ry, double rz, double tx, double ty, double tz) { vnl_matrix_fixed< double, 3, 3 > rot = mitk::imv::GetRotationMatrixVnl(rx, ry, rz); mitk::BaseGeometry::Pointer geom = this->GetGeometry(); mitk::Point3D center = geom->GetCenter(); vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New(); vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New(); for (unsigned int i=0; i<m_NumFibers; i++) { vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); for (int j=0; j<numPoints; j++) { double* p = points->GetPoint(j); vnl_vector_fixed< double, 3 > dir; dir[0] = p[0]-center[0]; dir[1] = p[1]-center[1]; dir[2] = p[2]-center[2]; dir = rot*dir; dir[0] += center[0]+tx; dir[1] += center[1]+ty; dir[2] += center[2]+tz; vtkIdType id = vtkNewPoints->InsertNextPoint(dir.data_block()); container->GetPointIds()->InsertNextId(id); } vtkNewCells->InsertNextCell(container); } m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New(); m_FiberPolyData->SetPoints(vtkNewPoints); m_FiberPolyData->SetLines(vtkNewCells); this->SetFiberPolyData(m_FiberPolyData, true); } void mitk::FiberBundle::RotateAroundAxis(double x, double y, double z) { x = x*itk::Math::pi/180; y = y*itk::Math::pi/180; z = z*itk::Math::pi/180; vnl_matrix_fixed< double, 3, 3 > rotX; rotX.set_identity(); rotX[1][1] = cos(x); rotX[2][2] = rotX[1][1]; rotX[1][2] = -sin(x); rotX[2][1] = -rotX[1][2]; vnl_matrix_fixed< double, 3, 3 > rotY; rotY.set_identity(); rotY[0][0] = cos(y); rotY[2][2] = rotY[0][0]; rotY[0][2] = sin(y); rotY[2][0] = -rotY[0][2]; vnl_matrix_fixed< double, 3, 3 > rotZ; rotZ.set_identity(); rotZ[0][0] = cos(z); rotZ[1][1] = rotZ[0][0]; rotZ[0][1] = -sin(z); rotZ[1][0] = -rotZ[0][1]; mitk::BaseGeometry::Pointer geom = this->GetGeometry(); mitk::Point3D center = geom->GetCenter(); vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New(); vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New(); for (unsigned int i=0; i<m_NumFibers; i++) { vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); for (int j=0; j<numPoints; j++) { double* p = points->GetPoint(j); vnl_vector_fixed< double, 3 > dir; dir[0] = p[0]-center[0]; dir[1] = p[1]-center[1]; dir[2] = p[2]-center[2]; dir = rotZ*rotY*rotX*dir; dir[0] += center[0]; dir[1] += center[1]; dir[2] += center[2]; vtkIdType id = vtkNewPoints->InsertNextPoint(dir.data_block()); container->GetPointIds()->InsertNextId(id); } vtkNewCells->InsertNextCell(container); } m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New(); m_FiberPolyData->SetPoints(vtkNewPoints); m_FiberPolyData->SetLines(vtkNewCells); this->SetFiberPolyData(m_FiberPolyData, true); } void mitk::FiberBundle::ScaleFibers(double x, double y, double z, bool subtractCenter) { MITK_INFO << "Scaling fibers"; boost::timer::progress_display disp(m_NumFibers); mitk::BaseGeometry* geom = this->GetGeometry(); mitk::Point3D c = geom->GetCenter(); vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New(); vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New(); for (unsigned int i=0; i<m_NumFibers; i++) { ++disp ; vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); for (int j=0; j<numPoints; j++) { double* p = points->GetPoint(j); if (subtractCenter) { p[0] -= c[0]; p[1] -= c[1]; p[2] -= c[2]; } p[0] *= x; p[1] *= y; p[2] *= z; if (subtractCenter) { p[0] += c[0]; p[1] += c[1]; p[2] += c[2]; } vtkIdType id = vtkNewPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } vtkNewCells->InsertNextCell(container); } m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New(); m_FiberPolyData->SetPoints(vtkNewPoints); m_FiberPolyData->SetLines(vtkNewCells); this->SetFiberPolyData(m_FiberPolyData, true); } void mitk::FiberBundle::TranslateFibers(double x, double y, double z) { vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New(); vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New(); for (unsigned int i=0; i<m_NumFibers; i++) { vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); for (int j=0; j<numPoints; j++) { double* p = points->GetPoint(j); p[0] += x; p[1] += y; p[2] += z; vtkIdType id = vtkNewPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } vtkNewCells->InsertNextCell(container); } m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New(); m_FiberPolyData->SetPoints(vtkNewPoints); m_FiberPolyData->SetLines(vtkNewCells); this->SetFiberPolyData(m_FiberPolyData, true); } void mitk::FiberBundle::MirrorFibers(unsigned int axis) { if (axis>2) return; MITK_INFO << "Mirroring fibers"; boost::timer::progress_display disp(m_NumFibers); vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New(); vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New(); for (unsigned int i=0; i<m_NumFibers; i++) { ++disp; vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); for (int j=0; j<numPoints; j++) { double* p = points->GetPoint(j); p[axis] = -p[axis]; vtkIdType id = vtkNewPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } vtkNewCells->InsertNextCell(container); } m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New(); m_FiberPolyData->SetPoints(vtkNewPoints); m_FiberPolyData->SetLines(vtkNewCells); this->SetFiberPolyData(m_FiberPolyData, true); } void mitk::FiberBundle::RemoveDir(vnl_vector_fixed<double,3> dir, double threshold) { dir.normalize(); vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New(); vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New(); boost::timer::progress_display disp(static_cast<unsigned long>(m_FiberPolyData->GetNumberOfCells())); for (int i=0; i<m_FiberPolyData->GetNumberOfCells(); i++) { ++disp ; vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); // calculate curvatures vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); bool discard = false; for (int j=0; j<numPoints-1; j++) { double p1[3]; points->GetPoint(j, p1); double p2[3]; points->GetPoint(j+1, p2); vnl_vector_fixed< double, 3 > v1; v1[0] = p2[0]-p1[0]; v1[1] = p2[1]-p1[1]; v1[2] = p2[2]-p1[2]; if (v1.magnitude()>0.001) { v1.normalize(); if (fabs(dot_product(v1,dir))>threshold) { discard = true; break; } } } if (!discard) { for (int j=0; j<numPoints; j++) { double p1[3]; points->GetPoint(j, p1); vtkIdType id = vtkNewPoints->InsertNextPoint(p1); container->GetPointIds()->InsertNextId(id); } vtkNewCells->InsertNextCell(container); } } m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New(); m_FiberPolyData->SetPoints(vtkNewPoints); m_FiberPolyData->SetLines(vtkNewCells); this->SetFiberPolyData(m_FiberPolyData, true); // UpdateColorCoding(); // UpdateFiberGeometry(); } bool mitk::FiberBundle::ApplyCurvatureThreshold(float minRadius, bool deleteFibers) { if (minRadius<0) return true; vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New(); vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New(); MITK_INFO << "Applying curvature threshold"; boost::timer::progress_display disp(static_cast<unsigned long>(m_FiberPolyData->GetNumberOfCells())); for (int i=0; i<m_FiberPolyData->GetNumberOfCells(); i++) { ++disp ; vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); // calculate curvatures vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); for (int j=0; j<numPoints-2; j++) { double p1[3]; points->GetPoint(j, p1); double p2[3]; points->GetPoint(j+1, p2); double p3[3]; points->GetPoint(j+2, p3); vnl_vector_fixed< float, 3 > v1, v2, v3; v1[0] = static_cast<float>(p2[0]-p1[0]); v1[1] = static_cast<float>(p2[1]-p1[1]); v1[2] = static_cast<float>(p2[2]-p1[2]); v2[0] = static_cast<float>(p3[0]-p2[0]); v2[1] = static_cast<float>(p3[1]-p2[1]); v2[2] = static_cast<float>(p3[2]-p2[2]); v3[0] = static_cast<float>(p1[0]-p3[0]); v3[1] = static_cast<float>(p1[1]-p3[1]); v3[2] = static_cast<float>(p1[2]-p3[2]); float a = v1.magnitude(); float b = v2.magnitude(); float c = v3.magnitude(); float r = a*b*c/std::sqrt((a+b+c)*(a+b-c)*(b+c-a)*(a-b+c)); // radius of triangle via Heron's formula (area of triangle) vtkIdType id = vtkNewPoints->InsertNextPoint(p1); container->GetPointIds()->InsertNextId(id); if (deleteFibers && r<minRadius) break; if (r<minRadius) { j += 2; vtkNewCells->InsertNextCell(container); container = vtkSmartPointer<vtkPolyLine>::New(); } else if (j==numPoints-3) { id = vtkNewPoints->InsertNextPoint(p2); container->GetPointIds()->InsertNextId(id); id = vtkNewPoints->InsertNextPoint(p3); container->GetPointIds()->InsertNextId(id); vtkNewCells->InsertNextCell(container); } } } if (vtkNewCells->GetNumberOfCells()<=0) return false; m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New(); m_FiberPolyData->SetPoints(vtkNewPoints); m_FiberPolyData->SetLines(vtkNewCells); this->SetFiberPolyData(m_FiberPolyData, true); return true; } bool mitk::FiberBundle::RemoveShortFibers(float lengthInMM) { MITK_INFO << "Removing short fibers"; if (lengthInMM<=0 || lengthInMM<m_MinFiberLength) { MITK_INFO << "No fibers shorter than " << lengthInMM << " mm found!"; return true; } if (lengthInMM>m_MaxFiberLength) // can't remove all fibers { MITK_WARN << "Process aborted. No fibers would be left!"; return false; } vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New(); vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New(); float min = m_MaxFiberLength; boost::timer::progress_display disp(m_NumFibers); for (unsigned int i=0; i<m_NumFibers; i++) { ++disp; vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); if (m_FiberLengths.at(i)>=lengthInMM) { vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); for (int j=0; j<numPoints; j++) { double* p = points->GetPoint(j); vtkIdType id = vtkNewPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } vtkNewCells->InsertNextCell(container); if (m_FiberLengths.at(i)<min) min = m_FiberLengths.at(i); } } if (vtkNewCells->GetNumberOfCells()<=0) return false; m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New(); m_FiberPolyData->SetPoints(vtkNewPoints); m_FiberPolyData->SetLines(vtkNewCells); this->SetFiberPolyData(m_FiberPolyData, true); return true; } bool mitk::FiberBundle::RemoveLongFibers(float lengthInMM) { if (lengthInMM<=0 || lengthInMM>m_MaxFiberLength) return true; if (lengthInMM<m_MinFiberLength) // can't remove all fibers return false; vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New(); vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New(); MITK_INFO << "Removing long fibers"; boost::timer::progress_display disp(m_NumFibers); for (unsigned int i=0; i<m_NumFibers; i++) { ++disp; vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); if (m_FiberLengths.at(i)<=lengthInMM) { vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); for (int j=0; j<numPoints; j++) { double* p = points->GetPoint(j); vtkIdType id = vtkNewPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } vtkNewCells->InsertNextCell(container); } } if (vtkNewCells->GetNumberOfCells()<=0) return false; m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New(); m_FiberPolyData->SetPoints(vtkNewPoints); m_FiberPolyData->SetLines(vtkNewCells); this->SetFiberPolyData(m_FiberPolyData, true); return true; } void mitk::FiberBundle::ResampleSpline(float pointDistance, double tension, double continuity, double bias ) { if (pointDistance<=0) return; vtkSmartPointer<vtkPoints> vtkSmoothPoints = vtkSmartPointer<vtkPoints>::New(); //in smoothpoints the interpolated points representing a fiber are stored. //in vtkcells all polylines are stored, actually all id's of them are stored vtkSmartPointer<vtkCellArray> vtkSmoothCells = vtkSmartPointer<vtkCellArray>::New(); //cellcontainer for smoothed lines MITK_INFO << "Smoothing fibers"; vtkSmartPointer<vtkFloatArray> newFiberWeights = vtkSmartPointer<vtkFloatArray>::New(); newFiberWeights->SetName("FIBER_WEIGHTS"); newFiberWeights->SetNumberOfValues(m_NumFibers); std::vector< vtkSmartPointer<vtkPolyLine> > resampled_streamlines; resampled_streamlines.resize(m_NumFibers); boost::timer::progress_display disp(m_NumFibers); #pragma omp parallel for for (int i=0; i<static_cast<int>(m_NumFibers); i++) { vtkSmartPointer<vtkPoints> newPoints = vtkSmartPointer<vtkPoints>::New(); float length = 0; #pragma omp critical { length = m_FiberLengths.at(static_cast<unsigned int>(i)); ++disp; vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); for (int j=0; j<numPoints; j++) newPoints->InsertNextPoint(points->GetPoint(j)); } int sampling = static_cast<int>(std::ceil(length/pointDistance)); vtkSmartPointer<vtkKochanekSpline> xSpline = vtkSmartPointer<vtkKochanekSpline>::New(); vtkSmartPointer<vtkKochanekSpline> ySpline = vtkSmartPointer<vtkKochanekSpline>::New(); vtkSmartPointer<vtkKochanekSpline> zSpline = vtkSmartPointer<vtkKochanekSpline>::New(); xSpline->SetDefaultBias(bias); xSpline->SetDefaultTension(tension); xSpline->SetDefaultContinuity(continuity); ySpline->SetDefaultBias(bias); ySpline->SetDefaultTension(tension); ySpline->SetDefaultContinuity(continuity); zSpline->SetDefaultBias(bias); zSpline->SetDefaultTension(tension); zSpline->SetDefaultContinuity(continuity); vtkSmartPointer<vtkParametricSpline> spline = vtkSmartPointer<vtkParametricSpline>::New(); spline->SetXSpline(xSpline); spline->SetYSpline(ySpline); spline->SetZSpline(zSpline); spline->SetPoints(newPoints); vtkSmartPointer<vtkParametricFunctionSource> functionSource = vtkSmartPointer<vtkParametricFunctionSource>::New(); functionSource->SetParametricFunction(spline); functionSource->SetUResolution(sampling); functionSource->SetVResolution(sampling); functionSource->SetWResolution(sampling); functionSource->Update(); vtkPolyData* outputFunction = functionSource->GetOutput(); vtkPoints* tmpSmoothPnts = outputFunction->GetPoints(); //smoothPoints of current fiber vtkSmartPointer<vtkPolyLine> smoothLine = vtkSmartPointer<vtkPolyLine>::New(); #pragma omp critical { for (int j=0; j<tmpSmoothPnts->GetNumberOfPoints(); j++) { vtkIdType id = vtkSmoothPoints->InsertNextPoint(tmpSmoothPnts->GetPoint(j)); smoothLine->GetPointIds()->InsertNextId(id); } resampled_streamlines[static_cast<unsigned long>(i)] = smoothLine; } } for (auto container : resampled_streamlines) { vtkSmoothCells->InsertNextCell(container); } m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New(); m_FiberPolyData->SetPoints(vtkSmoothPoints); m_FiberPolyData->SetLines(vtkSmoothCells); this->SetFiberPolyData(m_FiberPolyData, true); } void mitk::FiberBundle::ResampleSpline(float pointDistance) { ResampleSpline(pointDistance, 0, 0, 0 ); } unsigned int mitk::FiberBundle::GetNumberOfPoints() const { unsigned int points = 0; for (int i=0; i<m_FiberPolyData->GetNumberOfCells(); i++) { vtkCell* cell = m_FiberPolyData->GetCell(i); points += cell->GetNumberOfPoints(); } return points; } void mitk::FiberBundle::Compress(float error) { vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New(); vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New(); MITK_INFO << "Compressing fibers with max. error " << error << "mm"; unsigned int numRemovedPoints = 0; boost::timer::progress_display disp(static_cast<unsigned long>(m_FiberPolyData->GetNumberOfCells())); vtkSmartPointer<vtkFloatArray> newFiberWeights = vtkSmartPointer<vtkFloatArray>::New(); newFiberWeights->SetName("FIBER_WEIGHTS"); newFiberWeights->SetNumberOfValues(m_NumFibers); #pragma omp parallel for for (int i=0; i<static_cast<int>(m_FiberPolyData->GetNumberOfCells()); i++) { std::vector< vnl_vector_fixed< double, 3 > > vertices; float weight = 1; #pragma omp critical { ++disp; weight = m_FiberWeights->GetValue(i); vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); for (int j=0; j<numPoints; j++) { double cand[3]; points->GetPoint(j, cand); vnl_vector_fixed< double, 3 > candV; candV[0]=cand[0]; candV[1]=cand[1]; candV[2]=cand[2]; vertices.push_back(candV); } } // calculate curvatures auto numPoints = vertices.size(); std::vector< int > removedPoints; removedPoints.resize(numPoints, 0); removedPoints[0]=-1; removedPoints[numPoints-1]=-1; vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); unsigned int remCounter = 0; bool pointFound = true; while (pointFound) { pointFound = false; double minError = static_cast<double>(error); unsigned int removeIndex = 0; for (unsigned int j=0; j<vertices.size(); j++) { if (removedPoints[j]==0) { vnl_vector_fixed< double, 3 > candV = vertices.at(j); int validP = -1; vnl_vector_fixed< double, 3 > pred; for (int k=static_cast<int>(j)-1; k>=0; k--) if (removedPoints[static_cast<unsigned int>(k)]<=0) { pred = vertices.at(static_cast<unsigned int>(k)); validP = k; break; } int validS = -1; vnl_vector_fixed< double, 3 > succ; for (unsigned int k=j+1; k<numPoints; k++) if (removedPoints[k]<=0) { succ = vertices.at(k); validS = static_cast<int>(k); break; } if (validP>=0 && validS>=0) { double a = (candV-pred).magnitude(); double b = (candV-succ).magnitude(); double c = (pred-succ).magnitude(); double s=0.5*(a+b+c); double hc=(2.0/c)*sqrt(fabs(s*(s-a)*(s-b)*(s-c))); if (hc<minError) { removeIndex = j; minError = hc; pointFound = true; } } } } if (pointFound) { removedPoints[removeIndex] = 1; remCounter++; } } for (unsigned int j=0; j<numPoints; j++) { if (removedPoints[j]<=0) { #pragma omp critical { vtkIdType id = vtkNewPoints->InsertNextPoint(vertices.at(j).data_block()); container->GetPointIds()->InsertNextId(id); } } } #pragma omp critical { newFiberWeights->SetValue(vtkNewCells->GetNumberOfCells(), weight); numRemovedPoints += remCounter; vtkNewCells->InsertNextCell(container); } } if (vtkNewCells->GetNumberOfCells()>0) { MITK_INFO << "Removed points: " << numRemovedPoints; SetFiberWeights(newFiberWeights); m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New(); m_FiberPolyData->SetPoints(vtkNewPoints); m_FiberPolyData->SetLines(vtkNewCells); this->SetFiberPolyData(m_FiberPolyData, true); } } void mitk::FiberBundle::ResampleToNumPoints(unsigned int targetPoints) { if (targetPoints<2) mitkThrow() << "Minimum two points required for resampling!"; MITK_INFO << "Resampling fibers (number of points " << targetPoints << ")"; bool unequal_fibs = true; while (unequal_fibs) { vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New(); vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New(); vtkSmartPointer<vtkFloatArray> newFiberWeights = vtkSmartPointer<vtkFloatArray>::New(); newFiberWeights->SetName("FIBER_WEIGHTS"); newFiberWeights->SetNumberOfValues(m_NumFibers); unequal_fibs = false; + MITK_INFO << "Start"; +// cv::parallel_for_(cv::Range(0, m_FiberPolyData->GetNumberOfCells()), [&](const cv::Range &range) +// { +// for (int i = range.start; i < range.end; i++) for (unsigned int i=0; i<m_FiberPolyData->GetNumberOfCells(); i++) { std::vector< vnl_vector_fixed< double, 3 > > vertices; float weight = 1; double seg_len = 0; { weight = m_FiberWeights->GetValue(i); vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); if (numPoints!=targetPoints) seg_len = static_cast<double>(this->GetFiberLength(i)/(targetPoints-1)); vtkPoints* points = cell->GetPoints(); for (int j=0; j<numPoints; j++) { double cand[3]; points->GetPoint(j, cand); vnl_vector_fixed< double, 3 > candV; candV[0]=cand[0]; candV[1]=cand[1]; candV[2]=cand[2]; vertices.push_back(candV); } } vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); vnl_vector_fixed< double, 3 > lastV = vertices.at(0); { vtkIdType id = vtkNewPoints->InsertNextPoint(lastV.data_block()); container->GetPointIds()->InsertNextId(id); } for (unsigned int j=1; j<vertices.size(); j++) { vnl_vector_fixed< double, 3 > vec = vertices.at(j) - lastV; double new_dist = vec.magnitude(); if (new_dist >= seg_len && seg_len>0) { vnl_vector_fixed< double, 3 > newV = lastV; if ( new_dist-seg_len <= mitk::eps ) { vec.normalize(); newV += vec * seg_len; } else { // intersection between sphere (radius 'pointDistance', center 'lastV') and line (direction 'd' and point 'p') vnl_vector_fixed< double, 3 > p = vertices.at(j-1); vnl_vector_fixed< double, 3 > d = vertices.at(j) - p; double a = d[0]*d[0] + d[1]*d[1] + d[2]*d[2]; double b = 2 * (d[0] * (p[0] - lastV[0]) + d[1] * (p[1] - lastV[1]) + d[2] * (p[2] - lastV[2])); double c = (p[0] - lastV[0])*(p[0] - lastV[0]) + (p[1] - lastV[1])*(p[1] - lastV[1]) + (p[2] - lastV[2])*(p[2] - lastV[2]) - seg_len*seg_len; double v1 =(-b + std::sqrt(b*b-4*a*c))/(2*a); double v2 =(-b - std::sqrt(b*b-4*a*c))/(2*a); if (v1>0) newV = p + d * v1; else if (v2>0) newV = p + d * v2; else MITK_INFO << "ERROR1 - linear resampling"; j--; } //#pragma omp critical { vtkIdType id = vtkNewPoints->InsertNextPoint(newV.data_block()); container->GetPointIds()->InsertNextId(id); } lastV = newV; } else if ( (j==vertices.size()-1 && new_dist>0.0001) || seg_len<=0.0000001) { //#pragma omp critical { vtkIdType id = vtkNewPoints->InsertNextPoint(vertices.at(j).data_block()); container->GetPointIds()->InsertNextId(id); } } } //#pragma omp critical { newFiberWeights->SetValue(vtkNewCells->GetNumberOfCells(), weight); vtkNewCells->InsertNextCell(container); if (container->GetNumberOfPoints()!=targetPoints) unequal_fibs = true; } } +// }); +// MITK_INFO << "Done"; if (vtkNewCells->GetNumberOfCells()>0) { SetFiberWeights(newFiberWeights); m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New(); m_FiberPolyData->SetPoints(vtkNewPoints); m_FiberPolyData->SetLines(vtkNewCells); this->SetFiberPolyData(m_FiberPolyData, true); } } } void mitk::FiberBundle::ResampleLinear(double pointDistance) { vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New(); vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New(); MITK_INFO << "Resampling fibers (linear)"; boost::timer::progress_display disp(static_cast<unsigned long>(m_FiberPolyData->GetNumberOfCells())); vtkSmartPointer<vtkFloatArray> newFiberWeights = vtkSmartPointer<vtkFloatArray>::New(); newFiberWeights->SetName("FIBER_WEIGHTS"); newFiberWeights->SetNumberOfValues(m_NumFibers); std::vector< vtkSmartPointer<vtkPolyLine> > resampled_streamlines; resampled_streamlines.resize(static_cast<unsigned long>(m_FiberPolyData->GetNumberOfCells())); #pragma omp parallel for for (int i=0; i<static_cast<int>(m_FiberPolyData->GetNumberOfCells()); i++) { std::vector< vnl_vector_fixed< double, 3 > > vertices; #pragma omp critical { ++disp; vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); for (int j=0; j<numPoints; j++) { double cand[3]; points->GetPoint(j, cand); vnl_vector_fixed< double, 3 > candV; candV[0]=cand[0]; candV[1]=cand[1]; candV[2]=cand[2]; vertices.push_back(candV); } } vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); vnl_vector_fixed< double, 3 > lastV = vertices.at(0); #pragma omp critical { vtkIdType id = vtkNewPoints->InsertNextPoint(lastV.data_block()); container->GetPointIds()->InsertNextId(id); } for (unsigned int j=1; j<vertices.size(); j++) { vnl_vector_fixed< double, 3 > vec = vertices.at(j) - lastV; double new_dist = vec.magnitude(); if (new_dist >= pointDistance) { vnl_vector_fixed< double, 3 > newV = lastV; if ( new_dist-pointDistance <= mitk::eps ) { vec.normalize(); newV += vec * pointDistance; } else { // intersection between sphere (radius 'pointDistance', center 'lastV') and line (direction 'd' and point 'p') vnl_vector_fixed< double, 3 > p = vertices.at(j-1); vnl_vector_fixed< double, 3 > d = vertices.at(j) - p; double a = d[0]*d[0] + d[1]*d[1] + d[2]*d[2]; double b = 2 * (d[0] * (p[0] - lastV[0]) + d[1] * (p[1] - lastV[1]) + d[2] * (p[2] - lastV[2])); double c = (p[0] - lastV[0])*(p[0] - lastV[0]) + (p[1] - lastV[1])*(p[1] - lastV[1]) + (p[2] - lastV[2])*(p[2] - lastV[2]) - pointDistance*pointDistance; double v1 =(-b + std::sqrt(b*b-4*a*c))/(2*a); double v2 =(-b - std::sqrt(b*b-4*a*c))/(2*a); if (v1>0) newV = p + d * v1; else if (v2>0) newV = p + d * v2; else MITK_INFO << "ERROR1 - linear resampling"; j--; } #pragma omp critical { vtkIdType id = vtkNewPoints->InsertNextPoint(newV.data_block()); container->GetPointIds()->InsertNextId(id); } lastV = newV; } else if (j==vertices.size()-1 && new_dist>0.0001) { #pragma omp critical { vtkIdType id = vtkNewPoints->InsertNextPoint(vertices.at(j).data_block()); container->GetPointIds()->InsertNextId(id); } } } #pragma omp critical { resampled_streamlines[static_cast<unsigned int>(i)] = container; } } for (auto container : resampled_streamlines) { vtkNewCells->InsertNextCell(container); } if (vtkNewCells->GetNumberOfCells()>0) { m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New(); m_FiberPolyData->SetPoints(vtkNewPoints); m_FiberPolyData->SetLines(vtkNewCells); this->SetFiberPolyData(m_FiberPolyData, true); } } // reapply selected colorcoding in case PolyData structure has changed bool mitk::FiberBundle::Equals(mitk::FiberBundle* fib, double eps) { if (fib==nullptr) { MITK_INFO << "Reference bundle is nullptr!"; return false; } if (m_NumFibers!=fib->GetNumFibers()) { MITK_INFO << "Unequal number of fibers!"; MITK_INFO << m_NumFibers << " vs. " << fib->GetNumFibers(); return false; } for (unsigned int i=0; i<m_NumFibers; i++) { vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkCell* cell2 = fib->GetFiberPolyData()->GetCell(i); auto numPoints2 = cell2->GetNumberOfPoints(); vtkPoints* points2 = cell2->GetPoints(); if (numPoints2!=numPoints) { MITK_INFO << "Unequal number of points in fiber " << i << "!"; MITK_INFO << numPoints2 << " vs. " << numPoints; return false; } for (int j=0; j<numPoints; j++) { double* p1 = points->GetPoint(j); double* p2 = points2->GetPoint(j); if (fabs(p1[0]-p2[0])>eps || fabs(p1[1]-p2[1])>eps || fabs(p1[2]-p2[2])>eps) { MITK_INFO << "Unequal points in fiber " << i << " at position " << j << "!"; MITK_INFO << "p1: " << p1[0] << ", " << p1[1] << ", " << p1[2]; MITK_INFO << "p2: " << p2[0] << ", " << p2[1] << ", " << p2[2]; return false; } } } return true; } void mitk::FiberBundle::PrintSelf(std::ostream &os, itk::Indent indent) const { os << indent << "Number of fibers: " << this->GetNumFibers() << std::endl; os << indent << "Min. fiber length: " << this->GetMinFiberLength() << std::endl; os << indent << "Max. fiber length: " << this->GetMaxFiberLength() << std::endl; os << indent << "Mean fiber length: " << this->GetMeanFiberLength() << std::endl; os << indent << "Median fiber length: " << this->GetMedianFiberLength() << std::endl; os << indent << "STDEV fiber length: " << this->GetLengthStDev() << std::endl; os << indent << "Number of points: " << this->GetNumberOfPoints() << std::endl; os << indent << "Extent x: " << this->GetGeometry()->GetExtentInMM(0) << "mm" << std::endl; os << indent << "Extent y: " << this->GetGeometry()->GetExtentInMM(1) << "mm" << std::endl; os << indent << "Extent z: " << this->GetGeometry()->GetExtentInMM(2) << "mm" << std::endl; os << indent << "Diagonal: " << this->GetGeometry()->GetDiagonalLength() << "mm" << std::endl; os << "\nReference geometry:" << std::endl; os << indent << "Size: [" << std::defaultfloat << m_TrackVisHeader.dim[0] << " " << m_TrackVisHeader.dim[1] << " " << m_TrackVisHeader.dim[2] << "]" << std::endl; os << indent << "Voxel size: [" << m_TrackVisHeader.voxel_size[0] << " " << m_TrackVisHeader.voxel_size[1] << " " << m_TrackVisHeader.voxel_size[2] << "]" << std::endl; os << indent << "Origin: [" << m_TrackVisHeader.origin[0] << " " << m_TrackVisHeader.origin[1] << " " << m_TrackVisHeader.origin[2] << "]" << std::endl; os << indent << "Matrix: " << std::scientific << std::endl; os << indent << "[[" << m_TrackVisHeader.vox_to_ras[0][0] << ", " << m_TrackVisHeader.vox_to_ras[0][1] << ", " << m_TrackVisHeader.vox_to_ras[0][2] << ", " << m_TrackVisHeader.vox_to_ras[0][3] << "]" << std::endl; os << indent << " [" << m_TrackVisHeader.vox_to_ras[1][0] << ", " << m_TrackVisHeader.vox_to_ras[1][1] << ", " << m_TrackVisHeader.vox_to_ras[1][2] << ", " << m_TrackVisHeader.vox_to_ras[1][3] << "]" << std::endl; os << indent << " [" << m_TrackVisHeader.vox_to_ras[2][0] << ", " << m_TrackVisHeader.vox_to_ras[2][1] << ", " << m_TrackVisHeader.vox_to_ras[2][2] << ", " << m_TrackVisHeader.vox_to_ras[2][3] << "]" << std::endl; os << indent << " [" << m_TrackVisHeader.vox_to_ras[3][0] << ", " << m_TrackVisHeader.vox_to_ras[3][1] << ", " << m_TrackVisHeader.vox_to_ras[3][2] << ", " << m_TrackVisHeader.vox_to_ras[3][3] << "]]" << std::defaultfloat << std::endl; if (m_FiberWeights!=nullptr) { std::vector< float > weights; for (int i=0; i<m_FiberWeights->GetSize(); i++) weights.push_back(m_FiberWeights->GetValue(i)); std::sort(weights.begin(), weights.end()); os << "\nFiber weight statistics" << std::endl; os << indent << "Min: " << weights.front() << std::endl; os << indent << "1% quantile: " << weights.at(static_cast<unsigned long>(weights.size()*0.01)) << std::endl; os << indent << "5% quantile: " << weights.at(static_cast<unsigned long>(weights.size()*0.05)) << std::endl; os << indent << "25% quantile: " << weights.at(static_cast<unsigned long>(weights.size()*0.25)) << std::endl; os << indent << "Median: " << weights.at(static_cast<unsigned long>(weights.size()*0.5)) << std::endl; os << indent << "75% quantile: " << weights.at(static_cast<unsigned long>(weights.size()*0.75)) << std::endl; os << indent << "95% quantile: " << weights.at(static_cast<unsigned long>(weights.size()*0.95)) << std::endl; os << indent << "99% quantile: " << weights.at(static_cast<unsigned long>(weights.size()*0.99)) << std::endl; os << indent << "Max: " << weights.back() << std::endl; } else os << indent << "\n\nNo fiber weight array found." << std::endl; Superclass::PrintSelf(os, 0); } mitk::FiberBundle::TrackVis_header mitk::FiberBundle::GetTrackVisHeader() { if (m_TrackVisHeader.hdr_size==0) { mitk::Geometry3D::Pointer geom = dynamic_cast<mitk::Geometry3D*>(this->GetGeometry()); SetTrackVisHeader(geom); } return m_TrackVisHeader; } void mitk::FiberBundle::SetTrackVisHeader(const mitk::FiberBundle::TrackVis_header &TrackVisHeader) { m_TrackVisHeader = TrackVisHeader; } void mitk::FiberBundle::SetTrackVisHeader(mitk::BaseGeometry* geometry) { vtkSmartPointer< vtkMatrix4x4 > matrix = vtkSmartPointer< vtkMatrix4x4 >::New(); matrix->Identity(); if (geometry==nullptr) return; for(int i=0; i<3 ;i++) { m_TrackVisHeader.dim[i] = geometry->GetExtent(i); m_TrackVisHeader.voxel_size[i] = geometry->GetSpacing()[i]; m_TrackVisHeader.origin[i] = geometry->GetOrigin()[i]; matrix = geometry->GetVtkMatrix(); } for (int i=0; i<4; ++i) for (int j=0; j<4; ++j) m_TrackVisHeader.vox_to_ras[i][j] = matrix->GetElement(i, j); m_TrackVisHeader.n_scalars = 0; m_TrackVisHeader.n_properties = 0; sprintf(m_TrackVisHeader.voxel_order,"LPS"); m_TrackVisHeader.image_orientation_patient[0] = 1.0; m_TrackVisHeader.image_orientation_patient[1] = 0.0; m_TrackVisHeader.image_orientation_patient[2] = 0.0; m_TrackVisHeader.image_orientation_patient[3] = 0.0; m_TrackVisHeader.image_orientation_patient[4] = 1.0; m_TrackVisHeader.image_orientation_patient[5] = 0.0; m_TrackVisHeader.pad1[0] = 0; m_TrackVisHeader.pad1[1] = 0; m_TrackVisHeader.pad2[0] = 0; m_TrackVisHeader.pad2[1] = 0; m_TrackVisHeader.invert_x = 0; m_TrackVisHeader.invert_y = 0; m_TrackVisHeader.invert_z = 0; m_TrackVisHeader.swap_xy = 0; m_TrackVisHeader.swap_yz = 0; m_TrackVisHeader.swap_zx = 0; m_TrackVisHeader.n_count = 0; m_TrackVisHeader.version = 2; m_TrackVisHeader.hdr_size = 1000; std::string id = "TRACK"; strcpy(m_TrackVisHeader.id_string, id.c_str()); } /* ESSENTIAL IMPLEMENTATION OF SUPERCLASS METHODS */ void mitk::FiberBundle::UpdateOutputInformation() { } void mitk::FiberBundle::SetRequestedRegionToLargestPossibleRegion() { } bool mitk::FiberBundle::RequestedRegionIsOutsideOfTheBufferedRegion() { return false; } bool mitk::FiberBundle::VerifyRequestedRegion() { return true; } void mitk::FiberBundle::SetRequestedRegion(const itk::DataObject* ) { } diff --git a/Modules/DiffusionCore/IODataStructures/mitkFiberBundle.h b/Modules/DiffusionCore/IODataStructures/mitkFiberBundle.h index c6bbdf1..75a2008 100644 --- a/Modules/DiffusionCore/IODataStructures/mitkFiberBundle.h +++ b/Modules/DiffusionCore/IODataStructures/mitkFiberBundle.h @@ -1,247 +1,252 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef _MITK_FiberBundle_H #define _MITK_FiberBundle_H //includes for MITK datastructure #include <mitkBaseData.h> #include <MitkDiffusionCoreExports.h> #include <mitkImage.h> #include <mitkDataStorage.h> #include <mitkPlanarFigure.h> #include <mitkPixelTypeTraits.h> #include <mitkPlanarFigureComposite.h> #include <mitkPeakImage.h> //includes storing fiberdata #include <vtkSmartPointer.h> #include <vtkPolyData.h> #include <vtkPoints.h> #include <vtkDataSet.h> #include <vtkTransform.h> #include <vtkFloatArray.h> #include <itkScalableAffineTransform.h> #include <mitkDiffusionFunctionCollection.h> #include <mitkLookupTable.h> +#include <opencv2/ml.hpp> +#include <opencv2/opencv.hpp> +#include <opencv2/highgui/highgui.hpp> + namespace mitk { /** * \brief Base Class for Fiber Bundles; */ class MITKDIFFUSIONCORE_EXPORT FiberBundle : public BaseData { public: typedef itk::Image<unsigned char, 3> ItkUcharImgType; // fiber colorcodings static const char* FIBER_ID_ARRAY; void UpdateOutputInformation() override; void SetRequestedRegionToLargestPossibleRegion() override; bool RequestedRegionIsOutsideOfTheBufferedRegion() override; bool VerifyRequestedRegion() override; void SetRequestedRegion(const itk::DataObject*) override; mitkClassMacro( FiberBundle, BaseData ) itkFactorylessNewMacro(Self) itkCloneMacro(Self) mitkNewMacro1Param(Self, vtkSmartPointer<vtkPolyData>) // custom constructor // colorcoding related methods void ColorSinglePoint(int f_idx, int p_idx, double rgb[3]); void ColorFibersByFiberWeights(bool opacity, LookupTable::LookupTableType type); void ColorFibersByCurvature(bool opacity, bool weight_fibers, mitk::LookupTable::LookupTableType type); void ColorFibersByLength(bool opacity, bool weight_fibers, mitk::LookupTable::LookupTableType type); void ColorFibersByScalarMap(mitk::Image::Pointer, bool opacity, bool weight_fibers, mitk::LookupTable::LookupTableType type, double max_cap, bool interpolate=true); template <typename TPixel> void ColorFibersByScalarMap(typename itk::Image<TPixel, 3>::Pointer, bool opacity, bool weight_fibers, mitk::LookupTable::LookupTableType type, double max_cap, bool interpolate=true); void ColorFibersByOrientation(); void SetFiberOpacity(vtkDoubleArray *FAValArray); void ResetFiberOpacity(); void SetFiberColors(vtkSmartPointer<vtkUnsignedCharArray> fiberColors); void SetFiberColors(float r, float g, float b, float alpha=255); + void SetSingleFiberColor(float r, float g, float b, unsigned int cellId, float alpha=255); vtkSmartPointer<vtkUnsignedCharArray> GetFiberColors() const { return m_FiberColors; } // fiber compression void Compress(float error = 0.0); // fiber resampling void ResampleSpline(float pointDistance=1); void ResampleSpline(float pointDistance, double tension, double continuity, double bias ); void ResampleLinear(double pointDistance=1); void ResampleToNumPoints(unsigned int targetPoints); mitk::FiberBundle::Pointer FilterByWeights(float weight_thr, bool invert=false); bool RemoveShortFibers(float lengthInMM); bool RemoveLongFibers(float lengthInMM); bool ApplyCurvatureThreshold(float minRadius, bool deleteFibers); void MirrorFibers(unsigned int axis); void RotateAroundAxis(double x, double y, double z); void TranslateFibers(double x, double y, double z); void ScaleFibers(double x, double y, double z, bool subtractCenter=true); void TransformFibers(double rx, double ry, double rz, double tx, double ty, double tz); void TransformFibers(itk::ScalableAffineTransform< mitk::ScalarType >::Pointer transform); void RemoveDir(vnl_vector_fixed<double,3> dir, double threshold); template< class TType=float > void TransformPoint(itk::Point<TType, 3>& point, itk::Matrix< TType, 3, 3>& rot, TType& tx, TType& ty, TType& tz) { mitk::Point3D center = this->GetGeometry()->GetCenter(); point[0] -= center[0]; point[1] -= center[1]; point[2] -= center[2]; point = rot*point; point[0] += center[0]+tx; point[1] += center[1]+ty; point[2] += center[2]+tz; } template< class TType=float > void TransformPoint(itk::Point<TType, 3>& point, TType rx, TType ry, TType rz, TType tx, TType ty, TType tz) { auto rot = mitk::imv::GetRotationMatrixItk<TType>(rx, ry, rz); mitk::Point3D center = this->GetGeometry()->GetCenter(); point[0] -= center[0]; point[1] -= center[1]; point[2] -= center[2]; point = rot*point; point[0] += center[0]+tx; point[1] += center[1]+ty; point[2] += center[2]+tz; } itk::Matrix< double, 3, 3 > TransformMatrix(itk::Matrix< double, 3, 3 > m, double rx, double ry, double rz); // add/subtract fibers FiberBundle::Pointer AddBundle(FiberBundle* fib); mitk::FiberBundle::Pointer AddBundles(std::vector< mitk::FiberBundle::Pointer > fibs); FiberBundle::Pointer SubtractBundle(FiberBundle* fib); // fiber subset extraction FiberBundle::Pointer ExtractFiberSubset(DataNode *roi, DataStorage* storage); std::vector<unsigned int> ExtractFiberIdSubset(DataNode* roi, DataStorage* storage); FiberBundle::Pointer RemoveFibersOutside(ItkUcharImgType* mask, bool invert=false); float GetOverlap(ItkUcharImgType* mask); std::tuple<float, float> GetDirectionalOverlap(ItkUcharImgType* mask, mitk::PeakImage::ItkPeakImageType* peak_image); float GetNumEpFractionInMask(ItkUcharImgType* mask, bool different_label); mitk::FiberBundle::Pointer SubsampleFibers(float factor, bool random_seed); // get/set data float GetFiberLength(unsigned int index) const { return m_FiberLengths.at(index); } vtkSmartPointer<vtkFloatArray> GetFiberWeights() const { return m_FiberWeights; } float GetFiberWeight(unsigned int fiber) const; void SetFiberWeights(float newWeight); void SetFiberWeight(unsigned int fiber, float weight); void SetFiberWeights(vtkSmartPointer<vtkFloatArray> weights); void SetFiberPolyData(vtkSmartPointer<vtkPolyData>, bool updateGeometry = true); vtkSmartPointer<vtkPolyData> GetFiberPolyData() const; itkGetConstMacro( NumFibers, unsigned int) //itkGetMacro( FiberSampling, int) itkGetConstMacro( MinFiberLength, float ) itkGetConstMacro( MaxFiberLength, float ) itkGetConstMacro( MeanFiberLength, float ) itkGetConstMacro( MedianFiberLength, float ) itkGetConstMacro( LengthStDev, float ) itkGetConstMacro( UpdateTime2D, itk::TimeStamp ) itkGetConstMacro( UpdateTime3D, itk::TimeStamp ) void RequestUpdate2D(){ m_UpdateTime2D.Modified(); } void RequestUpdate3D(){ m_UpdateTime3D.Modified(); } void RequestUpdate(){ m_UpdateTime2D.Modified(); m_UpdateTime3D.Modified(); } unsigned int GetNumberOfPoints() const; // copy fiber bundle mitk::FiberBundle::Pointer GetDeepCopy(); // compare fiber bundles bool Equals(FiberBundle* fib, double eps=0.01); vtkSmartPointer<vtkPolyData> GeneratePolyDataByIds(std::vector<unsigned int> fiberIds, vtkSmartPointer<vtkFloatArray> weights); // Structure to hold metadata of a TrackVis file struct TrackVis_header { char id_string[6]; short int dim[3]; float voxel_size[3]; float origin[3]; short int n_scalars; char scalar_name[10][20]; short int n_properties; char property_name[10][20]; float vox_to_ras[4][4]; char reserved[444]; char voxel_order[4]; char pad2[4]; float image_orientation_patient[6]; char pad1[2]; unsigned char invert_x; unsigned char invert_y; unsigned char invert_z; unsigned char swap_xy; unsigned char swap_yz; unsigned char swap_zx; int n_count; int version; int hdr_size; }; TrackVis_header GetTrackVisHeader(); void SetTrackVisHeader(const TrackVis_header &TrackVisHeader); void SetTrackVisHeader(BaseGeometry *geometry); void PrintSelf(std::ostream &os, itk::Indent indent) const override; protected: FiberBundle( vtkPolyData* fiberPolyData = nullptr ); ~FiberBundle() override; void GenerateFiberIds(); void UpdateFiberGeometry(); private: // actual fiber container vtkSmartPointer<vtkPolyData> m_FiberPolyData; // contains fiber ids vtkSmartPointer<vtkDataSet> m_FiberIdDataSet; unsigned int m_NumFibers; vtkSmartPointer<vtkUnsignedCharArray> m_FiberColors; vtkSmartPointer<vtkFloatArray> m_FiberWeights; std::vector< float > m_FiberLengths; float m_MinFiberLength; float m_MaxFiberLength; float m_MeanFiberLength; float m_MedianFiberLength; float m_LengthStDev; itk::TimeStamp m_UpdateTime2D; itk::TimeStamp m_UpdateTime3D; TrackVis_header m_TrackVisHeader; }; } // namespace mitk #endif /* _MITK_FiberBundle_H */ diff --git a/Modules/FiberDissection/CMakeLists.txt b/Modules/FiberDissection/CMakeLists.txt new file mode 100644 index 0000000..9b030ee --- /dev/null +++ b/Modules/FiberDissection/CMakeLists.txt @@ -0,0 +1,5 @@ +MITK_CREATE_MODULE( + SUBPROJECTS MITK-Diffusion + INCLUDE_DIRS Interactor MachineLearning ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS MitkDiffusionCore +) diff --git a/Modules/FiberDissection/Interactor/mitkStreamlineInteractor.cpp b/Modules/FiberDissection/Interactor/mitkStreamlineInteractor.cpp new file mode 100644 index 0000000..e885d79 --- /dev/null +++ b/Modules/FiberDissection/Interactor/mitkStreamlineInteractor.cpp @@ -0,0 +1,1207 @@ +/*============================================================================ + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center (DKFZ) +All rights reserved. + +Use of this source code is governed by a 3-clause BSD license that can be +found in the LICENSE file. + +============================================================================*/ + +#include "mitkStreamlineInteractor.h" +//#include "mitkStreamlineMapper2D.h" + +// MITK includes +#include <mitkInteractionConst.h> +#include <mitkInteractionPositionEvent.h> +#include <mitkInternalEvent.h> +#include <mitkLookupTableProperty.h> +#include <mitkOperationEvent.h> +#include <mitkRotationOperation.h> +#include <mitkScaleOperation.h> +#include <mitkSurface.h> +#include <mitkUndoController.h> +#include <mitkVtkMapper.h> + +// VTK includes +#include <vtkCamera.h> +#include <vtkInteractorObserver.h> +#include <vtkInteractorStyle.h> +#include <vtkMath.h> +#include <vtkPointData.h> +#include <vtkPolyData.h> +#include <vtkRenderWindowInteractor.h> +#include <vtkVector.h> +#include <vtkPolyLine.h> +#include <vtkVectorOperators.h> + +mitk::StreamlineInteractor::StreamlineInteractor() +{ + m_ColorForHighlight[0] = 1.0; + m_ColorForHighlight[1] = 0.5; + m_ColorForHighlight[2] = 0.0; + m_ColorForHighlight[3] = 1.0; + + // TODO if we want to get this configurable, the this is the recipe: + // - make the 2D mapper add corresponding properties to control "enabled" and "color" + // - make the interactor evaluate those properties + // - in an ideal world, modify the state machine on the fly and skip mouse move handling +} + +mitk::StreamlineInteractor::~StreamlineInteractor() +{ +} + +void mitk::StreamlineInteractor::ConnectActionsAndFunctions() +{ +// CONNECT_CONDITION("isoverstreamline", HasPickedHandle); + CONNECT_CONDITION("isoverstreamline", CheckSelection); + CONNECT_FUNCTION("selectstreamline", SelectStreamline); + + CONNECT_FUNCTION("addnegstreamline", AddStreamlineNegBundle); + CONNECT_FUNCTION("addposstreamline", AddStreamlinePosBundle); + CONNECT_FUNCTION("addnegtolabelstreamline", AddNegStreamlinetolabelsBundle); + CONNECT_FUNCTION("addpostolabelstreamline", AddPosStreamlinetolabelsBundle); +// CONNECT_FUNCTION("FeedUndoStack", FeedUndoStack); +} + +void mitk::StreamlineInteractor::SetNegativeNode(DataNode *node) +{ + +// DataInteractor::SetDataNode(node); + m_NegStreamlineNode = node; + m_NegStreamline= dynamic_cast<mitk::FiberBundle *>(node->GetData()); + MITK_INFO << "Negative Node added"; +} + +void mitk::StreamlineInteractor::SetToLabelNode(DataNode *node) +{ + m_manStreamlineNode = node; + DataInteractor::SetDataNode(m_manStreamlineNode); + m_manStreamline = dynamic_cast<mitk::FiberBundle *>(node->GetData()); + MITK_INFO << "Label node added"; +// m_init = false; + +} + +void mitk::StreamlineInteractor::SetPositiveNode(DataNode *node) +{ + + // DataInteractor::SetDataNode(node); + m_PosStreamlineNode = node; + m_PosStreamline= dynamic_cast<mitk::FiberBundle *>(node->GetData()); + MITK_INFO << "Positive Node added"; +} + +void mitk::StreamlineInteractor::LabelfromPrediction(bool predlabeling) +{ + m_predlabeling = predlabeling; + +} + +bool mitk::StreamlineInteractor::CheckSelection(const InteractionEvent *interactionEvent) +{ + /* Save Colorvector here*/ + + const auto *positionEvent = dynamic_cast<const InteractionPositionEvent *>(interactionEvent); + if (positionEvent != nullptr) + { + if (interactionEvent->GetSender()->GetMapperID() == BaseRenderer::Standard2D) + { + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer<vtkCellPicker>::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard2D); + + + auto vtk_mapper = dynamic_cast<VtkMapper *>(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + + + if (picker->GetCellId()==-1 && m_predlabeling==false) + { +// m_manStreamline->SetFiberColors(255, 255, 255); +// vtkSmartPointer<vtkUnsignedCharArray> FiberColors = m_manStreamline->m_FiberColors; + + RenderingManager::GetInstance()->RequestUpdateAll(); + return false; + } + else + { + + return true; + } + } + else { + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer<vtkCellPicker>::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard3D); + + + auto vtk_mapper = dynamic_cast<VtkMapper *>(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + + + if (picker->GetCellId()==-1 && m_predlabeling==false) + { +// m_manStreamline->SetFiberColors(255, 255, 255); + RenderingManager::GetInstance()->RequestUpdateAll(); + return false; + } + else + { + + return true; + } + + } + + + } + else { +// m_manStreamline->SetFiberColors(255, 255, 255); + RenderingManager::GetInstance()->RequestUpdateAll(); + return false; + } + +} + +void mitk::StreamlineInteractor::SelectStreamline(StateMachineAction *, InteractionEvent *interactionEvent) +{ + auto *positionEvent = dynamic_cast<InteractionPositionEvent *>(interactionEvent); + + if (interactionEvent->GetSender()->GetMapperID() == BaseRenderer::Standard2D) + { + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer<vtkCellPicker>::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard2D); + + + auto vtk_mapper = dynamic_cast<VtkMapper *>(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } + // } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + if (m_predlabeling==false) + { + vtkIdType pickedCellID = picker->GetCellId(); + m_manStreamline->SetSingleFiberColor(0.0, 255.0, 0.0, pickedCellID); +// m_manStreamline->SetFloatProperty("shape.tuberadius", 1.0) + } + } + else { + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer<vtkCellPicker>::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard3D); + + + auto vtk_mapper = dynamic_cast<VtkMapper *>(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } + // } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + if (m_predlabeling==false) + { + vtkIdType pickedCellID = picker->GetCellId(); + m_manStreamline->SetSingleFiberColor(0.0, 255.0, 0.0, pickedCellID); +// m_manStreamline->SetFloatProperty("shape.tuberadius", 1.0); + } + } + + + RenderingManager::GetInstance()->RequestUpdateAll(); +} + +void mitk::StreamlineInteractor::AddStreamlinePosBundle(StateMachineAction *, InteractionEvent *interactionEvent) +{ + MITK_INFO << "PositiveBundle clicked"; + DataInteractor::SetDataNode(m_manStreamlineNode); + + auto positionEvent = dynamic_cast<const InteractionPositionEvent *>(interactionEvent); + if (positionEvent == nullptr) + { + MITK_INFO << "no position"; + } + + if (interactionEvent->GetSender()->GetMapperID() == BaseRenderer::Standard2D) + { +// m_PickedHandle = PickFrom2D(positionEvent); + MITK_INFO << "2D"; + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer<vtkCellPicker>::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard2D); + + auto vtk_mapper = dynamic_cast<VtkMapper *>(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } +// } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + vtkIdType pickedCellID = picker->GetCellId(); + + + + if (picker->GetCellId()==-1) + { + MITK_INFO << "Nothing picked"; + } + else { + + + vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New(); + vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New(); + + unsigned int counter = 0; + for ( int i=0; i<m_PosStreamline->GetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_PosStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(pickedCellID); + + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // m_PosStreamline = mitk::FiberBundle::New(vNewPolyData); + m_PosStreamline->GetFiberPolyData()->SetPoints(vNewPoints); + m_PosStreamline->GetFiberPolyData()->SetLines(vNewLines); + m_PosStreamline->SetFiberColors(0, 255, 0); +// m_PosStreamline->SetFiberWeights(m_PosStreamline->GetFiberWeights()); + + m_manStreamline->GetFiberPolyData()->DeleteCell(pickedCellID); + m_manStreamline->GetFiberPolyData()->RemoveDeletedCells(); + if (m_predlabeling==false) + { + vtkSmartPointer<vtkPolyData> vNewPolyData2 = vtkSmartPointer<vtkPolyData>::New(); + vtkSmartPointer<vtkCellArray> vNewLines2 = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkPoints> vNewPoints2 = vtkSmartPointer<vtkPoints>::New(); + + + counter = 0; + for ( int i=0; i<m_manStreamline->GetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints2->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines2->InsertNextCell(container); + counter++; + + } + m_manStreamline->GetFiberPolyData()->SetPoints(vNewPoints2); + m_manStreamline->GetFiberPolyData()->SetLines(vNewLines2); + m_manStreamline->SetFiberColors(255, 255, 255); + } + + + + + + } + } + else + { + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer<vtkCellPicker>::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard3D); + + + auto vtk_mapper = dynamic_cast<VtkMapper *>(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } +// } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + vtkIdType pickedCellID = picker->GetCellId(); + + + + if (picker->GetCellId()==-1) + { + MITK_INFO << "Nothing picked"; + } + else { + + + vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New(); + vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New(); + + unsigned int counter = 0; + for ( int i=0; i<m_PosStreamline->GetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_PosStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(pickedCellID); + + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // m_PosStreamline = mitk::FiberBundle::New(vNewPolyData); + m_PosStreamline->GetFiberPolyData()->SetPoints(vNewPoints); + m_PosStreamline->GetFiberPolyData()->SetLines(vNewLines); + m_PosStreamline->SetFiberColors(0, 255, 0); +// m_PosStreamline->SetFiberWeights(m_PosStreamline->GetFiberWeights()); + + + m_manStreamline->GetFiberPolyData()->DeleteCell(pickedCellID); + m_manStreamline->GetFiberPolyData()->RemoveDeletedCells(); + + if (m_predlabeling==false) + { + vtkSmartPointer<vtkPolyData> vNewPolyData2 = vtkSmartPointer<vtkPolyData>::New(); + vtkSmartPointer<vtkCellArray> vNewLines2 = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkPoints> vNewPoints2 = vtkSmartPointer<vtkPoints>::New(); + + + counter = 0; + for ( int i=0; i<m_manStreamline->GetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints2->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines2->InsertNextCell(container); + counter++; + + } + m_manStreamline->GetFiberPolyData()->SetPoints(vNewPoints2); + m_manStreamline->GetFiberPolyData()->SetLines(vNewLines2); + m_manStreamline->SetFiberColors(255, 255, 255); + } + + } + } + RenderingManager::GetInstance()->RequestUpdateAll(); + } + +void mitk::StreamlineInteractor::AddStreamlineNegBundle(StateMachineAction *, InteractionEvent *interactionEvent) +{ + MITK_INFO << "NegativeBundle clicked"; + + DataInteractor::SetDataNode(m_manStreamlineNode); + + auto positionEvent = dynamic_cast<const InteractionPositionEvent *>(interactionEvent); + if (positionEvent == nullptr) + { + MITK_INFO << "no position"; + } + + if (interactionEvent->GetSender()->GetMapperID() == BaseRenderer::Standard2D) + { +// m_PickedHandle = PickFrom2D(positionEvent); + MITK_INFO << "2D"; + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer<vtkCellPicker>::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard2D); + + auto vtk_mapper = dynamic_cast<VtkMapper *>(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } +// } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + vtkIdType pickedCellID = picker->GetCellId(); + + + + if (picker->GetCellId()==-1) + { + MITK_INFO << "Nothing picked"; + } + else { + + + vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New(); + vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New(); + + unsigned int counter = 0; + for ( int i=0; i<m_NegStreamline->GetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_NegStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(pickedCellID); + + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // m_NegStreamline = mitk::FiberBundle::New(vNewPolyData); + m_NegStreamline->GetFiberPolyData()->SetPoints(vNewPoints); + m_NegStreamline->GetFiberPolyData()->SetLines(vNewLines); + m_NegStreamline->SetFiberColors(255, 0, 0); +// m_NegStreamline->SetFiberWeights(m_NegStreamline->GetFiberWeights()); + + m_manStreamline->GetFiberPolyData()->DeleteCell(pickedCellID); + m_manStreamline->GetFiberPolyData()->RemoveDeletedCells(); + + if (m_predlabeling==false) + { + vtkSmartPointer<vtkPolyData> vNewPolyData2 = vtkSmartPointer<vtkPolyData>::New(); + vtkSmartPointer<vtkCellArray> vNewLines2 = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkPoints> vNewPoints2 = vtkSmartPointer<vtkPoints>::New(); + + + counter = 0; + for ( int i=0; i<m_manStreamline->GetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints2->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines2->InsertNextCell(container); + counter++; + + } + m_manStreamline->GetFiberPolyData()->SetPoints(vNewPoints2); + m_manStreamline->GetFiberPolyData()->SetLines(vNewLines2); + m_manStreamline->SetFiberColors(255, 255, 255); + } + + + + + + } + } + else + { + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; +// if (picker == nullptr) +// { + + + picker = vtkSmartPointer<vtkCellPicker>::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard3D); + + + auto vtk_mapper = dynamic_cast<VtkMapper *>(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } +// } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + vtkIdType pickedCellID = picker->GetCellId(); + + + if (picker->GetCellId()==-1) + { + MITK_INFO << "Nothing picked"; + } + else + { + vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New(); + vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New(); + + unsigned int counter = 0; + for ( int i=0; i<m_NegStreamline->GetFiberPolyData()->GetNumberOfCells(); i++) + { + vtkCell* cell = m_NegStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(pickedCellID); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // m_NegStreamline = mitk::FiberBundle::New(vNewPolyData); + m_NegStreamline->GetFiberPolyData()->SetPoints(vNewPoints); + m_NegStreamline->GetFiberPolyData()->SetLines(vNewLines); + m_NegStreamline->SetFiberColors(255, 0, 0); + + m_manStreamline->GetFiberPolyData()->DeleteCell(pickedCellID); + m_manStreamline->GetFiberPolyData()->RemoveDeletedCells(); + + if (m_predlabeling==false) + { + vtkSmartPointer<vtkPolyData> vNewPolyData2 = vtkSmartPointer<vtkPolyData>::New(); + vtkSmartPointer<vtkCellArray> vNewLines2 = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkPoints> vNewPoints2 = vtkSmartPointer<vtkPoints>::New(); + + + counter = 0; + for ( int i=0; i<m_manStreamline->GetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints2->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines2->InsertNextCell(container); + counter++; + + } + m_manStreamline->GetFiberPolyData()->SetPoints(vNewPoints2); + m_manStreamline->GetFiberPolyData()->SetLines(vNewLines2); + m_manStreamline->SetFiberColors(255, 255, 255); + } + + } + } + RenderingManager::GetInstance()->RequestUpdateAll(); + } + +void mitk::StreamlineInteractor::AddNegStreamlinetolabelsBundle(StateMachineAction *, InteractionEvent *interactionEvent) +{ + MITK_INFO << "TolabelBundle clicked"; + DataInteractor::SetDataNode(m_NegStreamlineNode); + + + auto positionEvent = dynamic_cast<const InteractionPositionEvent *>(interactionEvent); + if (positionEvent == nullptr) + { + MITK_INFO << "no position"; + } + + if (interactionEvent->GetSender()->GetMapperID() == BaseRenderer::Standard2D) + { +// m_PickedHandle = PickFrom2D(positionEvent); + + MITK_INFO << "2D"; + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer<vtkCellPicker>::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard2D); + + auto vtk_mapper = dynamic_cast<VtkMapper *>(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } +// } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + vtkIdType pickedCellID = picker->GetCellId(); + + + + if (picker->GetCellId()==-1) + { + MITK_INFO << "Nothing picked"; + } + else { + + + vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New(); + vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New(); + + unsigned int counter = 0; + for ( int i=0; i<m_manStreamline->GetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vtkCell* cell = m_NegStreamline->GetFiberPolyData()->GetCell(pickedCellID); + + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // m_manStreamline = mitk::FiberBundle::New(vNewPolyData); + m_manStreamline->GetFiberPolyData()->SetPoints(vNewPoints); + m_manStreamline->GetFiberPolyData()->SetLines(vNewLines); + m_manStreamline->SetFiberColors(255, 255, 255); +// m_manStreamline->SetFiberWeights(m_manStreamline->GetFiberWeights()); + + m_NegStreamline->GetFiberPolyData()->DeleteCell(pickedCellID); + m_NegStreamline->GetFiberPolyData()->RemoveDeletedCells(); + + + + + + } + } + else + { + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; +// if (picker == nullptr) +// { + + + picker = vtkSmartPointer<vtkCellPicker>::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard3D); + + + auto vtk_mapper = dynamic_cast<VtkMapper *>(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } +// } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + vtkIdType pickedCellID = picker->GetCellId(); + + + if (picker->GetCellId()==-1) + { + MITK_INFO << "Nothing picked"; + } + else + { + vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New(); + vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New(); + + unsigned int counter = 0; + for ( int i=0; i<m_manStreamline->GetFiberPolyData()->GetNumberOfCells(); i++) + { + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vtkCell* cell = m_NegStreamline->GetFiberPolyData()->GetCell(pickedCellID); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // m_manStreamline = mitk::FiberBundle::New(vNewPolyData); + m_manStreamline->GetFiberPolyData()->SetPoints(vNewPoints); + m_manStreamline->GetFiberPolyData()->SetLines(vNewLines); + m_manStreamline->SetFiberColors(255, 255, 255); + + m_NegStreamline->GetFiberPolyData()->DeleteCell(pickedCellID); + m_NegStreamline->GetFiberPolyData()->RemoveDeletedCells(); + + } + } + RenderingManager::GetInstance()->RequestUpdateAll(); + } + +void mitk::StreamlineInteractor::AddPosStreamlinetolabelsBundle(StateMachineAction *, InteractionEvent *interactionEvent) +{ + MITK_INFO << "TolabelBundle clicked"; + DataInteractor::SetDataNode(m_PosStreamlineNode); + + + auto positionEvent = dynamic_cast<const InteractionPositionEvent *>(interactionEvent); + if (positionEvent == nullptr) + { + MITK_INFO << "no position"; + } + + if (interactionEvent->GetSender()->GetMapperID() == BaseRenderer::Standard2D) + { +// m_PickedHandle = PickFrom2D(positionEvent); + + MITK_INFO << "2D"; + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer<vtkCellPicker>::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard2D); + + auto vtk_mapper = dynamic_cast<VtkMapper *>(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } +// } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + vtkIdType pickedCellID = picker->GetCellId(); + + + + if (picker->GetCellId()==-1) + { + MITK_INFO << "Nothing picked"; + } + else { + + + vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New(); + vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New(); + + unsigned int counter = 0; + for ( int i=0; i<m_manStreamline->GetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vtkCell* cell = m_PosStreamline->GetFiberPolyData()->GetCell(pickedCellID); + + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // m_manStreamline = mitk::FiberBundle::New(vNewPolyData); + m_manStreamline->GetFiberPolyData()->SetPoints(vNewPoints); + m_manStreamline->GetFiberPolyData()->SetLines(vNewLines); + m_manStreamline->SetFiberColors(255, 255, 255); +// m_manStreamline->SetFiberWeights(m_manStreamline->GetFiberWeights()); + + m_PosStreamline->GetFiberPolyData()->DeleteCell(pickedCellID); + m_PosStreamline->GetFiberPolyData()->RemoveDeletedCells(); + + + + + + } + } + else + { + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; +// if (picker == nullptr) +// { + + + picker = vtkSmartPointer<vtkCellPicker>::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard3D); + + + auto vtk_mapper = dynamic_cast<VtkMapper *>(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } +// } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + vtkIdType pickedCellID = picker->GetCellId(); + + + if (picker->GetCellId()==-1) + { + MITK_INFO << "Nothing picked"; + } + else + { + vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New(); + vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New(); + + unsigned int counter = 0; + for ( int i=0; i<m_manStreamline->GetFiberPolyData()->GetNumberOfCells(); i++) + { + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vtkCell* cell = m_PosStreamline->GetFiberPolyData()->GetCell(pickedCellID); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // m_manStreamline = mitk::FiberBundle::New(vNewPolyData); + m_manStreamline->GetFiberPolyData()->SetPoints(vNewPoints); + m_manStreamline->GetFiberPolyData()->SetLines(vNewLines); + m_manStreamline->SetFiberColors(255, 255, 255); + + m_PosStreamline->GetFiberPolyData()->DeleteCell(pickedCellID); + m_PosStreamline->GetFiberPolyData()->RemoveDeletedCells(); + + } + } + RenderingManager::GetInstance()->RequestUpdateAll(); + } + diff --git a/Modules/FiberDissection/Interactor/mitkStreamlineInteractor.h b/Modules/FiberDissection/Interactor/mitkStreamlineInteractor.h new file mode 100644 index 0000000..3b43f1e --- /dev/null +++ b/Modules/FiberDissection/Interactor/mitkStreamlineInteractor.h @@ -0,0 +1,123 @@ +/*============================================================================ + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center (DKFZ) +All rights reserved. + +Use of this source code is governed by a 3-clause BSD license that can be +found in the LICENSE file. + +============================================================================*/ + +#ifndef mitkStreamlineInteractor_h +#define mitkStreamlineInteractor_h + + +#include "MitkFiberDissectionExports.h" + +// MITK includes +#include <mitkDataInteractor.h> +#include <mitkDataNode.h> +#include <mitkGeometry3D.h> +#include <mitkFiberBundle.h> + +// VTK includes +#include <vtkCellPicker.h> +#include <vtkSmartPointer.h> + +// System includes +#include <memory> + + +namespace mitk +{ + class InteractionPositionEvent; + + //! Data interactor to pick streamlines via interaction + //! with a mitk::Streamline. + //! + //! + //! To determine what parts of the object are clicked during interaction, + //! the mappers (2D: custom mapper, 3D: regular surface mapper) are asked + //! for their VTK objects, picking is performed, and the picked point is + //! forwarded to the Streamline object for interpretation. + //! + //! The interactor fills the undo/redo stack with operations on the modified geometry. + //! + //! \sa Streamline + class MITKFIBERDISSECTION_EXPORT StreamlineInteractor : public DataInteractor + { + public: + mitkClassMacro(StreamlineInteractor, DataInteractor); + itkFactorylessNewMacro(Self); + itkCloneMacro(Self); + + //! The node holding the Fiberbundle for visual feedback. + //! This is the node that the interactor is primarily working on + //! (calls DataInteractor::SetDataNode). + + void SetNegativeNode(DataNode *node); + void SetToLabelNode(DataNode *node); + void SetPositiveNode(DataNode *node); + void LabelfromPrediction(bool predlabeling); + + protected: + + void AddStreamlineNegBundle(StateMachineAction *, InteractionEvent *interactionEvent); + + void AddStreamlinePosBundle(StateMachineAction *, InteractionEvent *interactionEvent); + + void AddNegStreamlinetolabelsBundle(StateMachineAction *, InteractionEvent *interactionEvent); + + void AddPosStreamlinetolabelsBundle(StateMachineAction *, InteractionEvent *interactionEvent); + + bool CheckSelection(const InteractionEvent *interactionEvent); + + void SelectStreamline(StateMachineAction *, InteractionEvent *); + + + std::map<BaseRenderer *, vtkSmartPointer<vtkCellPicker>> m_Picker; + + private: + StreamlineInteractor(); + ~StreamlineInteractor() override; + + //! Setup the relation between the XML state machine and this object's methods. + void ConnectActionsAndFunctions() override; + + //! State machine condition: successful Streamline picking + //! \return true when any part of the Streamline has been picked. +// bool HasPickedHandle(const InteractionEvent *); + +// void DecideInteraction(StateMachineAction *, InteractionEvent *interactionEvent); + +// //! Pick a Streamline handle from a 2D event (passing by the 2D mapper) +// Streamline::HandleType PickFrom2D(const InteractionPositionEvent *positionEvent); + +// //! Pick a Streamline handle from a 3D event +// //! (passing by the general surface mapper and the Streamline object) +// Streamline::HandleType PickFrom3D(const InteractionPositionEvent *positionEvent); + +// void UpdateHandleHighlight(); + + //! the Streamline used for visual feedback and picking + mitk::FiberBundle::Pointer m_NegStreamline; + mitk::FiberBundle::Pointer m_PosStreamline; + mitk::FiberBundle::Pointer m_manStreamline; + bool m_predlabeling; +// mitk::FiberBundle::Pointer m_visualStreamline; + mitk::DataNode::Pointer m_NegStreamlineNode; + mitk::DataNode::Pointer m_PosStreamlineNode; + mitk::DataNode::Pointer m_manStreamlineNode; +// mitk::DataNode::Pointer m_visualStreamlineNode; + + + + vtkSmartPointer<vtkPolyData> m_extracted_streamline; + + double m_ColorForHighlight[4]; + + }; +} +#endif diff --git a/Modules/FiberDissection/Interactor/mitkStreamlineInteractorBrush.cpp b/Modules/FiberDissection/Interactor/mitkStreamlineInteractorBrush.cpp new file mode 100644 index 0000000..335500e --- /dev/null +++ b/Modules/FiberDissection/Interactor/mitkStreamlineInteractorBrush.cpp @@ -0,0 +1,1207 @@ +/*============================================================================ + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center (DKFZ) +All rights reserved. + +Use of this source code is governed by a 3-clause BSD license that can be +found in the LICENSE file. + +============================================================================*/ + +#include "mitkStreamlineInteractorBrush.h" +//#include "mitkStreamlineMapper2D.h" + +// MITK includes +#include <mitkInteractionConst.h> +#include <mitkInteractionPositionEvent.h> +#include <mitkInternalEvent.h> +#include <mitkLookupTableProperty.h> +#include <mitkOperationEvent.h> +#include <mitkRotationOperation.h> +#include <mitkScaleOperation.h> +#include <mitkSurface.h> +#include <mitkUndoController.h> +#include <mitkVtkMapper.h> + +// VTK includes +#include <vtkCamera.h> +#include <vtkInteractorObserver.h> +#include <vtkInteractorStyle.h> +#include <vtkMath.h> +#include <vtkPointData.h> +#include <vtkPolyData.h> +#include <vtkRenderWindowInteractor.h> +#include <vtkVector.h> +#include <vtkPolyLine.h> +#include <vtkVectorOperators.h> + +mitk::StreamlineInteractorBrush::StreamlineInteractorBrush() +{ + m_ColorForHighlight[0] = 1.0; + m_ColorForHighlight[1] = 0.5; + m_ColorForHighlight[2] = 0.0; + m_ColorForHighlight[3] = 1.0; + + // TODO if we want to get this configurable, the this is the recipe: + // - make the 2D mapper add corresponding properties to control "enabled" and "color" + // - make the interactor evaluate those properties + // - in an ideal world, modify the state machine on the fly and skip mouse move handling +} + +mitk::StreamlineInteractorBrush::~StreamlineInteractorBrush() +{ +} + +void mitk::StreamlineInteractorBrush::ConnectActionsAndFunctions() +{ +// CONNECT_CONDITION("isoverstreamline", HasPickedHandle); + CONNECT_CONDITION("isoverstreamline", CheckSelection); + CONNECT_FUNCTION("selectstreamline", SelectStreamline); + + CONNECT_FUNCTION("addnegstreamline", AddStreamlineNegBundle); + CONNECT_FUNCTION("addposstreamline", AddStreamlinePosBundle); + CONNECT_FUNCTION("addnegtolabelstreamline", AddNegStreamlinetolabelsBundle); + CONNECT_FUNCTION("addpostolabelstreamline", AddPosStreamlinetolabelsBundle); +// CONNECT_FUNCTION("FeedUndoStack", FeedUndoStack); +} + +void mitk::StreamlineInteractorBrush::SetNegativeNode(DataNode *node) +{ + +// DataInteractor::SetDataNode(node); + m_NegStreamlineNode = node; + m_NegStreamline= dynamic_cast<mitk::FiberBundle *>(node->GetData()); + MITK_INFO << "Negative Node added"; +} + +void mitk::StreamlineInteractorBrush::SetToLabelNode(DataNode *node) +{ + m_manStreamlineNode = node; + DataInteractor::SetDataNode(m_manStreamlineNode); + m_manStreamline = dynamic_cast<mitk::FiberBundle *>(node->GetData()); + MITK_INFO << "Label node added"; +// m_init = false; + +} + +void mitk::StreamlineInteractorBrush::SetPositiveNode(DataNode *node) +{ + + // DataInteractor::SetDataNode(node); + m_PosStreamlineNode = node; + m_PosStreamline= dynamic_cast<mitk::FiberBundle *>(node->GetData()); + MITK_INFO << "Positive Node added"; +} + +void mitk::StreamlineInteractorBrush::LabelfromPrediction(bool predlabeling) +{ + m_predlabeling = predlabeling; + +} + +bool mitk::StreamlineInteractorBrush::CheckSelection(const InteractionEvent *interactionEvent) +{ + /* Save Colorvector here*/ + + const auto *positionEvent = dynamic_cast<const InteractionPositionEvent *>(interactionEvent); + if (positionEvent != nullptr) + { + if (interactionEvent->GetSender()->GetMapperID() == BaseRenderer::Standard2D) + { + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer<vtkCellPicker>::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard2D); + + + auto vtk_mapper = dynamic_cast<VtkMapper *>(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + + + if (picker->GetCellId()==-1 && m_predlabeling==false) + { +// m_manStreamline->SetFiberColors(255, 255, 255); +// vtkSmartPointer<vtkUnsignedCharArray> FiberColors = m_manStreamline->m_FiberColors; + + RenderingManager::GetInstance()->RequestUpdateAll(); + return false; + } + else + { + + return true; + } + } + else { + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer<vtkCellPicker>::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard3D); + + + auto vtk_mapper = dynamic_cast<VtkMapper *>(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + + + if (picker->GetCellId()==-1 && m_predlabeling==false) + { +// m_manStreamline->SetFiberColors(255, 255, 255); + RenderingManager::GetInstance()->RequestUpdateAll(); + return false; + } + else + { + + return true; + } + + } + + + } + else { +// m_manStreamline->SetFiberColors(255, 255, 255); + RenderingManager::GetInstance()->RequestUpdateAll(); + return false; + } + +} + +void mitk::StreamlineInteractorBrush::SelectStreamline(StateMachineAction *, InteractionEvent *interactionEvent) +{ + auto *positionEvent = dynamic_cast<InteractionPositionEvent *>(interactionEvent); + + if (interactionEvent->GetSender()->GetMapperID() == BaseRenderer::Standard2D) + { + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer<vtkCellPicker>::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard2D); + + + auto vtk_mapper = dynamic_cast<VtkMapper *>(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } + // } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + if (m_predlabeling==false) + { + vtkIdType pickedCellID = picker->GetCellId(); + m_manStreamline->SetSingleFiberColor(0.0, 255.0, 0.0, pickedCellID); +// m_manStreamline->SetFloatProperty("shape.tuberadius", 1.0) + } + } + else { + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer<vtkCellPicker>::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard3D); + + + auto vtk_mapper = dynamic_cast<VtkMapper *>(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } + // } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + if (m_predlabeling==false) + { + vtkIdType pickedCellID = picker->GetCellId(); + m_manStreamline->SetSingleFiberColor(0.0, 255.0, 0.0, pickedCellID); +// m_manStreamline->SetFloatProperty("shape.tuberadius", 1.0); + } + } + + + RenderingManager::GetInstance()->RequestUpdateAll(); +} + +void mitk::StreamlineInteractorBrush::AddStreamlinePosBundle(StateMachineAction *, InteractionEvent *interactionEvent) +{ + MITK_INFO << "PositiveBundle clicked"; + DataInteractor::SetDataNode(m_manStreamlineNode); + + auto positionEvent = dynamic_cast<const InteractionPositionEvent *>(interactionEvent); + if (positionEvent == nullptr) + { + MITK_INFO << "no position"; + } + + if (interactionEvent->GetSender()->GetMapperID() == BaseRenderer::Standard2D) + { +// m_PickedHandle = PickFrom2D(positionEvent); + MITK_INFO << "2D"; + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer<vtkCellPicker>::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard2D); + + auto vtk_mapper = dynamic_cast<VtkMapper *>(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } +// } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + vtkIdType pickedCellID = picker->GetCellId(); + + + + if (picker->GetCellId()==-1) + { + MITK_INFO << "Nothing picked"; + } + else { + + + vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New(); + vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New(); + + unsigned int counter = 0; + for ( int i=0; i<m_PosStreamline->GetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_PosStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(pickedCellID); + + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // m_PosStreamline = mitk::FiberBundle::New(vNewPolyData); + m_PosStreamline->GetFiberPolyData()->SetPoints(vNewPoints); + m_PosStreamline->GetFiberPolyData()->SetLines(vNewLines); + m_PosStreamline->SetFiberColors(0, 255, 0); +// m_PosStreamline->SetFiberWeights(m_PosStreamline->GetFiberWeights()); + + m_manStreamline->GetFiberPolyData()->DeleteCell(pickedCellID); + m_manStreamline->GetFiberPolyData()->RemoveDeletedCells(); + if (m_predlabeling==false) + { + vtkSmartPointer<vtkPolyData> vNewPolyData2 = vtkSmartPointer<vtkPolyData>::New(); + vtkSmartPointer<vtkCellArray> vNewLines2 = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkPoints> vNewPoints2 = vtkSmartPointer<vtkPoints>::New(); + + + counter = 0; + for ( int i=0; i<m_manStreamline->GetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints2->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines2->InsertNextCell(container); + counter++; + + } + m_manStreamline->GetFiberPolyData()->SetPoints(vNewPoints2); + m_manStreamline->GetFiberPolyData()->SetLines(vNewLines2); + m_manStreamline->SetFiberColors(255, 255, 255); + } + + + + + + } + } + else + { + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer<vtkCellPicker>::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard3D); + + + auto vtk_mapper = dynamic_cast<VtkMapper *>(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } +// } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + vtkIdType pickedCellID = picker->GetCellId(); + + + + if (picker->GetCellId()==-1) + { + MITK_INFO << "Nothing picked"; + } + else { + + + vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New(); + vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New(); + + unsigned int counter = 0; + for ( int i=0; i<m_PosStreamline->GetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_PosStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(pickedCellID); + + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // m_PosStreamline = mitk::FiberBundle::New(vNewPolyData); + m_PosStreamline->GetFiberPolyData()->SetPoints(vNewPoints); + m_PosStreamline->GetFiberPolyData()->SetLines(vNewLines); + m_PosStreamline->SetFiberColors(0, 255, 0); +// m_PosStreamline->SetFiberWeights(m_PosStreamline->GetFiberWeights()); + + + m_manStreamline->GetFiberPolyData()->DeleteCell(pickedCellID); + m_manStreamline->GetFiberPolyData()->RemoveDeletedCells(); + + if (m_predlabeling==false) + { + vtkSmartPointer<vtkPolyData> vNewPolyData2 = vtkSmartPointer<vtkPolyData>::New(); + vtkSmartPointer<vtkCellArray> vNewLines2 = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkPoints> vNewPoints2 = vtkSmartPointer<vtkPoints>::New(); + + + counter = 0; + for ( int i=0; i<m_manStreamline->GetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints2->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines2->InsertNextCell(container); + counter++; + + } + m_manStreamline->GetFiberPolyData()->SetPoints(vNewPoints2); + m_manStreamline->GetFiberPolyData()->SetLines(vNewLines2); + m_manStreamline->SetFiberColors(255, 255, 255); + } + + } + } + RenderingManager::GetInstance()->RequestUpdateAll(); + } + +void mitk::StreamlineInteractorBrush::AddStreamlineNegBundle(StateMachineAction *, InteractionEvent *interactionEvent) +{ + MITK_INFO << "NegativeBundle clicked"; + + DataInteractor::SetDataNode(m_manStreamlineNode); + + auto positionEvent = dynamic_cast<const InteractionPositionEvent *>(interactionEvent); + if (positionEvent == nullptr) + { + MITK_INFO << "no position"; + } + + if (interactionEvent->GetSender()->GetMapperID() == BaseRenderer::Standard2D) + { +// m_PickedHandle = PickFrom2D(positionEvent); + MITK_INFO << "2D"; + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer<vtkCellPicker>::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard2D); + + auto vtk_mapper = dynamic_cast<VtkMapper *>(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } +// } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + vtkIdType pickedCellID = picker->GetCellId(); + + + + if (picker->GetCellId()==-1) + { + MITK_INFO << "Nothing picked"; + } + else { + + + vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New(); + vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New(); + + unsigned int counter = 0; + for ( int i=0; i<m_NegStreamline->GetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_NegStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(pickedCellID); + + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // m_NegStreamline = mitk::FiberBundle::New(vNewPolyData); + m_NegStreamline->GetFiberPolyData()->SetPoints(vNewPoints); + m_NegStreamline->GetFiberPolyData()->SetLines(vNewLines); + m_NegStreamline->SetFiberColors(255, 0, 0); +// m_NegStreamline->SetFiberWeights(m_NegStreamline->GetFiberWeights()); + + m_manStreamline->GetFiberPolyData()->DeleteCell(pickedCellID); + m_manStreamline->GetFiberPolyData()->RemoveDeletedCells(); + + if (m_predlabeling==false) + { + vtkSmartPointer<vtkPolyData> vNewPolyData2 = vtkSmartPointer<vtkPolyData>::New(); + vtkSmartPointer<vtkCellArray> vNewLines2 = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkPoints> vNewPoints2 = vtkSmartPointer<vtkPoints>::New(); + + + counter = 0; + for ( int i=0; i<m_manStreamline->GetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints2->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines2->InsertNextCell(container); + counter++; + + } + m_manStreamline->GetFiberPolyData()->SetPoints(vNewPoints2); + m_manStreamline->GetFiberPolyData()->SetLines(vNewLines2); + m_manStreamline->SetFiberColors(255, 255, 255); + } + + + + + + } + } + else + { + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; +// if (picker == nullptr) +// { + + + picker = vtkSmartPointer<vtkCellPicker>::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard3D); + + + auto vtk_mapper = dynamic_cast<VtkMapper *>(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } +// } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + vtkIdType pickedCellID = picker->GetCellId(); + + + if (picker->GetCellId()==-1) + { + MITK_INFO << "Nothing picked"; + } + else + { + vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New(); + vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New(); + + unsigned int counter = 0; + for ( int i=0; i<m_NegStreamline->GetFiberPolyData()->GetNumberOfCells(); i++) + { + vtkCell* cell = m_NegStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(pickedCellID); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // m_NegStreamline = mitk::FiberBundle::New(vNewPolyData); + m_NegStreamline->GetFiberPolyData()->SetPoints(vNewPoints); + m_NegStreamline->GetFiberPolyData()->SetLines(vNewLines); + m_NegStreamline->SetFiberColors(255, 0, 0); + + m_manStreamline->GetFiberPolyData()->DeleteCell(pickedCellID); + m_manStreamline->GetFiberPolyData()->RemoveDeletedCells(); + + if (m_predlabeling==false) + { + vtkSmartPointer<vtkPolyData> vNewPolyData2 = vtkSmartPointer<vtkPolyData>::New(); + vtkSmartPointer<vtkCellArray> vNewLines2 = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkPoints> vNewPoints2 = vtkSmartPointer<vtkPoints>::New(); + + + counter = 0; + for ( int i=0; i<m_manStreamline->GetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints2->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines2->InsertNextCell(container); + counter++; + + } + m_manStreamline->GetFiberPolyData()->SetPoints(vNewPoints2); + m_manStreamline->GetFiberPolyData()->SetLines(vNewLines2); + m_manStreamline->SetFiberColors(255, 255, 255); + } + + } + } + RenderingManager::GetInstance()->RequestUpdateAll(); + } + +void mitk::StreamlineInteractorBrush::AddNegStreamlinetolabelsBundle(StateMachineAction *, InteractionEvent *interactionEvent) +{ + MITK_INFO << "TolabelBundle clicked"; + DataInteractor::SetDataNode(m_NegStreamlineNode); + + + auto positionEvent = dynamic_cast<const InteractionPositionEvent *>(interactionEvent); + if (positionEvent == nullptr) + { + MITK_INFO << "no position"; + } + + if (interactionEvent->GetSender()->GetMapperID() == BaseRenderer::Standard2D) + { +// m_PickedHandle = PickFrom2D(positionEvent); + + MITK_INFO << "2D"; + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer<vtkCellPicker>::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard2D); + + auto vtk_mapper = dynamic_cast<VtkMapper *>(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } +// } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + vtkIdType pickedCellID = picker->GetCellId(); + + + + if (picker->GetCellId()==-1) + { + MITK_INFO << "Nothing picked"; + } + else { + + + vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New(); + vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New(); + + unsigned int counter = 0; + for ( int i=0; i<m_manStreamline->GetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vtkCell* cell = m_NegStreamline->GetFiberPolyData()->GetCell(pickedCellID); + + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // m_manStreamline = mitk::FiberBundle::New(vNewPolyData); + m_manStreamline->GetFiberPolyData()->SetPoints(vNewPoints); + m_manStreamline->GetFiberPolyData()->SetLines(vNewLines); + m_manStreamline->SetFiberColors(255, 255, 255); +// m_manStreamline->SetFiberWeights(m_manStreamline->GetFiberWeights()); + + m_NegStreamline->GetFiberPolyData()->DeleteCell(pickedCellID); + m_NegStreamline->GetFiberPolyData()->RemoveDeletedCells(); + + + + + + } + } + else + { + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; +// if (picker == nullptr) +// { + + + picker = vtkSmartPointer<vtkCellPicker>::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard3D); + + + auto vtk_mapper = dynamic_cast<VtkMapper *>(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } +// } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + vtkIdType pickedCellID = picker->GetCellId(); + + + if (picker->GetCellId()==-1) + { + MITK_INFO << "Nothing picked"; + } + else + { + vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New(); + vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New(); + + unsigned int counter = 0; + for ( int i=0; i<m_manStreamline->GetFiberPolyData()->GetNumberOfCells(); i++) + { + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vtkCell* cell = m_NegStreamline->GetFiberPolyData()->GetCell(pickedCellID); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // m_manStreamline = mitk::FiberBundle::New(vNewPolyData); + m_manStreamline->GetFiberPolyData()->SetPoints(vNewPoints); + m_manStreamline->GetFiberPolyData()->SetLines(vNewLines); + m_manStreamline->SetFiberColors(255, 255, 255); + + m_NegStreamline->GetFiberPolyData()->DeleteCell(pickedCellID); + m_NegStreamline->GetFiberPolyData()->RemoveDeletedCells(); + + } + } + RenderingManager::GetInstance()->RequestUpdateAll(); + } + +void mitk::StreamlineInteractorBrush::AddPosStreamlinetolabelsBundle(StateMachineAction *, InteractionEvent *interactionEvent) +{ + MITK_INFO << "TolabelBundle clicked"; + DataInteractor::SetDataNode(m_PosStreamlineNode); + + + auto positionEvent = dynamic_cast<const InteractionPositionEvent *>(interactionEvent); + if (positionEvent == nullptr) + { + MITK_INFO << "no position"; + } + + if (interactionEvent->GetSender()->GetMapperID() == BaseRenderer::Standard2D) + { +// m_PickedHandle = PickFrom2D(positionEvent); + + MITK_INFO << "2D"; + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer<vtkCellPicker>::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard2D); + + auto vtk_mapper = dynamic_cast<VtkMapper *>(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } +// } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + vtkIdType pickedCellID = picker->GetCellId(); + + + + if (picker->GetCellId()==-1) + { + MITK_INFO << "Nothing picked"; + } + else { + + + vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New(); + vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New(); + + unsigned int counter = 0; + for ( int i=0; i<m_manStreamline->GetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vtkCell* cell = m_PosStreamline->GetFiberPolyData()->GetCell(pickedCellID); + + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // m_manStreamline = mitk::FiberBundle::New(vNewPolyData); + m_manStreamline->GetFiberPolyData()->SetPoints(vNewPoints); + m_manStreamline->GetFiberPolyData()->SetLines(vNewLines); + m_manStreamline->SetFiberColors(255, 255, 255); +// m_manStreamline->SetFiberWeights(m_manStreamline->GetFiberWeights()); + + m_PosStreamline->GetFiberPolyData()->DeleteCell(pickedCellID); + m_PosStreamline->GetFiberPolyData()->RemoveDeletedCells(); + + + + + + } + } + else + { + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; +// if (picker == nullptr) +// { + + + picker = vtkSmartPointer<vtkCellPicker>::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard3D); + + + auto vtk_mapper = dynamic_cast<VtkMapper *>(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } +// } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + vtkIdType pickedCellID = picker->GetCellId(); + + + if (picker->GetCellId()==-1) + { + MITK_INFO << "Nothing picked"; + } + else + { + vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New(); + vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New(); + + unsigned int counter = 0; + for ( int i=0; i<m_manStreamline->GetFiberPolyData()->GetNumberOfCells(); i++) + { + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vtkCell* cell = m_PosStreamline->GetFiberPolyData()->GetCell(pickedCellID); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // m_manStreamline = mitk::FiberBundle::New(vNewPolyData); + m_manStreamline->GetFiberPolyData()->SetPoints(vNewPoints); + m_manStreamline->GetFiberPolyData()->SetLines(vNewLines); + m_manStreamline->SetFiberColors(255, 255, 255); + + m_PosStreamline->GetFiberPolyData()->DeleteCell(pickedCellID); + m_PosStreamline->GetFiberPolyData()->RemoveDeletedCells(); + + } + } + RenderingManager::GetInstance()->RequestUpdateAll(); + } + diff --git a/Modules/FiberDissection/Interactor/mitkStreamlineInteractorBrush.h b/Modules/FiberDissection/Interactor/mitkStreamlineInteractorBrush.h new file mode 100644 index 0000000..deb5b8f --- /dev/null +++ b/Modules/FiberDissection/Interactor/mitkStreamlineInteractorBrush.h @@ -0,0 +1,123 @@ +/*============================================================================ + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center (DKFZ) +All rights reserved. + +Use of this source code is governed by a 3-clause BSD license that can be +found in the LICENSE file. + +============================================================================*/ + +#ifndef mitkStreamlineInteractorBrush_h +#define mitkStreamlineInteractorBrush_h + + +#include "MitkFiberDissectionExports.h" + +// MITK includes +#include <mitkDataInteractor.h> +#include <mitkDataNode.h> +#include <mitkGeometry3D.h> +#include <mitkFiberBundle.h> + +// VTK includes +#include <vtkCellPicker.h> +#include <vtkSmartPointer.h> + +// System includes +#include <memory> + + +namespace mitk +{ + class InteractionPositionEvent; + + //! Data interactor to pick streamlines via interaction + //! with a mitk::Streamline. + //! + //! + //! To determine what parts of the object are clicked during interaction, + //! the mappers (2D: custom mapper, 3D: regular surface mapper) are asked + //! for their VTK objects, picking is performed, and the picked point is + //! forwarded to the Streamline object for interpretation. + //! + //! The interactor fills the undo/redo stack with operations on the modified geometry. + //! + //! \sa Streamline + class MITKFIBERDISSECTION_EXPORT StreamlineInteractorBrush : public DataInteractor + { + public: + mitkClassMacro(StreamlineInteractorBrush, DataInteractor); + itkFactorylessNewMacro(Self); + itkCloneMacro(Self); + + //! The node holding the Fiberbundle for visual feedback. + //! This is the node that the interactor is primarily working on + //! (calls DataInteractor::SetDataNode). + + void SetNegativeNode(DataNode *node); + void SetToLabelNode(DataNode *node); + void SetPositiveNode(DataNode *node); + void LabelfromPrediction(bool predlabeling); + + protected: + + void AddStreamlineNegBundle(StateMachineAction *, InteractionEvent *interactionEvent); + + void AddStreamlinePosBundle(StateMachineAction *, InteractionEvent *interactionEvent); + + void AddNegStreamlinetolabelsBundle(StateMachineAction *, InteractionEvent *interactionEvent); + + void AddPosStreamlinetolabelsBundle(StateMachineAction *, InteractionEvent *interactionEvent); + + bool CheckSelection(const InteractionEvent *interactionEvent); + + void SelectStreamline(StateMachineAction *, InteractionEvent *); + + + std::map<BaseRenderer *, vtkSmartPointer<vtkCellPicker>> m_Picker; + + private: + StreamlineInteractorBrush(); + ~StreamlineInteractorBrush() override; + + //! Setup the relation between the XML state machine and this object's methods. + void ConnectActionsAndFunctions() override; + + //! State machine condition: successful Streamline picking + //! \return true when any part of the Streamline has been picked. +// bool HasPickedHandle(const InteractionEvent *); + +// void DecideInteraction(StateMachineAction *, InteractionEvent *interactionEvent); + +// //! Pick a Streamline handle from a 2D event (passing by the 2D mapper) +// Streamline::HandleType PickFrom2D(const InteractionPositionEvent *positionEvent); + +// //! Pick a Streamline handle from a 3D event +// //! (passing by the general surface mapper and the Streamline object) +// Streamline::HandleType PickFrom3D(const InteractionPositionEvent *positionEvent); + +// void UpdateHandleHighlight(); + + //! the Streamline used for visual feedback and picking + mitk::FiberBundle::Pointer m_NegStreamline; + mitk::FiberBundle::Pointer m_PosStreamline; + mitk::FiberBundle::Pointer m_manStreamline; + bool m_predlabeling; +// mitk::FiberBundle::Pointer m_visualStreamline; + mitk::DataNode::Pointer m_NegStreamlineNode; + mitk::DataNode::Pointer m_PosStreamlineNode; + mitk::DataNode::Pointer m_manStreamlineNode; +// mitk::DataNode::Pointer m_visualStreamlineNode; + + + + vtkSmartPointer<vtkPolyData> m_extracted_streamline; + + double m_ColorForHighlight[4]; + + }; +} +#endif diff --git a/Modules/FiberDissection/MachineLearning/mitkStreamlineFeatureExtractor.cpp b/Modules/FiberDissection/MachineLearning/mitkStreamlineFeatureExtractor.cpp new file mode 100644 index 0000000..309c41f --- /dev/null +++ b/Modules/FiberDissection/MachineLearning/mitkStreamlineFeatureExtractor.cpp @@ -0,0 +1,981 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center. + +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ +#include "mitkStreamlineFeatureExtractor.h" + +#define _USE_MATH_DEFINES +#include <math.h> +#include <boost/progress.hpp> +#include <vnl/vnl_sparse_matrix.h> +#include <mitkIOUtil.h> + +namespace mitk{ + +StreamlineFeatureExtractor::StreamlineFeatureExtractor() + : m_NumPoints(40) +{ + +} + +StreamlineFeatureExtractor::~StreamlineFeatureExtractor() +{ + +} + +void StreamlineFeatureExtractor::SetTractogramPrediction(const mitk::FiberBundle::Pointer &TractogramPrediction) +{ + m_TractogramPrediction= TractogramPrediction; +} + +void StreamlineFeatureExtractor::SetTractogramGroundtruth(const mitk::FiberBundle::Pointer &TractogramGroundtruth) +{ + m_TractogramGroundtruth= TractogramGroundtruth; +} + +void StreamlineFeatureExtractor::SetTractogramPlus(const mitk::FiberBundle::Pointer &TractogramPlus) +{ + m_TractogramPlus = TractogramPlus; +} + +void StreamlineFeatureExtractor::SetTractogramMinus(const mitk::FiberBundle::Pointer &TractogramMinus) +{ + m_TractogramMinus = TractogramMinus; +} + +void StreamlineFeatureExtractor::SetTractogramPrototypes(const mitk::FiberBundle::Pointer &TractogramPrototypes, bool standard) +{ + if (standard) + { + MITK_INFO << "Use Standard Prototypes..."; + m_inputPrototypes = mitk::IOUtil::Load<mitk::FiberBundle>("/home/r948e/E132-Projekte/Projects/2022_Peretzke_Interactive_Fiber_Dissection/mitk_diff/prototypes_599671_40.trk"); + } + else { + MITK_INFO << "Use individual Prototypes..."; + m_inputPrototypes = TractogramPrototypes; + } + + +} + +void StreamlineFeatureExtractor::SetActiveCycle(int &activeCycle) +{ + m_activeCycle= activeCycle; +} + + +void StreamlineFeatureExtractor::SetTractogramTest(const mitk::FiberBundle::Pointer &TractogramTest, std::string TractogramTestName) +{ +// std::string path = "/home/r948e/E132-Projekte/Projects/2022_Peretzke_Interactive_Fiber_Dissection/mitk_diff/storage/"; +// path.append(TractogramTestName); + MITK_INFO << TractogramTestName; + m_TractogramTest= TractogramTest; +// auto s = std::to_string(m_NumPoints); +// m_DistancesTestName= path.append("_distances" + std::to_string(m_NumPoints) + "_" + std::to_string(m_activeCycle) + ".csv"); +} + +std::vector<vnl_matrix<float> > StreamlineFeatureExtractor::ResampleFibers(mitk::FiberBundle::Pointer tractogram) +{ + MITK_INFO << "Infunction"; +// mitk::FiberBundle::Pointer temp_fib = tractogram->GetDeepCopy(); +// temp_fib->ResampleToNumPoints(m_NumPoints); + MITK_INFO << "Resampling Done"; + + std::vector< vnl_matrix<float> > out_fib(tractogram->GetFiberPolyData()->GetNumberOfCells()); +//#pragma omp parallel for + for (int i=0; i<tractogram->GetFiberPolyData()->GetNumberOfCells(); i++) + { + vtkCell* cell = tractogram->GetFiberPolyData()->GetCell(i); + int numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vnl_matrix<float> streamline; + streamline.set_size(3, m_NumPoints); + streamline.fill(0.0); + + for (int j=0; j<numPoints; j++) + { + double cand[3]; + points->GetPoint(j, cand); + + vnl_vector_fixed< float, 3 > candV; + candV[0]=cand[0]; candV[1]=cand[1]; candV[2]=cand[2]; + streamline.set_column(j, candV); + } + +// out_fib.push_back(streamline); + out_fib.at(i)=streamline; + } +// }); + + + + return out_fib; +} + +std::vector<vnl_matrix<float> > StreamlineFeatureExtractor::CalculateDmdf(std::vector<vnl_matrix<float> > tractogram, + std::vector<vnl_matrix<float> > prototypes) +{ + + std::vector< vnl_matrix<float> > dist_vec(tractogram.size());// + MITK_INFO << "Start Calculating Dmdf"; +// cv::parallel_for_(cv::Range(0, tractogram.size()), [&](const cv::Range &range) +// { +// for (int i = range.start; i < range.end; i++) +#pragma omp parallel for + for (unsigned int i=0; i<tractogram.size(); i++) + { + vnl_matrix<float> distances; + distances.set_size(1, prototypes.size()); + distances.fill(0.0); + for (unsigned int j=0; j<prototypes.size(); j++) + { + vnl_matrix<float> single_distances; + single_distances.set_size(1, tractogram.at(0).cols()); + single_distances.fill(0.0); + vnl_matrix<float> single_distances_flip; + single_distances_flip.set_size(1, tractogram.at(0).cols()); + single_distances_flip.fill(0.0); + for (unsigned int ik=0; ik<tractogram.at(0).cols(); ik++) + { + double cur_dist; + double cur_dist_flip; + + cur_dist = sqrt(pow(tractogram.at(i).get(0,ik) - prototypes.at(j).get(0,ik), 2.0) + + pow(tractogram.at(i).get(1,ik) - prototypes.at(j).get(1,ik), 2.0) + + pow(tractogram.at(i).get(2,ik) - prototypes.at(j).get(2,ik), 2.0)); + + cur_dist_flip = sqrt(pow(tractogram.at(i).get(0,ik) - prototypes.at(j).get(0,prototypes.at(0).cols()-(ik+1)), 2.0) + + pow(tractogram.at(i).get(1,ik) - prototypes.at(j).get(1,prototypes.at(0).cols()-(ik+1)), 2.0) + + pow(tractogram.at(i).get(2,ik) - prototypes.at(j).get(2,prototypes.at(0).cols()-(ik+1)), 2.0)); + + single_distances.put(0,ik, cur_dist); + single_distances_flip.put(0,ik, cur_dist_flip); + + } + + if (single_distances_flip.mean()> single_distances.mean()) + { + distances.put(0,j, single_distances.mean()); + } + else { + distances.put(0,j, single_distances_flip.mean()); + } + } + dist_vec.at(i) = distances; + } +// }); + MITK_INFO << "Done Calculation"; + MITK_INFO << dist_vec.at(0).size(); + + return dist_vec; +} + +std::vector<vnl_matrix<float> > StreamlineFeatureExtractor::MergeTractogram(std::vector<vnl_matrix<float> > prototypes, + std::vector<vnl_matrix<float> > positive_local_prototypes, + std::vector<vnl_matrix<float> > negative_local_prototypes) +{ + unsigned int pos_locals; + unsigned int neg_locals; + + if (positive_local_prototypes.size() >= 50) + { + pos_locals= 50; + } + else { + pos_locals= positive_local_prototypes.size(); + } + + if (negative_local_prototypes.size() >= 50) + { + neg_locals = 50; + } + else { + neg_locals= negative_local_prototypes.size(); + } + + + + std::vector< vnl_matrix<float> > merged_prototypes; + + for (unsigned int k=0; k<prototypes.size(); k++) + { + merged_prototypes.push_back(prototypes.at(k)); + } + + for (unsigned int k=0; k<positive_local_prototypes.size(); k++) + { + merged_prototypes.push_back(positive_local_prototypes.at(k)); + } + + for (unsigned int k=0; k<negative_local_prototypes.size(); k++) + { + merged_prototypes.push_back(negative_local_prototypes.at(k)); + } + + MITK_INFO << "Number of prototypes:"; + MITK_INFO << prototypes.size(); + MITK_INFO << "Number of positive local prototypes:"; + MITK_INFO << pos_locals; + MITK_INFO << "Number of negative local prototypes:"; + MITK_INFO << neg_locals; + + return merged_prototypes; + +} + + +std::vector<unsigned int> StreamlineFeatureExtractor::Sort(std::vector<float> sortingVector, int lengths, int start) +{ + std::vector<unsigned int> index; + std::priority_queue<std::pair<float, int>> q; + + for (unsigned int i = 0; i < sortingVector.size(); ++i) + { + q.push(std::pair<float, int>(sortingVector[i], i)); + } + + + for (int i = 0; i < lengths; ++i) + { + int ki = q.top().second; + if (i>=start) + { + index.push_back(ki); + } + q.pop(); + } + return index; +} + + +std::vector<std::vector<unsigned int>> StreamlineFeatureExtractor::GetData() +{ + MITK_INFO << "Start Function Get Data"; + + /*Vector which saves Prediction and Fibers to label based on uncertainty*/ + std::vector<std::vector<unsigned int>> index_vec; + +// int labels_arr [m_DistancesPlus.size()+m_DistancesMinus.size()]; + cv::Mat data; + cv::Mat labels_arr_vec; + + int size_plus = 0; + + + /*Create Trainingdata: Go through positive and negative Bundle and save distances as cv::Mat and create vector with labels*/ + for ( unsigned int i=0; i<m_DistancesPlus.size(); i++) + { + float data_arr [m_DistancesPlus.at(0).size()]; +// labels_arr[i]=1; + labels_arr_vec.push_back(1); + + for ( unsigned int j=0; j<m_DistancesPlus.at(0).cols(); j++) + { + data_arr[j] = m_DistancesPlus.at(i).get(0,j); + } + cv::Mat curdata(1, m_DistancesPlus.at(0).size(), CV_32F, data_arr); + data.push_back(curdata); + size_plus++; + + } + + for ( unsigned int i=m_DistancesPlus.size(); i<m_DistancesPlus.size()+m_DistancesMinus.size(); i++) + { + int it = i - size_plus; + float data_arr [m_DistancesMinus.at(0).size()]; +// labels_arr[i]=0; + labels_arr_vec.push_back(0); + + for ( unsigned int j=0; j<m_DistancesMinus.at(0).cols(); j++) + { + data_arr[j] = m_DistancesMinus.at(it).get(0,j); + } + cv::Mat curdata(1, m_DistancesPlus.at(0).size(), CV_32F, data_arr); + data.push_back(curdata); + + } + MITK_INFO << data.cols; + MITK_INFO << data.rows; + + /*Calculate weights*/ + int zerosgt = labels_arr_vec.rows - cv::countNonZero(labels_arr_vec); + int onesgt = cv::countNonZero(labels_arr_vec); + float plusval = labels_arr_vec.rows / (2.0 * onesgt ) ; + float minusval = labels_arr_vec.rows / (2.0 * zerosgt ); + float w[2] = {minusval, plusval}; + cv::Mat newweight = cv::Mat(1,2, CV_32F, w); + MITK_INFO << "Weights"; + MITK_INFO << newweight; + + + /*Shuffle Data*/ + std::vector <int> seeds; + for (int cont = 0; cont < labels_arr_vec.rows; cont++) + { + seeds.push_back(cont); + } + + cv::randShuffle(seeds); + cv::Mat labels_shuffled; + cv::Mat samples_shuffled; + + + + + for (int cont = 0; cont < labels_arr_vec.rows; cont++) + { + labels_shuffled.push_back(labels_arr_vec.row(seeds[cont])); + } + + for (int cont = 0; cont < labels_arr_vec.rows; cont++) + { + samples_shuffled.push_back(data.row(seeds[cont])); + } + + +// std::ofstream labelsfile; +// labelsfile.open("/home/r948e/E132-Projekte/Projects/2022_Peretzke_Interactive_Fiber_Dissection/mitk_diff/storage/Labels_" + std::to_string(m_activeCycle) + ".csv"); +// labelsfile<< cv::format(labels_shuffled, cv::Formatter::FMT_CSV) << std::endl; +// labelsfile.close(); + +// std::ofstream featuresfile; +// featuresfile.open("/home/r948e/E132-Projekte/Projects/2022_Peretzke_Interactive_Fiber_Dissection/mitk_diff/storage/Features_" + std::to_string(m_activeCycle) + ".csv"); +// featuresfile<< cv::format(samples_shuffled, cv::Formatter::FMT_CSV) << std::endl; +// featuresfile.close(); + + /*Create Dataset and initialize Classifier*/ + cv::Ptr<cv::ml::TrainData> m_traindata = cv::ml::TrainData::create(samples_shuffled, cv::ml::ROW_SAMPLE, labels_shuffled); + + + + + statistic_model= cv::ml::RTrees::create(); + auto criteria = cv::TermCriteria(); + criteria.type = cv::TermCriteria::MAX_ITER; +// criteria.epsilon = 1e-8; + criteria.maxCount = 400; + + statistic_model->setMaxDepth(10); //set to three +// statistic_model->setMinSampleCount(m_traindata->getNTrainSamples()*0.01); + statistic_model->setMinSampleCount(2); + statistic_model->setTruncatePrunedTree(false); + statistic_model->setUse1SERule(false); + statistic_model->setUseSurrogates(false); + statistic_model->setTermCriteria(criteria); + statistic_model->setCVFolds(1); + statistic_model->setPriors(newweight); + + + /*Train Classifier*/ + MITK_INFO << "Start Training"; + statistic_model->train(m_traindata); + + + /*Predict on Test Data*/ + MITK_INFO << "Predicting"; + + /*Create Dataset as cv::Mat*/ + cv::Mat dataTest; + for ( unsigned int i=0; i<m_DistancesTest.size(); i++) + { + float data_arr [m_DistancesTest.at(0).size()]; + + for ( unsigned int j=0; j<m_DistancesTest.at(0).cols(); j++) + { + data_arr[j] = m_DistancesTest.at(i).get(0,j); + } + cv::Mat curdata(1, m_DistancesTest.at(0).size(), CV_32F, data_arr); + dataTest.push_back(curdata); + } + + + std::vector<unsigned int> indexPrediction; + std::vector<float> e(m_DistancesTest.size()); + std::vector<int> pred(m_DistancesTest.size()); + + + /*For every Sample/Streamline get Prediction and entropy (=based on counts of Random Forest)*/ + MITK_INFO << "Predicting on all cores"; +#pragma omp parallel for + for (unsigned int i=0; i<m_DistancesTest.size(); i++) + { + + + int val = statistic_model->predict(dataTest.row(i)); + pred.at(i)=val; + + #pragma omp critical + if (val==1) + { + indexPrediction.push_back(i); + } + + + cv::Mat vote; + statistic_model->getVotes(dataTest.row(i), vote, 0); + e.at(i) = ( -(vote.at<int>(1,0)*1.0)/ (vote.at<int>(1,0)+vote.at<int>(1,1)) * log2((vote.at<int>(1,0)*1.0)/ (vote.at<int>(1,0)+vote.at<int>(1,1))) - + (vote.at<int>(1,1)*1.0)/ (vote.at<int>(1,0)+vote.at<int>(1,1))* log2((vote.at<int>(1,1)*1.0)/ (vote.at<int>(1,0)+vote.at<int>(1,1)))); + + if (isnan(e.at(i))) + { + e.at(i)=0; + } + + } + MITK_INFO << "Done"; + + /*Save entropy values for analysis*/ + std::ofstream entropyfile; + entropyfile.open("/home/r948e/mycsv/entropydata_" + std::to_string(m_activeCycle) + ".csv"); + for (unsigned int i = 0; i < e.size(); i++) + { + entropyfile << e.at(i) << ' '; + } + entropyfile.close(); + + std::ofstream predictionfile; + predictionfile.open("/home/r948e/mycsv/predictiondata_" + std::to_string(m_activeCycle) + ".csv"); + for (unsigned int i = 0; i < pred.size(); i++) + { + predictionfile << pred.at(i) << ' '; + } + predictionfile.close(); + + + + + MITK_INFO << "--------------"; + MITK_INFO << "Prediction vector size:"; + MITK_INFO << indexPrediction.size(); + MITK_INFO << "Entropy vector size:"; + entropy_vector = e; + MITK_INFO << e.size(); + + MITK_INFO << "--------------"; + + /*Get index of most unertain data (lengths defines how many data is saved)*/ +// int lengths=500; + int lengths = std::count_if(e.begin(), e.end(),[&](auto const& val){ return val >= 0.95; }); + if (lengths>1500) + { + lengths=1500; + } +// else if (lengths>3000) +// { +// lengths=3000; +// } + + int lengthsCertain = std::count_if(e.begin(), e.end(),[&](auto const& val){ return val < 0.1; }); + + std::vector<unsigned int> indexUnc = Sort(e, lengths, 0); + + std::vector<unsigned int> indexCertain = Sort(e, e.size() , e.size()-lengthsCertain ); + +// std::vector<unsigned int> indexCertainBetween = Sort(e, e.size()-lengthsCertain , lengths); + + MITK_INFO << "Index Certainty Vector size"; + MITK_INFO << indexCertain.size(); + +// for (unsigned int i=indexCertain.size(); i>=0; --i) + std::vector<unsigned int> indexCertainNeg; + std::vector<unsigned int> indexCertainPos; + + for (unsigned int i=0; i<indexCertain.size(); i++) + { + if(pred.at(indexCertain.at(i))==0 ) + { + indexCertainNeg.push_back(indexCertain.at(i)); + } + else { + indexCertainPos.push_back(indexCertain.at(i)); + } + + } + + + // for (unsigned int i=indexCertain.size(); i>=0; --i) +// std::vector<unsigned int> indexCertainBetweenNeg; +// std::vector<unsigned int> indexCertainBetweenPos; + +// for (unsigned int i=0; i<indexCertainBetween.size(); i++) +// { +// if(pred.at(indexCertainBetween.at(i))==0 ) +// { +// indexCertainBetweenNeg.push_back(indexCertainBetween.at(i)); +// } +// else { +// indexCertainBetweenPos.push_back(indexCertainBetween.at(i)); +// } + +// } + + MITK_INFO << "Index Uncertainty Vector size"; + MITK_INFO << indexUnc.size(); + MITK_INFO << "Index Certainty Vector size"; + MITK_INFO << indexCertainPos.size(); + MITK_INFO << indexCertainNeg.size(); + MITK_INFO << indexCertainNeg.size() +indexCertainPos.size(); + MITK_INFO << "Index Certainty between Vector size"; +// MITK_INFO << indexCertainBetweenPos.size(); +// MITK_INFO << indexCertainBetweenNeg.size(); +// MITK_INFO << indexCertainBetweenNeg.size() +indexCertainBetweenPos.size(); + + +// vnl_matrix<float> distances_matrix; + +// distances_matrix.set_size(lengths, lengths); +// distances_matrix.fill(0.0); + +// std::vector<float> distances_matrix_mean; + + +// for (int i=0; i<lengths; i++) +// { +// for (int k=0; k<lengths; k++) +// { +// /*From the length.size() Samples with the highest Entropey calculate the differen between the Features*/ +// vnl_matrix<float> diff = m_DistancesTest.at(indexUnc.at(i)) - m_DistancesTest.at(indexUnc.at(k)); + +// /*Into the eucledean difference matrix, put the distance in Feature Space between every sample pair*/ +// distances_matrix.put(i,k,diff.absolute_value_sum()/m_DistancesTest.at(0).size()); + +// } +// /*For every Sample/Streamline get the mean eucledean distance to all other Samples => one value for every Sample*/ +//// distances_matrix_mean.push_back(distances_matrix.get_row(i).mean()); +//// MITK_INFO << meanval.at(i); + +// } + + + +// /*Index to find values in distancematrix*/ +// std::vector<unsigned int> myidx; +// /*Index to find actual streamlines using indexUnc*/ +// std::vector<unsigned int> indexUncDist; +// /*Start with the Streamline of the highest entropy, which is in distance_matrix at idx 0*/ +// myidx.push_back(0); +// indexUncDist.push_back(indexUnc.at(myidx.at(0))); + +// /*Vecotr that stores minvalues of current iteration*/ +// vnl_matrix<float> cur_vec; +// cur_vec.set_size(1,lengths); +// cur_vec.fill(0.0); +// for (int i=0; i<lengths; i++) +// { + +//// unsigned int cur_i = indexUnc.at(myidx.at(i)); + +// /*Save mean distance of all used Samples*/ +// vnl_matrix<float> sum_matrix; +// sum_matrix.set_size(myidx.size(), lengths); +// sum_matrix.fill(0); +// for (unsigned int ii=0; ii<myidx.size(); ii++) +// { + +// sum_matrix.set_row(ii, distances_matrix.get_column(myidx.at(ii))); +// } + +// for (unsigned int k=0; k<sum_matrix.columns(); k++) +// { +// cur_vec.put(0,k, sum_matrix.get_column(k).min_value()); +// } +// myidx.push_back(cur_vec.arg_max()); + + +// indexUncDist.push_back(indexUnc.at(myidx.at(i+1))); +// sum_matrix.clear(); + +// } + +// MITK_INFO << "Dist_stop"; + + + /*Save Prediction*/ + index_vec.push_back(indexPrediction); + /*Save index of uncertainty measures*/ + index_vec.push_back(indexUnc); + /*Save index of uncertainty measures influenced by distance*/ +// index_vec.push_back(indexUncDist); + /*Save index of certain measures*/ + index_vec.push_back(indexCertainNeg); + /*Save index of certain measures*/ +// index_vec.push_back(indexCertainPos); + /*Save index of certain measures*/ +// index_vec.push_back(indexCertainBetweenNeg); + /*Save index of certain measures*/ +// index_vec.push_back(indexCertainBetweenPos); + + return index_vec; + +} + +std::vector<std::vector<unsigned int>> StreamlineFeatureExtractor::GetDistanceData(float &value) +{ + /*Vector which saves Fibers to be labeled based on fft subset uncertainty*/ + std::vector<std::vector<unsigned int>> index_vec; + + /*Get index of most unertain data (lengths defines how many data is saved)*/ +// int lengths=500; + MITK_INFO << entropy_vector.size(); + int lengths = std::count_if(entropy_vector.begin(), entropy_vector.end(),[&](auto const& val){ return val >= value; }); + if (lengths>1500) + { + lengths=1500; + } + MITK_INFO << lengths; + /*Maybe shuffling of length so not the most uncertain values are chosen*/ + std::vector<unsigned int> indexUnc = Sort(entropy_vector, lengths, 0); + + vnl_matrix<float> distances_matrix; + + distances_matrix.set_size(lengths, lengths); + distances_matrix.fill(0.0); + + std::vector<float> distances_matrix_mean; + + + for (int i=0; i<lengths; i++) + { + for (int k=0; k<lengths; k++) + { + /*From the length.size() Samples with the highest Entropey calculate the differen between the Features*/ + vnl_matrix<float> diff = m_DistancesTest.at(indexUnc.at(i)) - m_DistancesTest.at(indexUnc.at(k)); + + /*Into the eucledean difference matrix, put the distance in Feature Space between every sample pair*/ + distances_matrix.put(i,k,diff.absolute_value_sum()/m_DistancesTest.at(0).size()); + + } + /*For every Sample/Streamline get the mean eucledean distance to all other Samples => one value for every Sample*/ +// distances_matrix_mean.push_back(distances_matrix.get_row(i).mean()); +// MITK_INFO << meanval.at(i); + + } + + MITK_INFO << "Distance Matrix Calculated"; + + /*Index to find values in distancematrix*/ + std::vector<unsigned int> myidx; + /*Index to find actual streamlines using indexUnc*/ + std::vector<unsigned int> indexUncDist; + /*Start with the Streamline of the highest entropy, which is in distance_matrix at idx 0*/ + myidx.push_back(0); + indexUncDist.push_back(indexUnc.at(myidx.at(0))); + + /*Vecotr that stores minvalues of current iteration*/ + vnl_matrix<float> cur_vec; + cur_vec.set_size(1,lengths); + cur_vec.fill(0.0); + for (int i=0; i<lengths; i++) + { + +// unsigned int cur_i = indexUnc.at(myidx.at(i)); + + /*Save mean distance of all used Samples*/ + vnl_matrix<float> sum_matrix; + sum_matrix.set_size(myidx.size(), lengths); + sum_matrix.fill(0); + for (unsigned int ii=0; ii<myidx.size(); ii++) + { + + sum_matrix.set_row(ii, distances_matrix.get_column(myidx.at(ii))); + } + + for (unsigned int k=0; k<sum_matrix.columns(); k++) + { + cur_vec.put(0,k, sum_matrix.get_column(k).min_value()); + } + myidx.push_back(cur_vec.arg_max()); + + + indexUncDist.push_back(indexUnc.at(myidx.at(i+1))); + sum_matrix.clear(); + + } + + MITK_INFO << "Dist_stop"; + + index_vec.push_back(indexUncDist); + + return index_vec; +} + +mitk::FiberBundle::Pointer StreamlineFeatureExtractor::CreatePrediction(std::vector<unsigned int> &index, bool removefrompool) +{ + mitk::FiberBundle::Pointer Prediction; + MITK_INFO << "Create Bundle"; + + vtkSmartPointer<vtkPolyData> FibersData; + FibersData = vtkSmartPointer<vtkPolyData>::New(); + FibersData->SetPoints(vtkSmartPointer<vtkPoints>::New()); + FibersData->SetLines(vtkSmartPointer<vtkCellArray>::New()); + + vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New(); + vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New(); + +// vtkSmartPointer<vtkFloatArray> weights = vtkSmartPointer<vtkFloatArray>::New(); +// weights->SetNumberOfValues(this->GetNumFibers()+fib->GetNumFibers()); + + unsigned int indexSize = index.size(); + unsigned int counter = 0; + MITK_INFO << "Start Loop"; + for (unsigned int i=0; i<indexSize; i++) + { + + vtkCell* cell = m_TractogramTest->GetFiberPolyData()->GetCell(index[i]); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } +// weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + if (removefrompool) + { + for (unsigned int i=0; i<indexSize; i++) + { + m_TractogramTest->GetFiberPolyData()->DeleteCell(index[i]); + } + } + + + + + MITK_INFO << "Counter"; + MITK_INFO << counter; + + + vNewPolyData->SetLines(vNewLines); + vNewPolyData->SetPoints(vNewPoints); + + FibersData = vtkSmartPointer<vtkPolyData>::New(); + FibersData->SetPoints(vtkSmartPointer<vtkPoints>::New()); + FibersData->SetLines(vtkSmartPointer<vtkCellArray>::New()); + FibersData->SetPoints(vNewPoints); + FibersData->SetLines(vNewLines); + + Prediction = mitk::FiberBundle::New(vNewPolyData); + +// Bundle->SetFiberColors(255, 255, 255); + MITK_INFO << "Cells Prediciton"; + MITK_INFO << Prediction->GetFiberPolyData()->GetNumberOfCells(); + MITK_INFO << "Cells Tractorgram"; + MITK_INFO << m_TractogramTest->GetFiberPolyData()->GetNumberOfCells(); + + return Prediction; +} + +std::vector<int> StreamlineFeatureExtractor::CreateLabels(std::vector<vnl_matrix<float> > Testdata, + std::vector<vnl_matrix<float> > Prediction) +{ +// vnl_vector<int> labels; +// vnl_vector.set_size(Testdata.size()); +// vnl_vector.fill(0); + std::vector<int> labels(Testdata.size(), 0); + + +#pragma omp parallel for + for (unsigned int i=0; i<Prediction.size(); i++) + { + for (unsigned int k=0; k<Testdata.size(); k++) + { + if (Testdata.at(k)==Prediction.at(i)) + { + labels.at(k)=1; + } + } + } + + + return labels; + + + + +} + +void StreamlineFeatureExtractor::GenerateData() +{ + MITK_INFO << "Update"; + +// mitk::FiberBundle::Pointer inputPrototypes = mitk::IOUtil::Load<mitk::FiberBundle>("/home/r948e/E132-Projekte/Projects/2022_Peretzke_Interactive_Fiber_Dissection/data/Synt_tract_40_prototypes.trk"); + + std::vector<vnl_matrix<float> > T_Prototypes; + std::vector<vnl_matrix<float> > T_TractogramPlus; + std::vector<vnl_matrix<float> > T_TractogramMinus; + std::vector<vnl_matrix<float> > T_TractogramTest; + std::vector<vnl_matrix<float> > T_mergedPrototypes; + + + MITK_INFO << "Resample Input Prototypes"; + T_Prototypes = ResampleFibers(m_inputPrototypes); + MITK_INFO << "Resample Input Tractogram Minus"; + T_TractogramMinus= ResampleFibers(m_TractogramMinus); + MITK_INFO << "Resample Input Tractogram Plus"; + T_TractogramPlus= ResampleFibers(m_TractogramPlus); + + /* Merge T_Prototypes, T_TractogramMinus and T_TractogramPlus for extra Features*/ + MITK_INFO << "Merging Prototypes"; + T_mergedPrototypes = MergeTractogram(T_Prototypes, T_TractogramPlus, T_TractogramMinus); + + + + + MITK_INFO << "Calculate Features"; + MITK_INFO << "Calculate Minus Features"; + m_DistancesMinus = CalculateDmdf(T_TractogramMinus, T_mergedPrototypes); + MITK_INFO << "Calculate Plus Features"; + m_DistancesPlus = CalculateDmdf(T_TractogramPlus, T_mergedPrototypes); + + MITK_INFO << "Resample Test Data"; + T_TractogramTest= ResampleFibers(m_TractogramTest); + MITK_INFO << "Calculate Features of Test Data"; + m_DistancesTest= CalculateDmdf(T_TractogramTest, T_mergedPrototypes); + + + + + MITK_INFO << "Done with Datacreation"; + m_index =GetData(); + +} + +vnl_vector<float> StreamlineFeatureExtractor::ValidationPipe() +{ + std::vector<vnl_matrix<float> > T_Prototypes; + std::vector<vnl_matrix<float> > T_TractogramPrediction; + std::vector<vnl_matrix<float> > T_TractogramGroundtruth; + std::vector<vnl_matrix<float> > T_TractogramTest; + std::vector<vnl_matrix<float> > DistancesPrediction; + std::vector<vnl_matrix<float> > DistancesGroundtruth; + std::vector<vnl_matrix<float> > DistancesTest; + std::vector<int> LabelsPrediction; + std::vector<int> LabelsGroundtruth; + + MITK_INFO << "Start Resampling"; + T_Prototypes = ResampleFibers(m_inputPrototypes); + T_TractogramPrediction= ResampleFibers(m_TractogramPrediction); + T_TractogramGroundtruth= ResampleFibers(m_TractogramGroundtruth); + T_TractogramTest= ResampleFibers(m_TractogramTest); + + + + MITK_INFO << "Calculate Features"; + DistancesPrediction = CalculateDmdf(T_TractogramPrediction, T_Prototypes); + DistancesGroundtruth = CalculateDmdf(T_TractogramGroundtruth, T_Prototypes); + DistancesTest = CalculateDmdf(T_TractogramTest, T_Prototypes); + + LabelsGroundtruth = CreateLabels(DistancesTest, DistancesGroundtruth); + LabelsPrediction = CreateLabels(DistancesTest, DistancesPrediction); + + std::ofstream LabelsPredictionFile; + LabelsPredictionFile.open("/home/r948e/mycsv/predictionlabels_" + std::to_string(m_activeCycle) + ".csv"); + for (unsigned int i = 0; i < LabelsPrediction.size(); i++) + { + LabelsPredictionFile << LabelsPrediction.at(i) << ' '; + } + LabelsPredictionFile.close(); + + std::ofstream LabelsGroundtruthFile; + LabelsGroundtruthFile.open("/home/r948e/mycsv/groundtruthlabels_" + std::to_string(m_activeCycle) + ".csv"); + for (unsigned int i = 0; i < LabelsGroundtruth.size(); i++) + { + LabelsGroundtruthFile << LabelsGroundtruth.at(i) << ' '; + } + LabelsGroundtruthFile.close(); + + float FP = 0.0; + float FN = 0.0; + float TP = 0.0; + float TN = 0.0; + std::vector<int> indexfp; +//#pragma omp parallel for + for (unsigned int i=0; i<LabelsGroundtruth.size(); i++) + { + if (LabelsGroundtruth.at(i)==1 && LabelsPrediction.at(i)==1) + { + TP +=1; + } + else if (LabelsGroundtruth.at(i)==1 && LabelsPrediction.at(i)==0) + { + FN +=1; + } + else if (LabelsGroundtruth.at(i)==0 && LabelsPrediction.at(i)==1) + { + FP +=1; + indexfp.push_back(i); + } + else if (LabelsGroundtruth.at(i)==0 && LabelsPrediction.at(i)==0) + { + TN +=1; + } + } + + float Precision; + float Recall; + float F1_score; + + MITK_INFO << "TP"; + MITK_INFO << TP; + MITK_INFO << "FP"; + MITK_INFO << FP; + MITK_INFO << "TN"; + MITK_INFO << TN; + MITK_INFO << "FN"; + MITK_INFO << FN; + Precision = TP/(TP + FP); + MITK_INFO << "Precision"; + MITK_INFO << Precision; + Recall = TP/(TP + FN); + MITK_INFO << "Recall"; + MITK_INFO << Recall; + F1_score = (2*Precision*Recall)/(Precision+Recall); + MITK_INFO << "F1_score"; + MITK_INFO << F1_score; + + + + vnl_vector<float> metrics(7); + + metrics.put(0, TP); + metrics.put(1, FP); + metrics.put(2, TN); + metrics.put(3, FN); + metrics.put(4, Precision); + metrics.put(5, Recall); + metrics.put(6, F1_score); + + + + + return metrics; + +} + + +} + + + diff --git a/Modules/FiberDissection/MachineLearning/mitkStreamlineFeatureExtractor.h b/Modules/FiberDissection/MachineLearning/mitkStreamlineFeatureExtractor.h new file mode 100644 index 0000000..c39865e --- /dev/null +++ b/Modules/FiberDissection/MachineLearning/mitkStreamlineFeatureExtractor.h @@ -0,0 +1,129 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center. + +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ +#ifndef StreamlineFeatureExtractor_h +#define StreamlineFeatureExtractor_h + + +#include "MitkFiberDissectionExports.h" +// MITK +#include <mitkPlanarEllipse.h> +#include <mitkFiberBundle.h> + +// ITK +#include <itkProcessObject.h> + +// VTK +#include <vtkSmartPointer.h> +#include <vtkPolyData.h> +#include <vtkCellArray.h> +#include <vtkPoints.h> +#include <vtkPolyLine.h> + +// OpenCV +#include <opencv2/ml.hpp> +#include <opencv2/opencv.hpp> +#include <opencv2/highgui/highgui.hpp> + +namespace mitk{ + +/** +* \brief */ + +class MITKFIBERDISSECTION_EXPORT StreamlineFeatureExtractor +{ +public: + + + StreamlineFeatureExtractor(); + ~StreamlineFeatureExtractor(); + + typedef itk::Image< float, 3 > FloatImageType; + typedef itk::Image< unsigned char, 3 > UcharImageType; + + void Update(){ + this->GenerateData(); + } + +// void Validate(){ +// this->ValidationPipe(); +// } + + + + void SetTractogramGroundtruth(const mitk::FiberBundle::Pointer &Tractogram); + void SetTractogramPrediction(const mitk::FiberBundle::Pointer &Tractogram); + void SetTractogramPlus(const mitk::FiberBundle::Pointer &Tractogram); + void SetTractogramMinus(const mitk::FiberBundle::Pointer &Tractogram); + void SetTractogramTest(const mitk::FiberBundle::Pointer &Tractogram, std::string TractogramTestName); + void SetTractogramPrototypes(const mitk::FiberBundle::Pointer &TractogramPrototypes, bool standard); + void SetActiveCycle(int &activeCycle); + void SetInitRandom(int &initRandom); +// void SetRandomThreshold(int &threshold); + vnl_vector<float> ValidationPipe(); + + + void CreateClassifier(); + std::vector<std::vector<unsigned int>> GetData(); + +// void CreatePrediction(std::vector<unsigned int> &index); + mitk::FiberBundle::Pointer CreatePrediction(std::vector<unsigned int> &index, bool removefrompool); + std::vector<std::vector<unsigned int>> GetDistanceData(float &value); + + mitk::FiberBundle::Pointer m_Prediction; + mitk::FiberBundle::Pointer m_ToLabel; + + std::vector<std::vector<unsigned int>> m_index; + std::vector<float> entropy_vector; + cv::Ptr<cv::ml::RTrees> statistic_model; + + +protected: + + void GenerateData(); +// void ValidationPipe(); + + std::vector<int> CreateLabels(std::vector<vnl_matrix<float> > Testdata, + std::vector<vnl_matrix<float> > Prediction); + std::vector< vnl_matrix<float> > ResampleFibers(FiberBundle::Pointer tractogram); + std::vector<vnl_matrix<float> > CalculateDmdf(std::vector<vnl_matrix<float> > tractogram, + std::vector<vnl_matrix<float> > prototypes); + std::vector< vnl_matrix<float> > MergeTractogram(std::vector<vnl_matrix<float> > prototypes, + std::vector<vnl_matrix<float> > positive_local_prototypes, + std::vector<vnl_matrix<float> > negative_local_prototypes); + std::vector<unsigned int> Sort(std::vector<float> sortingVector, int lengths, int start); + + + + + unsigned int m_NumPoints; + int m_activeCycle; + int m_initRandom; + int m_thresh; + mitk::FiberBundle::Pointer m_TractogramPrediction; + mitk::FiberBundle::Pointer m_TractogramGroundtruth; + mitk::FiberBundle::Pointer m_TractogramPlus; + mitk::FiberBundle::Pointer m_TractogramMinus; + mitk::FiberBundle::Pointer m_TractogramTest; + mitk::FiberBundle::Pointer m_inputPrototypes; + std::string m_DistancesTestName; + std::vector<vnl_matrix<float> > m_DistancesPlus; + std::vector<vnl_matrix<float> > m_DistancesMinus; + std::vector<vnl_matrix<float> > m_DistancesTest; + cv::Ptr<cv::ml::TrainData> m_traindata; +}; +} + +#endif diff --git a/Modules/FiberDissection/files.cmake b/Modules/FiberDissection/files.cmake new file mode 100644 index 0000000..397bf16 --- /dev/null +++ b/Modules/FiberDissection/files.cmake @@ -0,0 +1,27 @@ +set(H_FILES + + #Interactor + Interactor/mitkStreamlineInteractor.h + Interactor/mitkStreamlineInteractorBrush.h + + #MachineLearning + MachineLearning/mitkStreamlineFeatureExtractor.h +) + +set(CPP_FILES + + #Interactor + Interactor/mitkStreamlineInteractor.cpp + Interactor/mitkStreamlineInteractorBrush.cpp + + #MachineLearning + MachineLearning/mitkStreamlineFeatureExtractor.cpp +) + +set(RESOURCE_FILES + # "Interactions" prefix forced by mitk::StateMachine + Interactions/Streamline3DStates.xml + Interactions/Streamline3DConfig.xml + Interactions/StreamlineBrush3DStates.xml + Interactions/StreamlineBrush3DConfig.xml +) diff --git a/Modules/FiberDissection/resource/Interactions/Streamline3DConfig.xml b/Modules/FiberDissection/resource/Interactions/Streamline3DConfig.xml new file mode 100644 index 0000000..e01f2f2 --- /dev/null +++ b/Modules/FiberDissection/resource/Interactions/Streamline3DConfig.xml @@ -0,0 +1,19 @@ +<config> + <event_variant class="MousePressEvent" name="AddNegStreamlineClick"> + <attribute name="EventButton" value="RightMouseButton"/> + <attribute name="Modifiers" value="shift"/> + </event_variant>addtolabelstreamline + <event_variant class="MousePressEvent" name="AddPosStreamlineClick"> + <attribute name="EventButton" value="RightMouseButton"/> + <attribute name="Modifiers" value="alt"/> + </event_variant> + <event_variant class="MousePressEvent" name="AddNegStreamlinetolabelClick"> + <attribute name="EventButton" value="RightMouseButton"/> + <attribute name="Modifiers" value="ctrl,shift"/> + </event_variant> + <event_variant class="MousePressEvent" name="AddPosStreamlinetolabelClick"> + <attribute name="EventButton" value="RightMouseButton"/> + <attribute name="Modifiers" value="ctrl,alt"/> + </event_variant> + <event_variant class="MouseMoveEvent" name="CheckSelected"/> +</config> diff --git a/Modules/FiberDissection/resource/Interactions/Streamline3DStates.xml b/Modules/FiberDissection/resource/Interactions/Streamline3DStates.xml new file mode 100644 index 0000000..5b4f97f --- /dev/null +++ b/Modules/FiberDissection/resource/Interactions/Streamline3DStates.xml @@ -0,0 +1,20 @@ +<statemachine NAME="StreamlineInteractor3D"> + <state name="start" startstate="true" > + <transition event_class="MouseMoveEvent" event_variant="CheckSelected" target="start"> + <condition name="isoverstreamline"/> + <action name="selectstreamline"/> + </transition> + <transition event_class="InteractionPositionEvent" event_variant="AddNegStreamlineClick" target="start"> + <action name="addnegstreamline"/> + </transition> + <transition event_class="InteractionPositionEvent" event_variant="AddPosStreamlineClick" target="start"> + <action name="addposstreamline"/> + </transition> + <transition event_class="InteractionPositionEvent" event_variant="AddNegStreamlinetolabelClick" target="start"> + <action name="addnegtolabelstreamline"/> + </transition> + <transition event_class="InteractionPositionEvent" event_variant="AddPosStreamlinetolabelClick" target="start"> + <action name="addpostolabelstreamline"/> + </transition> + </state> +</statemachine> diff --git a/Modules/FiberDissection/resource/Interactions/StreamlineBrush3DConfig.xml b/Modules/FiberDissection/resource/Interactions/StreamlineBrush3DConfig.xml new file mode 100644 index 0000000..0890749 --- /dev/null +++ b/Modules/FiberDissection/resource/Interactions/StreamlineBrush3DConfig.xml @@ -0,0 +1,19 @@ +<config> + <event_variant class="MouseMoveEvent" name="AddNegStreamlineClick"> + <attribute name="EventButton" value="RightMouseButton"/> + <attribute name="Modifiers" value="shift"/> + </event_variant>addtolabelstreamline + <event_variant class="MouseMoveEvent" name="AddPosStreamlineClick"> + <attribute name="EventButton" value="RightMouseButton"/> + <attribute name="Modifiers" value="alt"/> + </event_variant> + <event_variant class="MouseMoveEvent" name="AddNegStreamlinetolabelClick"> + <attribute name="EventButton" value="RightMouseButton"/> + <attribute name="Modifiers" value="ctrl,shift"/> + </event_variant> + <event_variant class="MouseMoveEvent" name="AddPosStreamlinetolabelClick"> + <attribute name="EventButton" value="RightMouseButton"/> + <attribute name="Modifiers" value="ctrl,alt"/> + </event_variant> + <event_variant class="MouseMoveEvent" name="CheckSelected"/> +</config> diff --git a/Modules/FiberDissection/resource/Interactions/StreamlineBrush3DStates.xml b/Modules/FiberDissection/resource/Interactions/StreamlineBrush3DStates.xml new file mode 100644 index 0000000..5b4f97f --- /dev/null +++ b/Modules/FiberDissection/resource/Interactions/StreamlineBrush3DStates.xml @@ -0,0 +1,20 @@ +<statemachine NAME="StreamlineInteractor3D"> + <state name="start" startstate="true" > + <transition event_class="MouseMoveEvent" event_variant="CheckSelected" target="start"> + <condition name="isoverstreamline"/> + <action name="selectstreamline"/> + </transition> + <transition event_class="InteractionPositionEvent" event_variant="AddNegStreamlineClick" target="start"> + <action name="addnegstreamline"/> + </transition> + <transition event_class="InteractionPositionEvent" event_variant="AddPosStreamlineClick" target="start"> + <action name="addposstreamline"/> + </transition> + <transition event_class="InteractionPositionEvent" event_variant="AddNegStreamlinetolabelClick" target="start"> + <action name="addnegtolabelstreamline"/> + </transition> + <transition event_class="InteractionPositionEvent" event_variant="AddPosStreamlinetolabelClick" target="start"> + <action name="addpostolabelstreamline"/> + </transition> + </state> +</statemachine> diff --git a/Modules/ModuleList.cmake b/Modules/ModuleList.cmake index ac97051..926de49 100644 --- a/Modules/ModuleList.cmake +++ b/Modules/ModuleList.cmake @@ -1,8 +1,9 @@ set(MITK_MODULES DiffusionCore FiberTracking Connectomics MriSimulation DiffusionIO DiffusionCmdApps + FiberDissection ) diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/CMakeLists.txt b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/CMakeLists.txt index 8462ed4..6a48682 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/CMakeLists.txt +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/CMakeLists.txt @@ -1,10 +1,10 @@ # The project name must correspond to the directory name of your plug-in # and must not contain periods. project(org_mitk_gui_qt_diffusionimaging_fiberprocessing) mitk_create_plugin( SUBPROJECTS MITK-Diffusion EXPORT_DIRECTIVE DIFFUSIONIMAGING_FIBERPROCESSING_EXPORT EXPORTED_INCLUDE_SUFFIXES src - MODULE_DEPENDS MitkFiberTracking MitkMriSimulation MitkChart MitkMultilabel MitkModelFit + MODULE_DEPENDS MitkFiberTracking MitkMriSimulation MitkChart MitkMultilabel MitkModelFit MitkQtWidgetsExt MitkFiberDissection ) diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/CMakeLists.txt.user b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/CMakeLists.txt.user new file mode 100644 index 0000000..ab39197 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/CMakeLists.txt.user @@ -0,0 +1,434 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE QtCreatorProject> +<!-- Written by QtCreator 6.0.2, 2022-07-14T14:22:18. --> +<qtcreator> + <data> + <variable>EnvironmentId</variable> + <value type="QByteArray">{7fc4674f-cf78-4922-8cee-e8273e158382}</value> + </data> + <data> + <variable>ProjectExplorer.Project.ActiveTarget</variable> + <value type="qlonglong">0</value> + </data> + <data> + <variable>ProjectExplorer.Project.EditorSettings</variable> + <valuemap type="QVariantMap"> + <value type="bool" key="EditorConfiguration.AutoIndent">true</value> + <value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value> + <value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value> + <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0"> + <value type="QString" key="language">Cpp</value> + <valuemap type="QVariantMap" key="value"> + <value type="QByteArray" key="CurrentPreferences">CppGlobal</value> + </valuemap> + </valuemap> + <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1"> + <value type="QString" key="language">QmlJS</value> + <valuemap type="QVariantMap" key="value"> + <value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value> + </valuemap> + </valuemap> + <value type="qlonglong" key="EditorConfiguration.CodeStyle.Count">2</value> + <value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value> + <value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value> + <value type="int" key="EditorConfiguration.IndentSize">4</value> + <value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value> + <value type="int" key="EditorConfiguration.MarginColumn">80</value> + <value type="bool" key="EditorConfiguration.MouseHiding">true</value> + <value type="bool" key="EditorConfiguration.MouseNavigation">true</value> + <value type="int" key="EditorConfiguration.PaddingMode">1</value> + <value type="bool" key="EditorConfiguration.PreferSingleLineComments">false</value> + <value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value> + <value type="bool" key="EditorConfiguration.ShowMargin">false</value> + <value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value> + <value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value> + <value type="bool" key="EditorConfiguration.SpacesForTabs">true</value> + <value type="int" key="EditorConfiguration.TabKeyBehavior">0</value> + <value type="int" key="EditorConfiguration.TabSize">8</value> + <value type="bool" key="EditorConfiguration.UseGlobal">true</value> + <value type="bool" key="EditorConfiguration.UseIndenter">false</value> + <value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value> + <value type="bool" key="EditorConfiguration.addFinalNewLine">true</value> + <value type="bool" key="EditorConfiguration.cleanIndentation">true</value> + <value type="bool" key="EditorConfiguration.cleanWhitespace">true</value> + <value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value> + <value type="bool" key="EditorConfiguration.inEntireDocument">false</value> + <value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value> + </valuemap> + </data> + <data> + <variable>ProjectExplorer.Project.PluginSettings</variable> + <valuemap type="QVariantMap"> + <valuemap type="QVariantMap" key="AutoTest.ActiveFrameworks"> + <value type="bool" key="AutoTest.Framework.Boost">true</value> + <value type="bool" key="AutoTest.Framework.CTest">false</value> + <value type="bool" key="AutoTest.Framework.Catch">true</value> + <value type="bool" key="AutoTest.Framework.GTest">true</value> + <value type="bool" key="AutoTest.Framework.QtQuickTest">true</value> + <value type="bool" key="AutoTest.Framework.QtTest">true</value> + </valuemap> + <valuemap type="QVariantMap" key="AutoTest.CheckStates"/> + <value type="int" key="AutoTest.RunAfterBuild">0</value> + <value type="bool" key="AutoTest.UseGlobal">true</value> + <valuelist type="QVariantList" key="ClangCodeModel.CustomCommandLineKey"/> + <value type="bool" key="ClangCodeModel.UseGlobalConfig">true</value> + <value type="QString" key="ClangCodeModel.WarningConfigId">Builtin.BuildSystem</value> + <valuemap type="QVariantMap" key="ClangTools"> + <value type="bool" key="ClangTools.AnalyzeOpenFiles">true</value> + <value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value> + <value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value> + <value type="int" key="ClangTools.ParallelJobs">12</value> + <valuelist type="QVariantList" key="ClangTools.SelectedDirs"/> + <valuelist type="QVariantList" key="ClangTools.SelectedFiles"/> + <valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/> + <value type="bool" key="ClangTools.UseGlobalSettings">true</value> + </valuemap> + </valuemap> + </data> + <data> + <variable>ProjectExplorer.Project.Target.0</variable> + <valuemap type="QVariantMap"> + <value type="QString" key="DeviceType">Desktop</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Qt 5.12.12 GCC 64bit</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Qt 5.12.12 GCC 64bit</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{696d7eab-256e-4d8a-89bd-eaa6ae60deb2}</value> + <value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">1</value> + <value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value> + <value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value> + <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0"> + <value type="QString" key="CMake.Build.Type">Debug</value> + <value type="QString" key="CMake.Initial.Parameters">-GUnix Makefiles +-DCMAKE_BUILD_TYPE:STRING=Debug +-DCMAKE_PROJECT_INCLUDE_BEFORE:PATH=%{IDE:ResourcePath}/package-manager/auto-setup.cmake +-DQT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable} +-DCMAKE_PREFIX_PATH:STRING=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_C_COMPILER:STRING=%{Compiler:Executable:C} +-DCMAKE_CXX_COMPILER:STRING=%{Compiler:Executable:Cxx}</value> + <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/r948e/E132-Projekte/Projects/2022_Peretzke_Interactive_Fiber_Dissection/mitk_diff/repo_mitk_diff/mitk-diffusion/Plugins/build-org.mitk.gui.qt.diffusionimaging.fiberprocessing-Qt_5_12_12_GCC_64bit_temporary-Debug</value> + <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> + <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> + <valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets"> + <value type="QString">all</value> + </valuelist> + <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value> + </valuemap> + <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> + </valuemap> + <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1"> + <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> + <valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets"> + <value type="QString">clean</value> + </valuelist> + <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value> + </valuemap> + <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> + </valuemap> + <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> + <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value> + <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/> + <value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value> + <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value> + </valuemap> + <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1"> + <value type="QString" key="CMake.Build.Type">Release</value> + <value type="QString" key="CMake.Initial.Parameters">-GUnix Makefiles +-DCMAKE_BUILD_TYPE:STRING=Release +-DCMAKE_PROJECT_INCLUDE_BEFORE:PATH=%{IDE:ResourcePath}/package-manager/auto-setup.cmake +-DQT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable} +-DCMAKE_PREFIX_PATH:STRING=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_C_COMPILER:STRING=%{Compiler:Executable:C} +-DCMAKE_CXX_COMPILER:STRING=%{Compiler:Executable:Cxx}</value> + <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/r948e/E132-Projekte/Projects/2022_Peretzke_Interactive_Fiber_Dissection/mitk_diff/repo_mitk_diff/mitk-diffusion/Plugins/build-org.mitk.gui.qt.diffusionimaging.fiberprocessing-Qt_5_12_12_GCC_64bit_temporary-Release</value> + <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> + <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> + <valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets"> + <value type="QString">all</value> + </valuelist> + <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value> + </valuemap> + <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> + </valuemap> + <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1"> + <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> + <valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets"> + <value type="QString">clean</value> + </valuelist> + <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value> + </valuemap> + <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> + </valuemap> + <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> + <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value> + <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/> + <value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value> + <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value> + </valuemap> + <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2"> + <value type="QString" key="CMake.Build.Type">RelWithDebInfo</value> + <value type="QString" key="CMake.Initial.Parameters">-GUnix Makefiles +-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo +-DCMAKE_PROJECT_INCLUDE_BEFORE:PATH=%{IDE:ResourcePath}/package-manager/auto-setup.cmake +-DQT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable} +-DCMAKE_PREFIX_PATH:STRING=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_C_COMPILER:STRING=%{Compiler:Executable:C} +-DCMAKE_CXX_COMPILER:STRING=%{Compiler:Executable:Cxx}</value> + <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/r948e/E132-Projekte/Projects/2022_Peretzke_Interactive_Fiber_Dissection/mitk_diff/repo_mitk_diff/mitk-diffusion/Plugins/build-org.mitk.gui.qt.diffusionimaging.fiberprocessing-Qt_5_12_12_GCC_64bit_temporary-RelWithDebInfo</value> + <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> + <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> + <valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets"> + <value type="QString">all</value> + </valuelist> + <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value> + </valuemap> + <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> + </valuemap> + <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1"> + <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> + <valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets"> + <value type="QString">clean</value> + </valuelist> + <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value> + </valuemap> + <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> + </valuemap> + <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> + <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value> + <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/> + <value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value> + <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release with Debug Information</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value> + </valuemap> + <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.3"> + <value type="QString" key="CMake.Build.Type">MinSizeRel</value> + <value type="QString" key="CMake.Initial.Parameters">-GUnix Makefiles +-DCMAKE_BUILD_TYPE:STRING=MinSizeRel +-DCMAKE_PROJECT_INCLUDE_BEFORE:PATH=%{IDE:ResourcePath}/package-manager/auto-setup.cmake +-DQT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable} +-DCMAKE_PREFIX_PATH:STRING=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_C_COMPILER:STRING=%{Compiler:Executable:C} +-DCMAKE_CXX_COMPILER:STRING=%{Compiler:Executable:Cxx}</value> + <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/r948e/E132-Projekte/Projects/2022_Peretzke_Interactive_Fiber_Dissection/mitk_diff/repo_mitk_diff/mitk-diffusion/Plugins/build-org.mitk.gui.qt.diffusionimaging.fiberprocessing-Qt_5_12_12_GCC_64bit_temporary-MinSizeRel</value> + <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> + <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> + <valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets"> + <value type="QString">all</value> + </valuelist> + <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value> + </valuemap> + <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> + </valuemap> + <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1"> + <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> + <valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets"> + <value type="QString">clean</value> + </valuelist> + <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value> + </valuemap> + <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> + </valuemap> + <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> + <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value> + <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/> + <value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value> + <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Minimum Size Release</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value> + </valuemap> + <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.4"> + <value type="QString" key="CMake.Build.Type">Release</value> + <value type="QString" key="CMake.Initial.Parameters">-GUnix Makefiles +-DCMAKE_BUILD_TYPE:STRING=Release +-DCMAKE_PROJECT_INCLUDE_BEFORE:PATH=%{IDE:ResourcePath}/package-manager/auto-setup.cmake +-DQT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable} +-DCMAKE_PREFIX_PATH:STRING=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_C_COMPILER:STRING=%{Compiler:Executable:C} +-DCMAKE_CXX_COMPILER:STRING=%{Compiler:Executable:Cxx}</value> + <value type="QString" key="CMake.Source.Directory">/home/r948e/E132-Projekte/Projects/2022_Peretzke_Interactive_Fiber_Dissection/mitk_diff/mitk</value> + <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/r948e/MITK_Diff/git_build</value> + <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> + <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> + <valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets"> + <value type="QString">all</value> + </valuelist> + <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value> + </valuemap> + <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> + </valuemap> + <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1"> + <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> + <valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets"> + <value type="QString">clean</value> + </valuelist> + <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value> + </valuemap> + <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> + </valuemap> + <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> + <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value> + <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/> + <value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value> + <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release2</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value> + </valuemap> + <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.5"> + <value type="QString" key="CMake.Build.Type">Release</value> + <value type="QString" key="CMake.Initial.Parameters">-GUnix Makefiles +-DCMAKE_BUILD_TYPE:STRING=Release +-DCMAKE_PROJECT_INCLUDE_BEFORE:PATH=%{IDE:ResourcePath}/package-manager/auto-setup.cmake +-DQT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable} +-DCMAKE_PREFIX_PATH:STRING=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_C_COMPILER:STRING=%{Compiler:Executable:C} +-DCMAKE_CXX_COMPILER:STRING=%{Compiler:Executable:Cxx}</value> + <value type="QString" key="CMake.Source.Directory">/home/r948e/E132-Projekte/Projects/2022_Peretzke_Interactive_Fiber_Dissection/mitk_diff/mitk</value> + <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/r948e/MITK_Diff/qt_build</value> + <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> + <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> + <valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets"> + <value type="QString">all</value> + </valuelist> + <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value> + </valuemap> + <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> + </valuemap> + <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1"> + <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> + <valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets"> + <value type="QString">clean</value> + </valuelist> + <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value> + </valuemap> + <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> + </valuemap> + <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> + <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value> + <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/> + <value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value> + <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release3</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value> + </valuemap> + <value type="qlonglong" key="ProjectExplorer.Target.BuildConfigurationCount">6</value> + <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0"> + <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> + <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value> + </valuemap> + <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value> + <valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/> + <value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value> + </valuemap> + <value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value> + <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0"> + <value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value> + <value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value> + <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value> + <valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds"> + <value type="QString">0</value> + <value type="QString">1</value> + <value type="QString">2</value> + <value type="QString">3</value> + <value type="QString">4</value> + <value type="QString">5</value> + <value type="QString">6</value> + <value type="QString">7</value> + <value type="QString">8</value> + <value type="QString">9</value> + <value type="QString">10</value> + <value type="QString">11</value> + <value type="QString">12</value> + <value type="QString">13</value> + <value type="QString">14</value> + </valuelist> + <valuelist type="QVariantList" key="CustomOutputParsers"/> + <value type="int" key="PE.EnvironmentAspect.Base">2</value> + <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value> + <value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value> + <value type="bool" key="RunConfiguration.UseCppDebugger">false</value> + <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value> + <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value> + <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value> + </valuemap> + <value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value> + </valuemap> + </data> + <data> + <variable>ProjectExplorer.Project.TargetCount</variable> + <value type="qlonglong">1</value> + </data> + <data> + <variable>ProjectExplorer.Project.Updater.FileVersion</variable> + <value type="int">22</value> + </data> + <data> + <variable>Version</variable> + <value type="int">22</value> + </data> +</qtcreator> diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/files.cmake b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/files.cmake index 0f586c9..3a42839 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/files.cmake +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/files.cmake @@ -1,63 +1,70 @@ set(SRC_CPP_FILES ) set(INTERNAL_CPP_FILES mitkPluginActivator.cpp QmitkFiberQuantificationView.cpp QmitkFiberProcessingView.cpp QmitkFiberClusteringView.cpp + QmitkInteractiveFiberDissectionView.cpp QmitkFiberFitView.cpp QmitkTractometryView.cpp Perspectives/QmitkFiberProcessingPerspective.cpp ) set(UI_FILES src/internal/QmitkFiberQuantificationViewControls.ui src/internal/QmitkFiberProcessingViewControls.ui src/internal/QmitkFiberClusteringViewControls.ui + src/internal/QmitkInteractiveFiberDissectionViewControls.ui src/internal/QmitkFiberFitViewControls.ui src/internal/QmitkTractometryViewControls.ui ) set(MOC_H_FILES src/internal/mitkPluginActivator.h src/internal/QmitkFiberQuantificationView.h src/internal/QmitkFiberProcessingView.h src/internal/QmitkFiberClusteringView.h + src/internal/QmitkInteractiveFiberDissectionView.h src/internal/QmitkFiberFitView.h src/internal/QmitkTractometryView.h src/internal/Perspectives/QmitkFiberProcessingPerspective.h ) set(CACHED_RESOURCE_FILES plugin.xml resources/FiberBundleOperations.png resources/FiberQuantification.png resources/FiberClustering.png resources/FiberFit.png resources/Tractometry.png resources/circle.png resources/polygon.png + resources/eraze.png + resources/brush.png + resources/highlighter.png ) set(QRC_FILES resources/QmitkFiberprocessing.qrc + resources/QmitkInteractiveFiberDissection.qrc ) set(CPP_FILES ) foreach(file ${SRC_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/${file}) endforeach(file ${SRC_CPP_FILES}) foreach(file ${INTERNAL_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/internal/${file}) endforeach(file ${INTERNAL_CPP_FILES}) diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/plugin.xml b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/plugin.xml index 4150004..4a46258 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/plugin.xml +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/plugin.xml @@ -1,163 +1,171 @@ <?xml version="1.0" encoding="UTF-8"?> <?BlueBerry version="0.1"?> <plugin> <extension point="org.blueberry.ui.views"> <view id="org.mitk.views.fiberquantification" name="Fiber Quantification" category="Fiber processing" class="QmitkFiberQuantificationView" icon="resources/FiberQuantification.png"> <keywordReference id="org.mitk.views.fiberquantification.Keyword"/> </view> + <view id="org.mitk.views.interactivefiberdissection" + name="Interactive Fiber Dissection" + category="Fiber processing" + class="QmitkInteractiveFiberDissectionView" + icon="resources/FiberBundleOperations.png"> + <keywordReference id="org.mitk.views.interactivefiberdissection.Keyword"/> + </view> + <view id="org.mitk.views.fiberprocessing" name="Fiber Processing" category="Fiber processing" class="QmitkFiberProcessingView" icon="resources/FiberBundleOperations.png"> <keywordReference id="org.mitk.views.fiberprocessing.Keyword"/> </view> <view id="org.mitk.views.fiberclustering" name="Fiber Clustering" category="Fiber processing" class="QmitkFiberClusteringView" icon="resources/FiberClustering.png"> <keywordReference id="org.mitk.views.fiberclustering.Keyword"/> </view> <view id="org.mitk.views.fiberfit" name="Fiber Fit" category="Fiber processing" class="QmitkFiberFitView" icon="resources/FiberFit.png"> <keywordReference id="org.mitk.views.fiberfit.Keyword"/> </view> <view id="org.mitk.views.tractometry" name="Tractometry" category="Fiber processing" class="QmitkTractometryView" icon="resources/Tractometry.png"> <keywordReference id="org.mitk.views.tractometry.Keyword"/> </view> </extension> <extension point="org.blueberry.ui.perspectives"> <perspective id="org.mitk.perspectives.fiberprocessings" name="Fiber Processing" class="QmitkFiberProcessingPerspective" icon="resources/FiberBundleOperations.png"> <description>This perspective contains all views necessary to post process fibers.</description> <keywordReference id="org.mitk.perspectives.fiberprocessings.Keyword"/> </perspective> </extension> <extension point="org.blueberry.ui.keywords"> <keyword label="cluster" id="org.mitk.views.fiberclustering.Keyword"/> <keyword label="fiber" id="org.mitk.views.fiberclustering.Keyword"/> <keyword label="quickbundles" id="org.mitk.views.fiberclustering.Keyword"/> <keyword label="clustering" id="org.mitk.views.fiberclustering.Keyword"/> <keyword label="fit" id="org.mitk.views.fiberfit.Keyword"/> <keyword label="sift" id="org.mitk.views.fiberfit.Keyword"/> <keyword label="life" id="org.mitk.views.fiberfit.Keyword"/> <keyword label="fiber" id="org.mitk.views.fiberfit.Keyword"/> <keyword label="processing" id="org.mitk.views.fiberprocessing.Keyword"/> <keyword label="extract" id="org.mitk.views.fiberprocessing.Keyword"/> <keyword label="remove" id="org.mitk.views.fiberprocessing.Keyword"/> <keyword label="fiber" id="org.mitk.views.fiberprocessing.Keyword"/> <keyword label="bundle" id="org.mitk.views.fiberprocessing.Keyword"/> <keyword label="color" id="org.mitk.views.fiberprocessing.Keyword"/> <keyword label="mirror" id="org.mitk.views.fiberprocessing.Keyword"/> <keyword label="threshold" id="org.mitk.views.fiberprocessing.Keyword"/> <keyword label="prune" id="org.mitk.views.fiberprocessing.Keyword"/> <keyword label="select" id="org.mitk.views.fiberprocessing.Keyword"/> <keyword label="segment" id="org.mitk.views.fiberprocessing.Keyword"/> <keyword label="dissect" id="org.mitk.views.fiberprocessing.Keyword"/> <keyword label="modify" id="org.mitk.views.fiberprocessing.Keyword"/> <keyword label="join" id="org.mitk.views.fiberprocessing.Keyword"/> <keyword label="merge" id="org.mitk.views.fiberprocessing.Keyword"/> <keyword label="add" id="org.mitk.views.fiberprocessing.Keyword"/> <keyword label="subtract" id="org.mitk.views.fiberprocessing.Keyword"/> <keyword label="difference" id="org.mitk.views.fiberprocessing.Keyword"/> <keyword label="fiber" id="org.mitk.views.fiberquantification.Keyword"/> <keyword label="quantification" id="org.mitk.views.fiberquantification.Keyword"/> <keyword label="statistics" id="org.mitk.views.fiberquantification.Keyword"/> <keyword label="length" id="org.mitk.views.fiberquantification.Keyword"/> <keyword label="number" id="org.mitk.views.fiberquantification.Keyword"/> <keyword label="principal" id="org.mitk.views.fiberquantification.Keyword"/> <keyword label="direction" id="org.mitk.views.fiberquantification.Keyword"/> <keyword label="peak" id="org.mitk.views.fiberquantification.Keyword"/> <keyword label="main" id="org.mitk.views.fiberquantification.Keyword"/> <keyword label="tract" id="org.mitk.views.fiberquantification.Keyword"/> <keyword label="density" id="org.mitk.views.fiberquantification.Keyword"/> <keyword label="image" id="org.mitk.views.fiberquantification.Keyword"/> <keyword label="TDI" id="org.mitk.views.fiberquantification.Keyword"/> <keyword label="envelope" id="org.mitk.views.fiberquantification.Keyword"/> <keyword label="hull" id="org.mitk.views.fiberquantification.Keyword"/> <keyword label="endpoints" id="org.mitk.views.fiberquantification.Keyword"/> <keyword label="end" id="org.mitk.views.fiberquantification.Keyword"/> <keyword label="endings" id="org.mitk.views.fiberquantification.Keyword"/> <keyword label="cluster" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="fiber" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="quickbundles" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="clustering" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="fit" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="sift" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="life" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="fiber" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="processing" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="extract" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="remove" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="fiber" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="bundle" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="color" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="mirror" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="threshold" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="prune" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="select" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="segment" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="dissect" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="modify" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="join" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="merge" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="add" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="subtract" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="difference" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="fiber" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="quantification" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="statistics" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="length" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="number" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="principal" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="direction" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="peak" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="main" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="tract" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="density" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="image" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="TDI" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="envelope" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="hull" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="endpoints" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="end" id="org.mitk.perspectives.fiberprocessings.Keyword"/> <keyword label="endings" id="org.mitk.perspectives.fiberprocessings.Keyword"/> </extension> </plugin> diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/QmitkInteractiveFiberDissection.qrc b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/QmitkInteractiveFiberDissection.qrc new file mode 100644 index 0000000..047b9e6 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/QmitkInteractiveFiberDissection.qrc @@ -0,0 +1,9 @@ +<RCC> + <qresource prefix="/QmitkInteractiveFiberDissection"> + <file>FiberBundle.png</file> + <file>circle.png</file> + <file>polygon.png</file> + <file>eraze.png</file> + <file>highlighter.png</file> + </qresource> +</RCC> diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/brush.png b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/brush.png new file mode 100644 index 0000000..4fdb238 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/brush.png differ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/eraze.png b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/eraze.png new file mode 100644 index 0000000..d4ac1c0 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/eraze.png differ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/highlighter.png b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/highlighter.png new file mode 100644 index 0000000..4fa7514 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/highlighter.png differ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/Perspectives/QmitkFiberProcessingPerspective.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/Perspectives/QmitkFiberProcessingPerspective.cpp index 038ed58..4ad19e7 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/Perspectives/QmitkFiberProcessingPerspective.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/Perspectives/QmitkFiberProcessingPerspective.cpp @@ -1,52 +1,53 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkFiberProcessingPerspective.h" #include "berryIViewLayout.h" void QmitkFiberProcessingPerspective::CreateInitialLayout(berry::IPageLayout::Pointer layout) { ///////////////////////////////////////////////////// // all di-app perspectives should have the following: ///////////////////////////////////////////////////// QString editorArea = layout->GetEditorArea(); layout->AddStandaloneViewPlaceholder("org.mitk.views.viewnavigatorview", berry::IPageLayout::LEFT, 0.3f, editorArea, false); layout->AddStandaloneView("org.mitk.views.datamanager", false, berry::IPageLayout::LEFT, 0.3f, editorArea); layout->AddStandaloneView("org.mitk.views.controlvisualizationpropertiesview", false, berry::IPageLayout::BOTTOM, .15f, "org.mitk.views.datamanager"); berry::IFolderLayout::Pointer left = layout->CreateFolder("org.mbi.diffusionimaginginternal.leftcontrols", berry::IPageLayout::BOTTOM, 0.15f, "org.mitk.views.controlvisualizationpropertiesview"); layout->AddStandaloneViewPlaceholder("org.mitk.views.imagenavigator", berry::IPageLayout::BOTTOM, .7f, "org.mbi.diffusionimaginginternal.leftcontrols", false); ///////////////////////////////////////////// // here goes the perspective specific stuff ///////////////////////////////////////////// left->AddView("org.mitk.views.fiberprocessing"); left->AddView("org.mitk.views.fiberquantification"); + left->AddView("org.mitk.views.interactivefiberdissection"); left->AddView("org.mitk.views.fiberclustering"); left->AddView("org.mitk.views.fiberfit"); left->AddView("org.mitk.views.tractometry"); } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkInteractiveFiberDissectionView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkInteractiveFiberDissectionView.cpp new file mode 100644 index 0000000..4cf6a57 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkInteractiveFiberDissectionView.cpp @@ -0,0 +1,1767 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center. + +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + + +// Blueberry +#include <berryISelectionService.h> +#include <berryIWorkbenchPart.h> +#include <berryIWorkbenchWindow.h> + +// Qmitk +#include "QmitkInteractiveFiberDissectionView.h" +#include <QmitkRenderWindow.h> //Pointset +#include <QmitkPointListWidget.h> //Pointset + +#include <QMessageBox> + +#include <mitkNodePredicateProperty.h> +#include <mitkImageCast.h> +#include <mitkPointSet.h> +#include <mitkImageAccessByItk.h> +#include <mitkDataNodeObject.h> +#include <mitkTensorImage.h> +#include "mitkNodePredicateDataType.h" +#include <mitkNodePredicateProperty.h> +#include <mitkNodePredicateAnd.h> +#include <mitkNodePredicateNot.h> +#include <mitkNodePredicateOr.h> +//#include <mitkStreamlineFeatureExtractor.h> + +#include <mitkInteractionConst.h> +#include "usModuleRegistry.h" +//#include <itkFiberCurvatureFilter.h> + + +#include <itkResampleImageFilter.h> +#include <itkGaussianInterpolateImageFunction.h> +#include <itkImageRegionIteratorWithIndex.h> +#include <itkTractsToFiberEndingsImageFilter.h> +#include <itkTractDensityImageFilter.h> +#include <itkImageRegion.h> +#include <itkTractsToRgbaImageFilter.h> +#include <itkFiberExtractionFilter.h> + +#include <mitkInteractionEventObserver.h> +#include <vtkCellPicker.h> + +#include <boost/algorithm/string.hpp> +#include <boost/lexical_cast.hpp> + +#include <vnl/vnl_sparse_matrix.h> + +const std::string QmitkInteractiveFiberDissectionView::VIEW_ID = "org.mitk.views.interactivefiberdissection"; +const std::string id_DataManager = "org.mitk.views.datamanager"; +using namespace mitk; + +QmitkInteractiveFiberDissectionView::QmitkInteractiveFiberDissectionView() + : QmitkAbstractView() + , m_Controls( 0 ) + , m_IterationCounter(0) + , m_RandomExtractionCounter(0) + , m_activeCycleCounter(0) + , m_createdStreamlineCounter(0) + , m_StreamlineInteractor(nullptr) +{ + +} + +// Destructor +QmitkInteractiveFiberDissectionView::~QmitkInteractiveFiberDissectionView() +{ + //disable interactor + if (m_StreamlineInteractor != nullptr) + { +// m_StreamlineInteractor->SetStreamlineNode(nullptr); + m_StreamlineInteractor->EnableInteraction(false); + } +} + + +void QmitkInteractiveFiberDissectionView::CreateQtPartControl( QWidget *parent ) +{ + // build up qt view, unless already done + if ( !m_Controls ) + { + // create GUI widgets from the Qt Designer's .ui file + m_Controls = new Ui::QmitkInteractiveFiberDissectionViewControls; + m_Controls->setupUi( parent ); + m_Controls->m_selectedPointSetWidget->SetDataStorage(GetDataStorage());//pointset + m_Controls->m_selectedPointSetWidget->SetNodePredicate(mitk::NodePredicateAnd::New(//pointset + mitk::TNodePredicateDataType<mitk::PointSet>::New(),//pointset + mitk::NodePredicateNot::New(mitk::NodePredicateOr::New(//pointset + mitk::NodePredicateProperty::New("helper object"),//pointset + mitk::NodePredicateProperty::New("hidden object")))));//pointset + + m_Controls->m_selectedPointSetWidget->SetSelectionIsOptional(true);//pointset + m_Controls->m_selectedPointSetWidget->SetAutoSelectNewNodes(true);//pointset + m_Controls->m_selectedPointSetWidget->SetEmptyInfo(QString("Please select a point set"));//pointset + m_Controls->m_selectedPointSetWidget->SetPopUpTitel(QString("Select point set"));//pointsett + + m_Controls->m_BundleBox->SetDataStorage(this->GetDataStorage()); + mitk::TNodePredicateDataType<mitk::FiberBundle>::Pointer isBundle= mitk::TNodePredicateDataType<mitk::FiberBundle>::New(); + m_Controls->m_BundleBox->SetPredicate( isBundle ); + + m_Controls->m_PrototypeBox->SetDataStorage(this->GetDataStorage()); + mitk::TNodePredicateDataType<mitk::FiberBundle>::Pointer isPrototype = mitk::TNodePredicateDataType<mitk::FiberBundle>::New(); + m_Controls->m_PrototypeBox->SetPredicate( isPrototype ); + + m_Controls->m_PredictionBox->SetDataStorage(this->GetDataStorage()); + mitk::TNodePredicateDataType<mitk::FiberBundle>::Pointer isPrediction = mitk::TNodePredicateDataType<mitk::FiberBundle>::New(); + m_Controls->m_PredictionBox->SetPredicate( isPrediction ); + + m_Controls->m_GroundtruthBox->SetDataStorage(this->GetDataStorage()); + mitk::TNodePredicateDataType<mitk::FiberBundle>::Pointer isGroundtruth = mitk::TNodePredicateDataType<mitk::FiberBundle>::New(); + m_Controls->m_GroundtruthBox->SetPredicate( isGroundtruth ); + + m_Controls->m_TestBundleBox->SetDataStorage(this->GetDataStorage()); + mitk::TNodePredicateDataType<mitk::FiberBundle>::Pointer isTestBundle = mitk::TNodePredicateDataType<mitk::FiberBundle>::New(); + m_Controls->m_TestBundleBox->SetPredicate( isTestBundle); + + + + + connect(m_Controls->m_ErazorButton, SIGNAL(toggled(bool)), this, SLOT( RemovefromBundle(bool) ) ); + connect(m_Controls->m_BrushButton, SIGNAL(toggled(bool)), this, SLOT( RemovefromBundleBrush(bool) ) ); + + connect(m_Controls->m_StreamlineCreation, SIGNAL( clicked() ), this, SLOT( CreateStreamline())); + + connect(m_Controls->m_AddRandomFibers, SIGNAL( clicked() ), this, SLOT( ExtractRandomFibersFromTractogram() ) ); //need + + connect(m_Controls->m_TrainClassifier, SIGNAL( clicked() ), this, SLOT( StartAlgorithm( ))); + + connect(m_Controls->m_CreatePrediction, SIGNAL( clicked() ), this, SLOT( CreatePredictionNode( ))); + + connect(m_Controls->m_certainData, SIGNAL( clicked() ), this, SLOT( CreateCertainNode( ))); + + connect(m_Controls->m_AddUncertainFibers, SIGNAL( clicked() ), this, SLOT( CreateUncertaintySampleNode( ))); + + connect(m_Controls->m_AddDistanceFibers, SIGNAL( clicked() ), this, SLOT( CreateDistanceSampleNode( ))); + + connect(m_Controls->m_unclabeling, SIGNAL(toggled(bool)), this, SLOT( RemovefromUncertainty(bool) ) ); //need + + connect(m_Controls->m_unclabelingBrush, SIGNAL(toggled(bool)), this, SLOT( RemovefromUncertaintyBrush(bool) ) ); //need + + connect(m_Controls->m_distlabeling, SIGNAL(toggled(bool)), this, SLOT( RemovefromDistance(bool) ) ); //need + + connect(m_Controls->m_predlabeling, SIGNAL(toggled(bool)), this, SLOT( RemovefromPrediction(bool) ) ); //need + + connect(m_Controls->m_predlabelingBrush, SIGNAL(toggled(bool)), this, SLOT( RemovefromPredictionBrush(bool) ) ); //need + + connect(m_Controls->m_sellabeling, SIGNAL(toggled(bool)), this, SLOT( RemovefromSelection(bool) ) ); //need + + connect(m_Controls->m_ResampleButton, SIGNAL( clicked() ), this, SLOT( ResampleTractogram( ) ) ); + + connect(m_Controls->m_RandomPrototypesButton, SIGNAL( clicked() ), this, SLOT( RandomPrototypes( ) ) ); + + connect(m_Controls->m_SFFPrototypesButton, SIGNAL( clicked() ), this, SLOT( SFFPrototypes( ) ) ); + + connect(m_Controls->m_validate, SIGNAL( clicked() ), this, SLOT( StartValidation( ) ) ); + + connect(m_Controls->m_automaticLabelling, SIGNAL( clicked() ), this, SLOT( AutomaticLabelling( ) ) ); + + connect(m_Controls->m_RemoveCertainData, SIGNAL( clicked() ), this, SLOT( RemoveCertainData( ) ) ); + + connect(m_Controls->m_resetClassifier, SIGNAL( clicked() ), this, SLOT( ResetClassifier( ) ) ); + + + + connect(m_Controls->m_addPointSetPushButton, &QPushButton::clicked,//pointset + this, &QmitkInteractiveFiberDissectionView::OnAddPointSetClicked);//pointset + connect(m_Controls->m_selectedPointSetWidget, &QmitkSingleNodeSelectionWidget::CurrentSelectionChanged,//pointset + this, &QmitkInteractiveFiberDissectionView::OnCurrentSelectionChanged);//pointset + + + + + auto renderWindowPart = this->GetRenderWindowPart();//pointset + if (nullptr != renderWindowPart)//pointset + this->RenderWindowPartActivated(renderWindowPart);//pointset + this->OnCurrentSelectionChanged(m_Controls->m_selectedPointSetWidget->GetSelectedNodes());//pointset + + } + + UpdateGui(); +} + + +void QmitkInteractiveFiberDissectionView::SetFocus() +{ + m_Controls->toolBoxx->setFocus(); + //m_Controls->m_addPointSetPushButton->setFocus();//pointset + UpdateGui(); +} + +void QmitkInteractiveFiberDissectionView::UpdateGui() +{ + m_Controls->m_FibLabel->setText("<font color='red'>nothing selected</font>"); + m_Controls->m_InputData->setTitle("Please Select Input Data"); + + // disable alle frames + + m_Controls->m_ErazorButton->setCheckable(true); + m_Controls->m_ErazorButton->setEnabled(false); + m_Controls->m_BrushButton->setCheckable(true); + m_Controls->m_BrushButton->setEnabled(false); + m_Controls->m_unclabeling->setCheckable(true); + m_Controls->m_unclabeling->setEnabled(false); + m_Controls->m_predlabeling->setCheckable(true); + m_Controls->m_predlabeling->setEnabled(false); + m_Controls->m_unclabelingBrush->setCheckable(true); + m_Controls->m_unclabelingBrush->setEnabled(false); + m_Controls->m_predlabelingBrush->setCheckable(true); + m_Controls->m_predlabelingBrush->setEnabled(false); + m_Controls->m_distlabeling->setCheckable(true); + m_Controls->m_distlabeling->setEnabled(false); + m_Controls->m_sellabeling->setCheckable(true); + m_Controls->m_sellabeling->setEnabled(false); + + + + m_Controls->m_addPointSetPushButton->setEnabled(false); + m_Controls->m_StreamlineCreation->setEnabled(false); + m_Controls->m_TrainClassifier->setEnabled(false); + m_Controls->m_CreatePrediction->setEnabled(false); + m_Controls->m_CreateUncertantyMap->setEnabled(false); + m_Controls->m_Numtolabel->setEnabled(false); + m_Controls->m_Numtolabel2->setEnabled(false); + m_Controls->m_addPointSetPushButton->setEnabled(false); + m_Controls->m_AddRandomFibers->setEnabled(false); + m_Controls->m_AddDistanceFibers->setEnabled(false); + m_Controls->m_AddUncertainFibers->setEnabled(false); +// m_Controls->m_PrototypeBox->setEditable(false); +// m_Controls->m_useStandardP-> + + mitk::DataNode::Pointer curtestnode = m_Controls->m_TestBundleBox->GetSelectedNode(); + bool testnodeSelected = curtestnode.IsNotNull(); + MITK_INFO << testnodeSelected; + bool fibSelected = !m_SelectedFB.empty(); + bool multipleFibsSelected = (m_SelectedFB.size()>1); + bool sthSelected = m_SelectedImageNode.IsNotNull(); + bool psSelected = m_SelectedPS.IsNotNull(); +// bool nfibSelected = !m_newfibersBundleNode.empty(); +// bool posSelected = !m_positiveBundleNode.empty(); + bool nfibSelected = m_newfibersBundleNode.IsNotNull(); +// bool posSelected = !m_positiveBundleNode.IsNotNull(); +// bool negSelected = !m_negativeBundleNode.IsNotNull(); + bool posSelected = this->GetDataStorage()->Exists(m_positiveBundleNode); + bool negSelected = this->GetDataStorage()->Exists(m_negativeBundleNode); + bool indexSelected = !m_index.empty(); + bool uncertaintySelected = this->GetDataStorage()->Exists(m_UncertaintyLabelNode); +// bool distanceSelected = this->GetDataStorage()->Exists(m_DistanceLabelNode); + bool predictionSelected = this->GetDataStorage()->Exists(m_PredictionNode); + + + + // toggle visibility of elements according to selected method + + + // are fiber bundles selected? + if ( testnodeSelected ) + { + m_Controls->m_addPointSetPushButton->setEnabled(true); + m_Controls->m_AddRandomFibers->setEnabled(true); + m_Controls->m_sellabeling->setEnabled(true); + } + + if (fibSelected) + { + m_Controls->m_FibLabel->setText(QString(m_SelectedFB.at(0)->GetName().c_str())); + // more than two bundles needed to join/subtract + if (multipleFibsSelected ) + { + m_Controls->m_FibLabel->setText("multiple bundles selected"); + } + + + + } + + + // is image selected + if ((sthSelected) || (testnodeSelected)) + { + m_Controls->m_addPointSetPushButton->setEnabled(true); + } + + if (psSelected) + { + m_Controls->m_StreamlineCreation->setEnabled(true); + } + + if (nfibSelected && posSelected) + { + m_Controls->m_ErazorButton->setEnabled(true); + m_Controls->m_BrushButton->setEnabled(true); + } + + + if (posSelected && negSelected) + { + m_Controls->m_TrainClassifier->setEnabled(true); + } + + if (indexSelected) + { + m_Controls->m_CreatePrediction->setEnabled(true); + m_Controls->m_AddUncertainFibers->setEnabled(true); + m_Controls->m_Numtolabel->setEnabled(true); + m_Controls->m_AddDistanceFibers->setEnabled(true); + m_Controls->m_Numtolabel2->setEnabled(true); + } + + if (uncertaintySelected) + { + m_Controls->m_unclabeling->setEnabled(true); + m_Controls->m_unclabelingBrush->setEnabled(true); + } + + if (predictionSelected) + { + m_Controls->m_predlabeling->setEnabled(true); + m_Controls->m_predlabelingBrush->setEnabled(true); + } + +// if (distanceSelected) +// { + m_Controls->m_distlabeling->setEnabled(true); +// } + +// if (m_Controls->m_useStandardP->isChecked()) +// { +// m_Controls->m_PrototypeBox->setEditable(true); +// } + + + + + + +} + +void QmitkInteractiveFiberDissectionView::OnEndInteraction() +{ + +} + +void QmitkInteractiveFiberDissectionView::ResampleTractogram() +{ + mitk::DataNode::Pointer node = m_Controls->m_BundleBox->GetSelectedNode(); + auto tractogram = dynamic_cast<mitk::FiberBundle *>(node->GetData()); + mitk::FiberBundle::Pointer tempfib = tractogram->GetDeepCopy(); + + std::vector<int> myvec; + for (unsigned int k=0; k<tempfib->GetNumFibers(); k++) + { + myvec.push_back(k); + } +// auto rng = std::default_random_engine {}; + std::random_shuffle(std::begin(myvec), std::end(myvec)); + + vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New(); + vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New(); + + vtkSmartPointer<vtkFloatArray> weights = vtkSmartPointer<vtkFloatArray>::New(); + + /* Check wether all Streamlines of the bundles are labeled... If all are labeled Skip for Loop*/ + unsigned int counter = 0; + + for (unsigned int i=0; i<tempfib->GetNumFibers(); i++) + { + vtkCell* cell = tempfib->GetFiberPolyData()->GetCell(myvec.at(i)); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + weights->InsertValue(counter, tempfib->GetFiberWeight(myvec.at(i))); + vNewLines->InsertNextCell(container); + counter++; + + } + + vNewPolyData->SetLines(vNewLines); + vNewPolyData->SetPoints(vNewPoints); + + mitk::FiberBundle::Pointer ShuffledBundle = mitk::FiberBundle::New(vNewPolyData); + ShuffledBundle->SetFiberWeights(weights); + + ShuffledBundle->ResampleToNumPoints(40); + MITK_INFO << "Resampling Done"; + + mitk::DataNode::Pointer newnode = mitk::DataNode::New(); + newnode->SetData( ShuffledBundle ); + newnode->SetName( node->GetName() + "_" + std::to_string(40) ); + this->GetDataStorage()->Add(newnode); + UpdateGui(); +} + +void QmitkInteractiveFiberDissectionView::RandomPrototypes() +{ + + + MITK_INFO << "Number of Fibers to use as Prototypes: "; + MITK_INFO << m_Controls->m_NumPrototypes->value(); + + mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(m_Controls->m_BundleBox->GetSelectedNode()->GetData()); + + MITK_INFO << fib->GetNumFibers(); + std::vector<int> myvec; + for (unsigned int k=0; k<fib->GetNumFibers(); k++) + { + myvec.push_back(k); + } +// auto rng = std::default_random_engine {}; + std::random_shuffle(std::begin(myvec), std::end(myvec)); + + vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New(); + vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New(); + + vtkSmartPointer<vtkFloatArray> weights = vtkSmartPointer<vtkFloatArray>::New(); + + /* Check wether all Streamlines of the bundles are labeled... If all are labeled Skip for Loop*/ + unsigned int counter = 0; + + for (int i=0; i<m_Controls->m_NumPrototypes->value(); i++) + { + vtkCell* cell = fib->GetFiberPolyData()->GetCell(myvec.at(i)); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + weights->InsertValue(counter, fib->GetFiberWeight(myvec.at(i))); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vNewPolyData->SetLines(vNewLines); + vNewPolyData->SetPoints(vNewPoints); + + mitk::FiberBundle::Pointer PrototypesBundle = mitk::FiberBundle::New(vNewPolyData); + PrototypesBundle->SetFiberWeights(weights); + + mitk::DataNode::Pointer node = mitk::DataNode::New(); + node->SetData(PrototypesBundle); + node->SetName("Random_Prototypes"); + +// MITK_INFO << "Number of Streamlines in first function"; +// MITK_INFO << m_newfibersBundleNode->GetData()->GetFiberPolyData()->GetNumberOfCells(); + m_Controls->m_PrototypeBox->SetAutoSelectNewItems (true); + this->GetDataStorage()->Add(node); + m_Controls->m_PrototypeBox->SetAutoSelectNewItems (false); + m_Controls->m_useStandardP->setChecked(false); + node->SetVisibility(false); + + +} + +void QmitkInteractiveFiberDissectionView::SFFPrototypes() +{ + + + MITK_INFO << "Number of Fibers to use as Prototypes: "; + MITK_INFO << m_Controls->m_NumPrototypes->value(); + MITK_INFO << "Start Creating Prototypes based on SFF"; + + mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(m_Controls->m_BundleBox->GetSelectedNode()->GetData()); + + /* Get Subset of Tractogram*/ + int size_subset = std::max(1.0, ceil(3.0 * m_Controls->m_NumPrototypes->value() * std::log(m_Controls->m_NumPrototypes->value()))); + + MITK_INFO << fib->GetNumFibers(); + std::vector<int> myvec; + for (unsigned int k=0; k<fib->GetNumFibers(); k++) + { + myvec.push_back(k); + } + +// std::random_shuffle(std::begin(myvec), std::end(myvec)); + + vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New(); + vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New(); + + vtkSmartPointer<vtkFloatArray> weights = vtkSmartPointer<vtkFloatArray>::New(); + + + unsigned int counter = 0; + + for (int i=0; i<size_subset; i++) + { + vtkCell* cell = fib->GetFiberPolyData()->GetCell(myvec.at(i)); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + weights->InsertValue(counter, fib->GetFiberWeight(myvec.at(i))); + vNewLines->InsertNextCell(container); + counter++; + + } + + + vNewPolyData->SetLines(vNewLines); + vNewPolyData->SetPoints(vNewPoints); + + mitk::FiberBundle::Pointer temp_fib = mitk::FiberBundle::New(vNewPolyData); + temp_fib->SetFiberWeights(weights); + + MITK_INFO << temp_fib->GetFiberPolyData()->GetNumberOfCells(); + /* Create std::vector <vnl_matrix> of the SubsetBundle*/ + std::vector< vnl_matrix<float> > out_fib(temp_fib->GetFiberPolyData()->GetNumberOfCells()); + + for (int i=0; i<temp_fib->GetFiberPolyData()->GetNumberOfCells(); i++) + { + vtkCell* cell = temp_fib->GetFiberPolyData()->GetCell(i); + int numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vnl_matrix<float> streamline; + streamline.set_size(3, cell->GetNumberOfPoints()); + streamline.fill(0.0); + + for (int j=0; j<numPoints; j++) + { + double cand[3]; + points->GetPoint(j, cand); + + vnl_vector_fixed< float, 3 > candV; + candV[0]=cand[0]; candV[1]=cand[1]; candV[2]=cand[2]; + streamline.set_column(j, candV); + } + + // out_fib.push_back(streamline); + out_fib.at(i)=streamline; + } + + + /* Calculate the distancematrix of Subset*/ + std::vector< vnl_matrix<float> > dist_vec(out_fib.size());// + cv::parallel_for_(cv::Range(0, out_fib.size()), [&](const cv::Range &range) + { + for (int i = range.start; i < range.end; i++) + + // for (unsigned int i=0; i<tractogram.size(); i++) + { + + vnl_matrix<float> distances; + distances.set_size(1, out_fib.size()); + distances.fill(0.0); + + + for (unsigned int j=0; j<out_fib.size(); j++) + { + vnl_matrix<float> single_distances; + single_distances.set_size(1, out_fib.at(0).cols()); + single_distances.fill(0.0); + vnl_matrix<float> single_distances_flip; + single_distances_flip.set_size(1, out_fib.at(0).cols()); + single_distances_flip.fill(0.0); + for (unsigned int ik=0; ik<out_fib.at(0).cols(); ik++) + { + double cur_dist; + double cur_dist_flip; + + cur_dist = sqrt(pow(out_fib.at(i).get(0,ik) - out_fib.at(j).get(0,ik), 2.0) + + pow(out_fib.at(i).get(1,ik) - out_fib.at(j).get(1,ik), 2.0) + + pow(out_fib.at(i).get(2,ik) - out_fib.at(j).get(2,ik), 2.0)); + + cur_dist_flip = sqrt(pow(out_fib.at(i).get(0,ik) - out_fib.at(j).get(0,out_fib.at(0).cols()-(ik+1)), 2.0) + + pow(out_fib.at(i).get(1,ik) - out_fib.at(j).get(1,out_fib.at(0).cols()-(ik+1)), 2.0) + + pow(out_fib.at(i).get(2,ik) - out_fib.at(j).get(2,out_fib.at(0).cols()-(ik+1)), 2.0)); + + single_distances.put(0,ik, cur_dist); + single_distances_flip.put(0,ik, cur_dist_flip); + + } + + if (single_distances_flip.mean()> single_distances.mean()) + { + distances.put(0,j, single_distances.mean()); + } + else { + distances.put(0,j, single_distances_flip.mean()); + } + + + + } + // dist_vec.push_back(distances); + dist_vec.at(i) = distances; + } + }); + + + /*Index to find values in distancematrix*/ + std::vector<unsigned int> myidx; + /*Index to find actual streamlines using indexUnc*/ + std::vector<unsigned int> indexUncDist; + /*Start with the Streamline of the highest entropy, which is in distance_matrix at idx 0*/ + myidx.push_back(0); + + /*Vecotr that stores minvalues of current iteration*/ + vnl_matrix<float> cur_vec; + cur_vec.set_size(1, size_subset); + cur_vec.fill(0.0); + for (int i=0; i<m_Controls->m_NumPrototypes->value(); i++) + { + + // unsigned int cur_i = indexUnc.at(myidx.at(i)); + + /*Save mean distance of all used Samples*/ + + vnl_matrix<float> sum_matrix; + sum_matrix.set_size(myidx.size(), size_subset); + sum_matrix.fill(0); + for (unsigned int ii=0; ii<myidx.size(); ii++) + { + + sum_matrix.set_row(ii, dist_vec.at(myidx.at(ii)).get_row(0)); + } + + for (unsigned int k=0; k<sum_matrix.columns(); k++) + { + cur_vec.put(0,k, sum_matrix.get_column(k).min_value()); + } + myidx.push_back(cur_vec.arg_max()); + sum_matrix.clear(); + + } + vtkSmartPointer<vtkPolyData> vNewPolyData2 = vtkSmartPointer<vtkPolyData>::New(); + vtkSmartPointer<vtkCellArray> vNewLines2 = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkPoints> vNewPoints2 = vtkSmartPointer<vtkPoints>::New(); + + vtkSmartPointer<vtkFloatArray> weights2 = vtkSmartPointer<vtkFloatArray>::New(); + + /* Check wether all Streamlines of the bundles are labeled... If all are labeled Skip for Loop*/ + counter = 0; + + for (int i=0; i<m_Controls->m_NumPrototypes->value(); i++) + { + + vtkCell* cell = fib->GetFiberPolyData()->GetCell(myidx.at(i)); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints2->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + weights2->InsertValue(counter, fib->GetFiberWeight(myvec.at(i))); + vNewLines2->InsertNextCell(container); + counter++; + + } + + vNewPolyData2->SetLines(vNewLines2); + vNewPolyData2->SetPoints(vNewPoints2); + + mitk::FiberBundle::Pointer PrototypesBundle = mitk::FiberBundle::New(vNewPolyData2); + PrototypesBundle->SetFiberWeights(weights2); + MITK_INFO << PrototypesBundle->GetFiberPolyData()->GetNumberOfCells(); + + + + mitk::DataNode::Pointer node = mitk::DataNode::New(); + node->SetData(PrototypesBundle); + node->SetName("SFF_Prototypes"); + +//// MITK_INFO << "Number of Streamlines in first function"; +//// MITK_INFO << m_newfibersBundleNode->GetData()->GetFiberPolyData()->GetNumberOfCells(); + m_Controls->m_PrototypeBox->SetAutoSelectNewItems (true); + this->GetDataStorage()->Add(node); + m_Controls->m_PrototypeBox->SetAutoSelectNewItems (false); + m_Controls->m_useStandardP->setChecked(false); + node->SetVisibility(false); + + + +} + +void QmitkInteractiveFiberDissectionView::OnAddPointSetClicked()//pointset +{ + // ask for the name of the point set + bool ok = false; + QString name = QInputDialog::getText(QApplication::activeWindow(), + tr("Add point set..."), tr("Enter name for the new point set"), QLineEdit::Normal, tr("PointSet").arg(++m_IterationCounter), &ok); +// QString name = "PointSet"; + if (!ok || name.isEmpty()) + { + return; + } + mitk::PointSet::Pointer pointSet = mitk::PointSet::New(); + mitk::DataNode::Pointer pointSetNode = mitk::DataNode::New(); + pointSetNode->SetData(pointSet); + pointSetNode->SetProperty("name", mitk::StringProperty::New(name.toStdString())); + pointSetNode->SetProperty("opacity", mitk::FloatProperty::New(1)); + pointSetNode->SetColor(1.0, 1.0, 0.0); + m_testnode = m_Controls->m_TestBundleBox->GetSelectedNode(); + this->GetDataStorage()->Add(pointSetNode, m_testnode); + + + m_Controls->m_selectedPointSetWidget->SetCurrentSelectedNode(pointSetNode); +} + +void QmitkInteractiveFiberDissectionView::OnCurrentSelectionChanged(QmitkSingleNodeSelectionWidget::NodeList /*nodes*/)//pointset +{ + + m_Controls->m_poinSetListWidget->SetPointSetNode(m_Controls->m_selectedPointSetWidget->GetSelectedNode()); + m_SelectedPS = m_Controls->m_selectedPointSetWidget->GetSelectedNode(); + +// m_Controls->m_trainbundleWidget->SetPointSetNode(m_Controls->m_trainbundleWidget->GetSelectedNode()); +// m_trainbundle = m_Controls->m_trainbundleWidget->GetSelectedNode(); + + + UpdateGui(); + +} + +void QmitkInteractiveFiberDissectionView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*part*/, const QList<mitk::DataNode::Pointer>& nodes) +{ + + m_SelectedFB.clear(); + + if (nodes.empty() || nodes.front().IsNull()) + { + m_SelectedImageNode = nullptr; + } + else + { + m_SelectedImageNode = nodes.front(); + } + + + + for (auto node: nodes) + { + if (dynamic_cast<mitk::Image*>(node->GetData())) + m_SelectedImage = dynamic_cast<mitk::Image*>(node->GetData()); + else if ( dynamic_cast<mitk::FiberBundle*>(node->GetData()) ) + m_SelectedFB.push_back(node); + } + + + + UpdateGui(); +} + +void QmitkInteractiveFiberDissectionView::RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart)//pointset +{ + if (nullptr != m_Controls) + { + m_Controls->m_poinSetListWidget->AddSliceNavigationController(renderWindowPart->GetQmitkRenderWindow("axial")->GetSliceNavigationController()); + m_Controls->m_poinSetListWidget->AddSliceNavigationController(renderWindowPart->GetQmitkRenderWindow("sagittal")->GetSliceNavigationController()); + m_Controls->m_poinSetListWidget->AddSliceNavigationController(renderWindowPart->GetQmitkRenderWindow("coronal")->GetSliceNavigationController()); + } +} + +void QmitkInteractiveFiberDissectionView::RenderWindowPartDeactivated(mitk::IRenderWindowPart* renderWindowPart)//pointset +{ + if (nullptr != m_Controls) + { + m_Controls->m_poinSetListWidget->RemoveSliceNavigationController(renderWindowPart->GetQmitkRenderWindow("axial")->GetSliceNavigationController()); + m_Controls->m_poinSetListWidget->RemoveSliceNavigationController(renderWindowPart->GetQmitkRenderWindow("sagittal")->GetSliceNavigationController()); + m_Controls->m_poinSetListWidget->RemoveSliceNavigationController(renderWindowPart->GetQmitkRenderWindow("coronal")->GetSliceNavigationController()); + } +} + +void QmitkInteractiveFiberDissectionView::CreateStreamline() +{ + + if (m_positiveBundleNode.IsNull()) + { + mitk::DataNode::Pointer node = mitk::DataNode::New(); + + m_positiveFibersData = vtkSmartPointer<vtkPolyData>::New(); + m_positiveFibersData->SetPoints(vtkSmartPointer<vtkPoints>::New()); + m_positiveFibersData->SetLines(vtkSmartPointer<vtkCellArray>::New()); + m_positiveBundle = mitk::FiberBundle:: New(m_positiveFibersData); + + node->SetData( m_positiveBundle ); + node->SetData(m_negativeBundle); +// node->SetFloatProperty("shape.tuberadius", 0.5); +// mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + m_positiveBundleNode = node; + this->GetDataStorage()->Add(m_positiveBundleNode); + MITK_INFO << "Create Bundle"; + } + + if (!m_positiveBundleNode.IsNull()) + { + + this->GetDataStorage()->Remove(m_positiveBundleNode); + MITK_INFO << "Adding fibers"; + MITK_INFO << m_positiveBundle->GetFiberPolyData()->GetNumberOfCells(); + m_positiveFibersData = m_positiveBundle->GetFiberPolyData(); + } + + + + + + vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New(); + vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New(); + + + + unsigned int counter = 0; + for (unsigned int i=0; i<m_positiveFibersData->GetNumberOfCells(); ++i) + { + MITK_INFO<< "New Line"; + vtkCell* cell = m_positiveFibersData->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; ++j) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + + vNewLines->InsertNextCell(container); + counter++; + } + + mitk::PointSet::Pointer pointSet = dynamic_cast<mitk::PointSet *>(m_SelectedPS->GetData()); + + + vnl_matrix<float> streamline; + streamline.set_size(3, pointSet->GetSize()); + streamline.fill(0.0); + + + mitk::PointSet::PointsIterator begin = pointSet->Begin(); + mitk::PointSet::PointsIterator end = pointSet->End(); + unsigned int i; + mitk::PointSet::PointsContainer::Iterator it; + + for (it = begin, i = 0; it != end; ++it, ++i) + { + PointSet::PointType pt = pointSet->GetPoint(it->Index()); + vnl_vector_fixed< float, 3 > candV; + candV[0]=pt[0]; candV[1]=pt[1]; candV[2]=pt[2]; + streamline.set_column(i, candV); + } + + // build Fiber + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + + + for (unsigned int j=0; j<streamline.cols(); j++) + { + double p[3]; + p[0] = streamline.get(0,j); + p[1] = streamline.get(1,j); + p[2] = streamline.get(2,j); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + MITK_INFO<< "Last Line from current pointset"; + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + m_positiveFibersData = vtkSmartPointer<vtkPolyData>::New(); + m_positiveFibersData->SetPoints(vtkSmartPointer<vtkPoints>::New()); + m_positiveFibersData->SetLines(vtkSmartPointer<vtkCellArray>::New()); + m_positiveFibersData->SetPoints(vNewPoints); + m_positiveFibersData->SetLines(vNewLines); + + m_positiveBundle = mitk::FiberBundle::New(vNewPolyData); + m_positiveBundle->ResampleToNumPoints(40); + MITK_INFO << "Resampling Done"; + + + m_positiveBundle->SetFiberColors(0, 255, 0); + + + + mitk::DataNode::Pointer node = mitk::DataNode::New(); + node->SetData(m_positiveBundle); + node->SetName("+Bundle"); +// node->SetFloatProperty("shape.tuberadius", 0.5); +// mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + + m_positiveBundleNode= node; + + + + MITK_INFO << "The + Bundle has Streamlines:"; + auto m_PosStreamline= dynamic_cast<mitk::FiberBundle *>(m_positiveBundleNode->GetData()); + MITK_INFO << m_PosStreamline->GetFiberPolyData()->GetNumberOfCells(); + + this->GetDataStorage()->Add(m_positiveBundleNode); +// m_Controls->m_selectedPointSetWidget->m_ToggleAddPoint->setEnabled(false); + + UpdateGui(); + m_createdStreamlineCounter +=1; + +} + +void QmitkInteractiveFiberDissectionView::ExtractRandomFibersFromTractogram() +{ + m_testnode = m_Controls->m_TestBundleBox->GetSelectedNode(); + m_testnode->SetVisibility(false); +// m_SelectedFB.at(0)->SetVisibility(false); + m_Controls->m_ErazorButton->setChecked(false); + m_Controls->m_BrushButton->setChecked(false); + + + MITK_INFO << "Number of Fibers to extract from Tractogram: "; + MITK_INFO << m_Controls->m_NumRandomFibers->value(); + if (this->GetDataStorage()->Exists(m_newfibersBundleNode)) + { + MITK_INFO << "To Label Bundle Exists"; + mitk::FiberBundle::Pointer Stack = dynamic_cast<mitk::FiberBundle *>(m_newfibersBundleNode->GetData()); + this->GetDataStorage()->Remove(m_newfibersBundleNode); + + mitk::DataNode::Pointer node = mitk::DataNode::New(); + + m_newfibersFibersData = vtkSmartPointer<vtkPolyData>::New(); + m_newfibersFibersData->SetPoints(vtkSmartPointer<vtkPoints>::New()); + m_newfibersBundle = mitk::FiberBundle:: New(m_newfibersFibersData); + m_newfibersFibersData->SetLines(vtkSmartPointer<vtkCellArray>::New()); + +// node->SetData( m_newfibersBundle ); +// m_newfibersBundleNode = node ; + + MITK_INFO << "Create Bundle"; + } + + mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(m_testnode->GetData()); + // mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(m_SelectedFB.at(0)->GetData()); +// mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle *>(m_trainbundle->GetData()); + + vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New(); + vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New(); + + vtkSmartPointer<vtkFloatArray> weights = vtkSmartPointer<vtkFloatArray>::New(); +// weights->SetNumberOfValues(this->GetNumFibers()+fib->GetNumFibers()); + +// MITK_INFO << fib->GetNumFibers(); +// std::vector<int> myvec; +// for (unsigned int k=0; k<fib->GetNumFibers(); k++) +// { +// myvec.push_back(k); +// } +// std::random_shuffle(std::begin(myvec), std::end(myvec)); + + /* Check weather all Streamlines of the bundles are labeled... If all are labeled Skip for Loop*/ + unsigned int counter = 0; +// int thresh1; +// int thresh2; +// thresh2 = m_Controls->m_NumRandomFibers->value()*(m_RandomExtractionCounter+1); +// thresh1 = m_Controls->m_NumRandomFibers->value()*(m_RandomExtractionCounter); +// if (thresh1>fib->GetFiberPolyData()->GetNumberOfCells()) +// { +// thresh1=fib->GetFiberPolyData()->GetNumberOfCells(); +// } +// if (thresh2>fib->GetFiberPolyData()->GetNumberOfCells()) +// { +// thresh2=fib->GetFiberPolyData()->GetNumberOfCells(); +// } + +// if (thresh1!=fib->GetFiberPolyData()->GetNumberOfCells()) + if (m_Controls->m_NumRandomFibers->value()!=fib->GetFiberPolyData()->GetNumberOfCells()) + { +// for ( int i=thresh1; i<thresh2; i++) + for ( int i=0; i<m_Controls->m_NumRandomFibers->value(); i++) + { + vtkCell* cell = fib->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + + counter++; + + } + + for ( int i=0; i<m_Controls->m_NumRandomFibers->value(); i++) + { + fib->GetFiberPolyData()->DeleteCell(i); + } + fib->GetFiberPolyData()->RemoveDeletedCells(); + + MITK_INFO << fib->GetFiberPolyData()->GetNumberOfCells(); + +// m_SelectedFB.at(0)->SetData(fib); + + vNewPolyData->SetLines(vNewLines); + vNewPolyData->SetPoints(vNewPoints); + + m_newfibersFibersData = vtkSmartPointer<vtkPolyData>::New(); + m_newfibersFibersData->SetPoints(vtkSmartPointer<vtkPoints>::New()); + m_newfibersFibersData->SetLines(vtkSmartPointer<vtkCellArray>::New()); + m_newfibersFibersData->SetPoints(vNewPoints); + m_newfibersFibersData->SetLines(vNewLines); + + m_newfibersBundle = mitk::FiberBundle::New(vNewPolyData); + m_newfibersBundle->SetFiberColors(255, 255, 255); + m_newfibersBundle->SetFiberWeights(weights); + + mitk::DataNode::Pointer node = mitk::DataNode::New(); + node->SetData(m_newfibersBundle); + node->SetName("ToLabel"); +// node->SetData(m_negativeBundle); +// node->SetFloatProperty("shape.tuberadius", 0.5); +// mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + + m_newfibersBundleNode = node; + +// MITK_INFO << "Number of Streamlines in first function"; +// MITK_INFO << m_newfibersBundleNode->GetData()->GetFiberPolyData()->GetNumberOfCells(); + this->GetDataStorage()->Add(m_newfibersBundleNode); + + mitk::FiberBundle::Pointer m_negativeBundle = mitk::FiberBundle::New(); + mitk::DataNode::Pointer node2 = mitk::DataNode::New(); + node2->SetName("-Bundle"); + node2->SetData(m_negativeBundle); +// node->SetFloatProperty("shape.tuberadius", 0.5); +// mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + m_negativeBundleNode = node2; + this->GetDataStorage()->Add(m_negativeBundleNode); + + m_RandomExtractionCounter++; + } + +// m_Controls->m_ErazorButton->setChecked(true); + + + UpdateGui(); + + +} + +void QmitkInteractiveFiberDissectionView::RemovefromBundle( bool checked ) +{ + if (checked) + { + m_Controls->m_BrushButton->setChecked(false); + +// if (m_StreamlineInteractor.IsNull()) +// { + this->CreateStreamlineInteractorBrush(); + this->CreateStreamlineInteractor(); +// } + m_StreamlineInteractor->EnableInteraction(true); + m_StreamlineInteractor->LabelfromPrediction(false); + m_StreamlineInteractor->SetNegativeNode(m_negativeBundleNode); + m_StreamlineInteractor->SetPositiveNode(m_positiveBundleNode); + m_StreamlineInteractor->SetToLabelNode(m_newfibersBundleNode); + m_StreamlineInteractor->EnableInteraction(true); + +// m_StreamlineInteractor->EnableInteraction(true); +// m_StreamlineInteractor->LabelfromPrediction(false); +// m_StreamlineInteractor->SetNegativeNode(m_negativeBundleNode); +// m_StreamlineInteractor->SetPositiveNode(m_positiveBundleNode); +// m_StreamlineInteractor->SetToLabelNode(m_newfibersBundleNode); +// } +// else +// { +// m_StreamlineInteractor->EnableInteraction(true); +// m_StreamlineInteractor->LabelfromPrediction(false); +// m_StreamlineInteractor->SetPositiveNode(m_positiveBundleNode); +// m_StreamlineInteractor->SetToLabelNode(m_newfibersBundleNode); +// } + } + else + { + m_StreamlineInteractor->EnableInteraction(false); +// m_StreamlineInteractor = nullptr; + } + + + UpdateGui(); +} + +void QmitkInteractiveFiberDissectionView::RemovefromBundleBrush( bool checked ) +{ + if (checked) + { + m_Controls->m_ErazorButton->setChecked(false); + +// if (m_StreamlineInteractorBrush.IsNull()) +// { + this->CreateStreamlineInteractor(); + this->CreateStreamlineInteractorBrush(); +// } + + + m_StreamlineInteractorBrush->EnableInteraction(true); + m_StreamlineInteractorBrush->LabelfromPrediction(false); + m_StreamlineInteractorBrush->SetNegativeNode(m_negativeBundleNode); + m_StreamlineInteractorBrush->SetPositiveNode(m_positiveBundleNode); + m_StreamlineInteractorBrush->SetToLabelNode(m_newfibersBundleNode); + m_StreamlineInteractorBrush->EnableInteraction(true); +// m_StreamlineInteractorBrush->EnableInteraction(true); +// m_StreamlineInteractorBrush->LabelfromPrediction(false); +// m_StreamlineInteractorBrush->SetNegativeNode(m_negativeBundleNode); +// m_StreamlineInteractorBrush->SetPositiveNode(m_positiveBundleNode); +// m_StreamlineInteractorBrush->SetToLabelNode(m_newfibersBundleNode); +// } +// else +// { +// m_StreamlineInteractorBrush->EnableInteraction(true); +// m_StreamlineInteractorBrush->LabelfromPrediction(false); +// m_StreamlineInteractorBrush->SetPositiveNode(m_positiveBundleNode); +// m_StreamlineInteractorBrush->SetToLabelNode(m_newfibersBundleNode); +// } + } + else + { + m_StreamlineInteractorBrush->EnableInteraction(false); +// m_StreamlineInteractor = nullptr; + } + + + UpdateGui(); +} + +void QmitkInteractiveFiberDissectionView::CreateStreamlineInteractor() +{ + + m_StreamlineInteractor = mitk::StreamlineInteractor::New(); + + m_StreamlineInteractor->LoadStateMachine("Streamline3DStates.xml", us::ModuleRegistry::GetModule("MitkFiberDissection")); + m_StreamlineInteractor->SetEventConfig("Streamline3DConfig.xml", us::ModuleRegistry::GetModule("MitkFiberDissection")); + +// m_StreamlineInteractor->SetRotationEnabled(rotationEnabled); +} + +void QmitkInteractiveFiberDissectionView::CreateStreamlineInteractorBrush() +{ + + m_StreamlineInteractorBrush = mitk::StreamlineInteractorBrush::New(); + + m_StreamlineInteractorBrush->LoadStateMachine("StreamlineBrush3DStates.xml", us::ModuleRegistry::GetModule("MitkFiberDissection")); + m_StreamlineInteractorBrush->SetEventConfig("StreamlineBrush3DConfig.xml", us::ModuleRegistry::GetModule("MitkFiberDissection")); + +// m_StreamlineInteractor->SetRotationEnabled(rotationEnabled); +} + +void QmitkInteractiveFiberDissectionView::StartAlgorithm() +{ + + m_negativeBundle = dynamic_cast<mitk::FiberBundle*>(m_negativeBundleNode->GetData()); + m_positiveBundle = dynamic_cast<mitk::FiberBundle*>(m_positiveBundleNode->GetData()); + + + this->GetDataStorage()->Remove(m_UncertaintyLabelNode); + this->GetDataStorage()->Remove(m_DistanceLabelNode); + + + MITK_INFO << "Clean Test Data"; + +// this->CleanTestArray(); + m_testnode = m_Controls->m_TestBundleBox->GetSelectedNode(); +// mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(m_SelectedFB.at(0)->GetData()); + mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(m_testnode->GetData()); + + MITK_INFO << fib->GetFiberPolyData()->GetNumberOfCells(); + fib->GetFiberPolyData()->RemoveDeletedCells(); + MITK_INFO << fib->GetFiberPolyData()->GetNumberOfCells(); + + + m_Controls->m_unclabeling->setChecked(false); + m_Controls->m_distlabeling->setChecked(false); + m_Controls->m_unclabelingBrush->setChecked(false); + m_Controls->m_predlabeling->setChecked(false); + m_Controls->m_predlabelingBrush->setChecked(false); + m_uncCounter = 0; + +// classifier.reset(); + MITK_INFO << "Extract Features"; + + classifier = std::make_shared<mitk::StreamlineFeatureExtractor>(); + classifier->SetActiveCycle(m_activeCycleCounter); + classifier->SetTractogramPlus(m_positiveBundle); + classifier->SetTractogramMinus(m_negativeBundle); + classifier->SetTractogramPrototypes(dynamic_cast<mitk::FiberBundle*>(m_Controls->m_PrototypeBox->GetSelectedNode()->GetData()), m_Controls->m_useStandardP->isChecked()); +// classifier->SetTractogramTest(dynamic_cast<mitk::FiberBundle*>(m_SelectedFB.at(0)->GetData()), m_SelectedFB.at(0)->GetName()); + classifier->SetTractogramTest(dynamic_cast<mitk::FiberBundle*>(m_testnode->GetData()), m_testnode->GetName()); +// classifier->SetTractogramTest(dynamic_cast<mitk::FiberBundle*>(m_trainbundle->GetData()), m_trainbundle->GetName()); + + + + classifier->Update(); + + m_index = classifier->m_index; + MITK_INFO << "Number of Cycles"; + MITK_INFO << m_activeCycleCounter; + m_activeCycleCounter += 1; + + + MITK_INFO << "Algorithm run succesfully"; +// mitk::DataNode::Pointer node = mitk::DataNode::New(); +// this->GetDataStorage()->Add(node); + m_Controls->m_CreatePrediction->setEnabled(true); + UpdateGui(); + +} + +void QmitkInteractiveFiberDissectionView::CreatePredictionNode() +{ + MITK_INFO << "Create Prediction"; + + m_Prediction = classifier->CreatePrediction(m_index.at(0), false); + mitk::DataNode::Pointer node = mitk::DataNode::New(); + node->SetData(m_Prediction); + auto s = std::to_string(m_activeCycleCounter); + node->SetName("Prediction"+s); + m_PredictionNode = node; + this->GetDataStorage()->Add(m_PredictionNode); + UpdateGui(); +} + +void QmitkInteractiveFiberDissectionView::CreateCertainNode() +{ + MITK_INFO << "Create Certain Data"; + + + m_CertainMinus = classifier->CreatePrediction(m_index.at(2), false); + mitk::DataNode::Pointer node = mitk::DataNode::New(); + node->SetData(m_CertainMinus); + auto s = std::to_string(m_activeCycleCounter); + node->SetName("m_CertainMinus"+s); + m_CertainMinusNode = node; + this->GetDataStorage()->Add(m_CertainMinusNode); + +// m_CertainPlus = classifier->CreatePrediction(m_index.at(4)); +// mitk::DataNode::Pointer node2= mitk::DataNode::New(); +// node2->SetData(m_CertainPlus); +// node2->SetName("m_CertainPlus"+s); +// m_CertainPlusNode = node2; +// this->GetDataStorage()->Add(m_CertainPlusNode); + + +// m_CertainBetweenMinus = classifier->CreatePrediction(m_index.at(4)); +// mitk::DataNode::Pointer node3 = mitk::DataNode::New(); +// node3->SetData(m_CertainBetweenMinus); +// node3->SetName("m_CertainBetweenMinus"+s); +// m_CertainBetweenMinusNode = node3; +// this->GetDataStorage()->Add(m_CertainBetweenMinusNode); + +// m_CertainBetweenPlus = classifier->CreatePrediction(m_index.at(6)); +// mitk::DataNode::Pointer node4= mitk::DataNode::New(); +// node4->SetData(m_CertainBetweenPlus); +// node4->SetName("m_CertainBetweenPlus"+s); +// m_CertainBetweenPlusNode = node4; +// this->GetDataStorage()->Add(m_CertainBetweenPlusNode); + +} + +void QmitkInteractiveFiberDissectionView::RemoveCertainData() +{ +// mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(m_SelectedFB.at(0)->GetData()); + mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(m_testnode->GetData()); + MITK_INFO << "Length of certain negativ data:"; + MITK_INFO << m_index.at(2).size(); + MITK_INFO << "Length of Testdata"; + MITK_INFO << fib->GetFiberPolyData()->GetNumberOfCells(); + for (unsigned int i=0; i< m_index.at(2).size(); i++) + { + fib->GetFiberPolyData()->DeleteCell(m_index.at(2).at(i)); + } +// fib->GetFiberPolyData()->RemoveDeletedCells(); + + MITK_INFO << "Length of Testdata"; + MITK_INFO << fib->GetFiberPolyData()->GetNumberOfCells(); +} + +void QmitkInteractiveFiberDissectionView::CreateUncertaintySampleNode() +{ + this->GetDataStorage()->Remove(m_UncertaintyLabelNode); + MITK_INFO << "Create Fibers to label based on Uncertainty"; + + std::vector<unsigned int> vec = m_index.at(1); + std::vector<unsigned int> myvec = {vec.begin() + m_uncCounter, vec.begin() + m_uncCounter + m_Controls->m_Numtolabel->value()}; + m_uncCounter = m_uncCounter + m_Controls->m_Numtolabel->value(); + MITK_INFO << m_index.at(1).size(); + MITK_INFO << myvec.size(); + + + m_UncertaintyLabel = classifier->CreatePrediction(myvec, true); + mitk::DataNode::Pointer node = mitk::DataNode::New(); + node->SetData(m_UncertaintyLabel); + float d = 5.0; + + auto s = std::to_string(m_activeCycleCounter); + node->SetName("UncertaintyLabel"+s); + m_UncertaintyLabelNode = node; + m_UncertaintyLabelNode->SetProperty("Fiber2DSliceThickness", mitk::FloatProperty::New(d)); + this->GetDataStorage()->Add(m_UncertaintyLabelNode); + UpdateGui(); +} + +void QmitkInteractiveFiberDissectionView::CreateDistanceSampleNode() +{ +// MITK_INFO << "Create Fibers to label based on Distance in Features-Space"; +// std::vector<unsigned int> myvec = m_index.at(2); +// myvec.resize(m_Controls->m_Numtolabel2->value()); +// MITK_INFO << m_index.at(2).size(); +// MITK_INFO << myvec.size(); + + float myval = m_Controls->m_subsetfft->value() * 0.01; + MITK_INFO << myval; + std::vector<std::vector<unsigned int>> curidx; + curidx = classifier->GetDistanceData(myval); + std::vector<unsigned int> myvec = curidx.at(0); + myvec.resize(m_Controls->m_Numtolabel2->value()); + MITK_INFO << m_index.at(2).size(); + MITK_INFO << myvec.size(); + m_DistanceLabel = classifier->CreatePrediction(myvec, true); + mitk::DataNode::Pointer node = mitk::DataNode::New(); + node->SetData(m_DistanceLabel); + auto s = std::to_string(m_activeCycleCounter); + node->SetName("DistanceLabel"+s); + m_DistanceLabelNode = node; + this->GetDataStorage()->Add(m_DistanceLabelNode); + UpdateGui(); +} + +void QmitkInteractiveFiberDissectionView::RemovefromUncertainty( bool checked ) +{ + if (checked) + { + m_Controls->m_unclabelingBrush->setChecked(false); + m_Controls->m_predlabelingBrush->setChecked(false); + m_Controls->m_predlabeling->setChecked(false); + + + m_UncertaintyLabel->SetFiberColors(255, 255, 255); + this->CreateStreamlineInteractor(); + m_StreamlineInteractor->EnableInteraction(true); + m_StreamlineInteractor->LabelfromPrediction(false); + m_StreamlineInteractor->SetNegativeNode(m_negativeBundleNode); + m_StreamlineInteractor->SetPositiveNode(m_positiveBundleNode); + m_StreamlineInteractor->SetToLabelNode(m_UncertaintyLabelNode); + } + else + { + m_StreamlineInteractor->EnableInteraction(false); +// m_StreamlineInteractor = nullptr; + } + RenderingManager::GetInstance()->RequestUpdateAll(); +} + +void QmitkInteractiveFiberDissectionView::RemovefromUncertaintyBrush( bool checked ) +{ + if (checked) + { + m_Controls->m_unclabeling->setChecked(false); + m_Controls->m_predlabelingBrush->setChecked(false); + m_Controls->m_predlabeling->setChecked(false); + + m_UncertaintyLabel->SetFiberColors(255, 255, 255); + this->CreateStreamlineInteractorBrush(); + m_StreamlineInteractorBrush->EnableInteraction(true); + m_StreamlineInteractorBrush->LabelfromPrediction(false); + m_StreamlineInteractorBrush->SetNegativeNode(m_negativeBundleNode); + m_StreamlineInteractorBrush->SetPositiveNode(m_positiveBundleNode); + m_StreamlineInteractorBrush->SetToLabelNode(m_UncertaintyLabelNode); + } + else + { + m_StreamlineInteractorBrush->EnableInteraction(false); +// m_StreamlineInteractor = nullptr; + } + RenderingManager::GetInstance()->RequestUpdateAll(); +} + +void QmitkInteractiveFiberDissectionView::RemovefromDistance( bool checked ) +{ + if (checked) + { + + m_DistanceLabel->SetFiberColors(255, 255, 255); + m_StreamlineInteractor->EnableInteraction(true); + m_StreamlineInteractor->LabelfromPrediction(false); + m_StreamlineInteractor->SetToLabelNode(m_DistanceLabelNode); + } + else + { + m_StreamlineInteractor->EnableInteraction(false); +// m_StreamlineInteractor = nullptr; + } + RenderingManager::GetInstance()->RequestUpdateAll(); +} + +void QmitkInteractiveFiberDissectionView::RemovefromPrediction( bool checked ) +{ + if (checked) + { + m_Controls->m_predlabelingBrush->setChecked(false); + m_Controls->m_unclabelingBrush->setChecked(false); + m_Controls->m_unclabeling->setChecked(false); + +// m_Prediction->SetFiberColors(255, 255, 255); + this->CreateStreamlineInteractor(); + m_StreamlineInteractor->EnableInteraction(true); + m_StreamlineInteractor->LabelfromPrediction(true); + m_StreamlineInteractor->SetNegativeNode(m_negativeBundleNode); + m_StreamlineInteractor->SetPositiveNode(m_positiveBundleNode); + m_StreamlineInteractor->SetToLabelNode(m_PredictionNode); + } + else + { + m_StreamlineInteractor->EnableInteraction(false); +// m_StreamlineInteractor = nullptr; +// this->CleanTestArray(); + } + +} + +void QmitkInteractiveFiberDissectionView::RemovefromPredictionBrush( bool checked ) +{ + if (checked) + { + m_Controls->m_predlabeling->setChecked(false); + m_Controls->m_unclabelingBrush->setChecked(false); + m_Controls->m_unclabeling->setChecked(false); + +// m_Prediction->SetFiberColors(255, 255, 255); + this->CreateStreamlineInteractorBrush(); + m_StreamlineInteractorBrush->EnableInteraction(true); + m_StreamlineInteractorBrush->LabelfromPrediction(true); + m_StreamlineInteractorBrush->SetNegativeNode(m_negativeBundleNode); + m_StreamlineInteractorBrush->SetPositiveNode(m_positiveBundleNode); + m_StreamlineInteractorBrush->SetToLabelNode(m_PredictionNode); + } + else + { + m_StreamlineInteractorBrush->EnableInteraction(false); +// m_StreamlineInteractor = nullptr; +// this->CleanTestArray(); + } + +} + +void QmitkInteractiveFiberDissectionView::RemovefromSelection( bool checked ) +{ + if (checked) + { + + // m_Prediction->SetFiberColors(255, 255, 255); + m_StreamlineInteractor->EnableInteraction(true); + m_StreamlineInteractor->LabelfromPrediction(true); +// m_StreamlineInteractor->SetToLabelNode(m_SelectedFB.at(0)); + m_StreamlineInteractor->SetToLabelNode(m_testnode); + } + else + { + m_StreamlineInteractor->EnableInteraction(false); + // m_StreamlineInteractor = nullptr; + } +} + +void QmitkInteractiveFiberDissectionView::StartValidation() +{ + + + + + validater.reset(); +// mitk::DataNode::Pointer prednode = m_Controls->m_BundleBox->GetSelectedNode(); +// mitk::FiberBundle::Pointer pred = dynamic_cast<mitk::FiberBundle *>(prednode->GetData()); +// mitk::DataNode::Pointer gtnode = m_Controls->m_BundleBox->GetSelectedNode(); +// mitk::FiberBundle::Pointer gt = dynamic_cast<mitk::FiberBundle *>(gtnode->GetData()); +// mitk::FiberBundle::Pointer pred = dynamic_cast<mitk::FiberBundle*>(m_Controls->m_PredictionBox->GetSelectedNode()->GetData()); +// mitk::FiberBundle::Pointer gt = dynamic_cast<mitk::FiberBundle*>(m_Controls->m_GroundtruthBox->GetSelectedNode()->GetData()); + + validater= std::make_shared<mitk::StreamlineFeatureExtractor>(); + validater->SetTractogramPrototypes(dynamic_cast<mitk::FiberBundle*>(m_Controls->m_PrototypeBox->GetSelectedNode()->GetData()), m_Controls->m_useStandardP->isChecked()); + MITK_INFO << "Prototypes loaded"; + validater->SetTractogramPrediction(dynamic_cast<mitk::FiberBundle*>(m_Controls->m_PredictionBox->GetSelectedNode()->GetData())); + MITK_INFO << "Prediction loaded"; + validater->SetTractogramGroundtruth(dynamic_cast<mitk::FiberBundle*>(m_Controls->m_GroundtruthBox->GetSelectedNode()->GetData())); + MITK_INFO << "Groundtruth loaded"; + + validater->SetActiveCycle(m_activeCycleCounter); +// validater->SetTractogramTest(dynamic_cast<mitk::FiberBundle*>(m_SelectedFB.at(0)->GetData()), m_SelectedFB.at(0)->GetName()); + validater->SetTractogramTest(dynamic_cast<mitk::FiberBundle*>(m_testnode->GetData()), m_testnode->GetName()); +// classifier->SetTractogramTest(dynamic_cast<mitk::FiberBundle*>(m_trainbundle->GetData()), m_trainbundle->GetName()); + + + + MITK_INFO << "Testdata loaded"; + vnl_vector<float> metrics; + metrics = validater->ValidationPipe(); + + m_metrics.push_back(metrics); + + + std::ofstream metricsfile; + metricsfile.open("/home/r948e/mycsv/metrics_" + std::to_string(m_activeCycleCounter) + ".csv"); + for (unsigned int i = 0; i < m_metrics.size(); i++) + { + metricsfile << m_metrics.at(i) << std::endl; + } + + metricsfile.close(); + + + MITK_INFO << "Validation run succesfully"; + + UpdateGui(); + +} + +void QmitkInteractiveFiberDissectionView::AutomaticLabelling() +{ +// mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(m_SelectedFB.at(0)->GetData()); +// mitk::FiberBundle::Pointer fib_true = dynamic_cast<mitk::FiberBundle*>(m_Controls->m_GroundtruthBox->GetSelectedNode()->GetData()); +// vtkCell* cell; +// vtkCell* cell2; +// for (int i=0; i<fib->GetFiberPolyData()->GetNumberOfCells(); i++) +// { +// cell = fib->GetFiberPolyData()->GetCell(i); +// for (int k=0; k<fib->GetFiberPolyData()->GetNumberOfCells(); k++ ) +// { +// cell2 = fib_true->GetFiberPolyData()->GetCell(i); +// if (cell==cell2) +// MITK_INFO << "Same"; +// } +// } + + mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(m_PredictionNode->GetData()); + mitk::FiberBundle::Pointer fib_true = dynamic_cast<mitk::FiberBundle*>(m_positiveBundleNode->GetData()); + + vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New(); + vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New(); + + vtkSmartPointer<vtkFloatArray> weights = vtkSmartPointer<vtkFloatArray>::New(); + + /* Check wether all Streamlines of the bundles are labeled... If all are labeled Skip for Loop*/ + unsigned int counter = 0; + + for (int i=0; i<fib->GetFiberPolyData()->GetNumberOfCells(); i++) + { + vtkCell* cell = fib->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + for (int i=0; i<fib_true->GetFiberPolyData()->GetNumberOfCells(); i++) + { + vtkCell* cell = fib_true->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + weights->InsertValue(counter, fib_true->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vNewPolyData->SetLines(vNewLines); + vNewPolyData->SetPoints(vNewPoints); + + mitk::FiberBundle::Pointer MergedPrediction = mitk::FiberBundle::New(vNewPolyData); + MergedPrediction->SetFiberWeights(weights); + + mitk::DataNode::Pointer node = mitk::DataNode::New(); + node->SetData(MergedPrediction); + node->SetName("MergedPrediction"); + this->GetDataStorage()->Add(node); + + +} + +void QmitkInteractiveFiberDissectionView::CleanTestArray() +{ + + mitk::FiberBundle::Pointer fib_pos = dynamic_cast<mitk::FiberBundle*>(m_positiveBundleNode->GetData()); + mitk::FiberBundle::Pointer fib_neg = dynamic_cast<mitk::FiberBundle*>(m_negativeBundleNode->GetData()); +// mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(m_SelectedFB.at(0)->GetData()); + mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(m_testnode->GetData()); + vtkCell* cur_cell; + vtkCell* cur_cell2; + MITK_INFO << fib_neg->GetFiberPolyData()->GetNumberOfCells(); + MITK_INFO << fib_pos->GetFiberPolyData()->GetNumberOfCells(); + MITK_INFO << fib->GetFiberPolyData()->GetNumberOfCells(); + + + std::vector<float> array; + std::vector<float> array2; + + + // cv::parallel_for_(cv::Range(0, fib->GetFiberPolyData()->GetNumberOfCells()), [&](const cv::Range &range) + // { + // for (int i = range.start; i < range.end; i++) + for (int i=0; i<fib->GetFiberPolyData()->GetNumberOfCells(); i++) + { + cur_cell = fib->GetFiberPolyData()->GetCell(i); + auto numPoints = cur_cell->GetNumberOfPoints(); + vtkPoints* points = cur_cell->GetPoints(); + for (unsigned int j=0; j<numPoints; j++) + { + double p[3]; + points->GetPoint(j, p); + array.push_back(*p); + } + for (int ik=0; ik<fib_neg->GetFiberPolyData()->GetNumberOfCells(); ik++) + { + cur_cell2 = fib_neg->GetFiberPolyData()->GetCell(ik); + auto numPoints2 = cur_cell2->GetNumberOfPoints(); + vtkPoints* points2 = cur_cell2->GetPoints(); + for (unsigned int j2=0; j2<numPoints2; j2++) + { + double p2[3]; + points2->GetPoint(j2, p2); + array2.push_back(*p2); + + } + if (array==array2) + { + fib->GetFiberPolyData()->DeleteCell(i); + MITK_INFO << "Delete Cell"; + } + array2.clear(); + } + for (int ik=0; ik<fib_pos->GetFiberPolyData()->GetNumberOfCells(); ik++) + { + + cur_cell2 = fib_pos->GetFiberPolyData()->GetCell(ik); + auto numPoints2 = cur_cell2->GetNumberOfPoints(); + vtkPoints* points2 = cur_cell2->GetPoints(); + for (unsigned int j2=0; j2<numPoints2; j2++) + { + double p2[3]; + points2->GetPoint(j2, p2); + array2.push_back(*p2); + } + if (array==array2) + { + fib->GetFiberPolyData()->DeleteCell(i); + MITK_INFO << "Delete Cell"; + } + array2.clear(); + } + array.clear(); + } + // }); + +// fib->GetFiberPolyData()->RemoveDeletedCells(); + + MITK_INFO << fib->GetFiberPolyData()->GetNumberOfCells(); + + + +} + +void QmitkInteractiveFiberDissectionView::ResetClassifier() +{ + m_IterationCounter = 0; + m_RandomExtractionCounter = 0; + m_activeCycleCounter = 0; + m_createdStreamlineCounter = 0; + + classifier.reset(); + this->GetDataStorage()->Remove(m_positiveBundleNode); + this->GetDataStorage()->Remove(m_negativeBundleNode); + this->GetDataStorage()->Remove(m_negativeBundleNode); + + m_positiveBundleNode = NULL; + m_negativeBundleNode = NULL; + m_negativeBundleNode = NULL; + m_positiveBundle = NULL; + m_negativeBundle = NULL; + m_negativeBundle = NULL; + m_Controls->m_TrainClassifier->setEnabled(false); + m_Controls->m_CreatePrediction->setEnabled(false); + m_Controls->m_CreateUncertantyMap->setEnabled(false); + + + +} diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkInteractiveFiberDissectionView.h b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkInteractiveFiberDissectionView.h new file mode 100644 index 0000000..acab0f6 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkInteractiveFiberDissectionView.h @@ -0,0 +1,191 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center. + +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + + +#ifndef QmitkInteractiveFiberDissectionView_h +#define QmitkInteractiveFiberDissectionView_h +#include "ui_QmitkInteractiveFiberDissectionViewControls.h" + +#include <QInputDialog> //Pointset +#include <QmitkPointListWidget.h>//Pointset + +#include <QmitkAbstractView.h>//Pointset +#include <QmitkSingleNodeSelectionWidget.h>//Pointset + + +#include <mitkFiberBundle.h> +#include <mitkDataInteractor.h> +#include <mitkIRenderWindowPartListener.h> //Pointset +#include <mitkStreamlineInteractor.h> +#include <mitkStreamlineInteractorBrush.h> +#include <mitkStreamlineFeatureExtractor.h> + +#include <itkCastImageFilter.h> +#include <itkVTKImageImport.h> +#include <itkVTKImageExport.h> +#include <itkRegionOfInterestImageFilter.h> + +#include <vtkLinearExtrusionFilter.h> +#include <vtkPolyDataToImageStencil.h> +#include <vtkSelectEnclosedPoints.h> +#include <vtkImageImport.h> +#include <vtkImageExport.h> +#include <vtkImageStencil.h> +#include <vtkSmartPointer.h> +#include <vtkSelection.h> +#include <vtkSelectionNode.h> +#include <vtkExtractSelectedThresholds.h> +#include <vtkFloatArray.h> +#include <vtkCellPicker.h> + +/*! +\brief View to process fiber bundles. Supplies methods to extract fibers from the bundle, fiber resampling, mirroring, join and subtract bundles and much more. +*/ +class QmitkInteractiveFiberDissectionView : public QmitkAbstractView, public mitk::IRenderWindowPartListener +{ + // 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: + + typedef itk::Image< unsigned char, 3 > ItkUCharImageType; + typedef itk::Image< float, 3 > ItkFloatImageType; + + static const std::string VIEW_ID; + + QmitkInteractiveFiberDissectionView(); + virtual ~QmitkInteractiveFiberDissectionView(); + + virtual void CreateQtPartControl(QWidget *parent) override; + + /// + /// Sets the focus to an internal widget. + /// + virtual void SetFocus() override; + +protected slots: + + void RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart) override; //Pointset + void RenderWindowPartDeactivated(mitk::IRenderWindowPart* renderWindowPart) override; //Pointset + void OnAddPointSetClicked();//Pointset + void CreateStreamline(); + void RemovefromBundle( bool checked ); + void RemovefromBundleBrush( bool checked ); + void ExtractRandomFibersFromTractogram(); + void StartAlgorithm(); + void CreatePredictionNode(); + void CreateCertainNode(); + void CreateUncertaintySampleNode(); + void CreateDistanceSampleNode(); + void RemovefromUncertainty( bool checked ); + void RemovefromUncertaintyBrush( bool checked ); + void RemovefromDistance( bool checked ); + void RemovefromPrediction( bool checked ); + void RemovefromPredictionBrush( bool checked ); + void RemovefromSelection( bool checked ); + void ResampleTractogram(); + void RandomPrototypes(); + void SFFPrototypes(); + void StartValidation(); + void AutomaticLabelling(); + void RemoveCertainData(); + void ResetClassifier(); + + + + void UpdateGui(); ///< update button activity etc. dpending on current datamanager selection + + + + +protected: + void OnCurrentSelectionChanged(QmitkSingleNodeSelectionWidget::NodeList nodes);//Pointset + + + virtual void OnSelectionChanged(berry::IWorkbenchPart::Pointer part, const QList<mitk::DataNode::Pointer>& nodes) override; + + void OnEndInteraction(); + void CreateStreamlineInteractor(); + void CreateStreamlineInteractorBrush(); + void CleanTestArray(); + + Ui::QmitkInteractiveFiberDissectionViewControls* m_Controls; + + + + int m_IterationCounter; ///< used for data node naming + int m_RandomExtractionCounter; ///< used for random extracton of different Streamlines + int m_activeCycleCounter; + int m_newpos; + int m_newneg; + int m_startneg; + int m_createdStreamlineCounter; + int m_uncCounter; +// int m_thresh2; + + + std::vector<mitk::DataNode::Pointer> m_SelectedFB; ///< selected fiber bundle nodes + mitk::DataNode::Pointer m_testnode; +// mitk::DataNode::Pointer m_trainbundle; + mitk::Image::Pointer m_SelectedImage; + mitk::DataNode::Pointer m_SelectedPS; + mitk::DataNode::Pointer m_SelectedImageNode; + mitk::FiberBundle::Pointer m_positiveBundle; + mitk::FiberBundle::Pointer m_newfibersBundle; + mitk::FiberBundle::Pointer m_negativeBundle; + mitk::FiberBundle::Pointer m_Prediction; + mitk::FiberBundle::Pointer m_CertainPlus; + mitk::FiberBundle::Pointer m_CertainMinus; + mitk::FiberBundle::Pointer m_CertainBetweenPlus; + mitk::FiberBundle::Pointer m_CertainBetweenMinus; + mitk::FiberBundle::Pointer m_UncertaintyLabel; + mitk::FiberBundle::Pointer m_DistanceLabel; + + + mitk::DataNode::Pointer m_positiveBundleNode; + mitk::DataNode::Pointer m_newfibersBundleNode; + mitk::DataNode::Pointer m_negativeBundleNode; + mitk::DataNode::Pointer m_PredictionNode; + mitk::DataNode::Pointer m_CertainPlusNode; + mitk::DataNode::Pointer m_CertainMinusNode; + mitk::DataNode::Pointer m_CertainBetweenPlusNode; + mitk::DataNode::Pointer m_CertainBetweenMinusNode; + mitk::DataNode::Pointer m_UncertaintyLabelNode; + mitk::DataNode::Pointer m_DistanceLabelNode; + + vtkSmartPointer<vtkPolyData> m_positiveFibersData; + vtkSmartPointer<vtkPolyData> m_newfibersFibersData; + + vtkSmartPointer<vtkCellPicker> m_picker1; + mitk::StreamlineInteractor::Pointer m_StreamlineInteractor; + mitk::StreamlineInteractorBrush::Pointer m_StreamlineInteractorBrush; + + std::shared_ptr< mitk::StreamlineFeatureExtractor > classifier; + std::shared_ptr< mitk::StreamlineFeatureExtractor > validater; + + + std::vector<vnl_vector<float>> m_metrics; + + std::vector<std::vector<unsigned int>> m_index; + +}; + + + +#endif // _QMITKFIBERTRACKINGVIEW_H_INCLUDED + diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkInteractiveFiberDissectionViewControls.ui b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkInteractiveFiberDissectionViewControls.ui new file mode 100644 index 0000000..1747417 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkInteractiveFiberDissectionViewControls.ui @@ -0,0 +1,1125 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>QmitkInteractiveFiberDissectionViewControls</class> + <widget class="QWidget" name="QmitkInteractiveFiberDissectionViewControls"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>417</width> + <height>711</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <property name="styleSheet"> + <string>QCommandLinkButton:disabled { + border: none; +} + +QGroupBox { + background-color: transparent; +}</string> + </property> + <layout class="QGridLayout" name="gridLayout_3"> + <property name="leftMargin"> + <number>9</number> + </property> + <property name="topMargin"> + <number>9</number> + </property> + <property name="rightMargin"> + <number>9</number> + </property> + <property name="bottomMargin"> + <number>9</number> + </property> + <item row="2" column="0"> + <widget class="QToolBox" name="toolBoxx"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="font"> + <font> + <bold>true</bold> + </font> + </property> + <property name="toolTip"> + <string>Label Fibers</string> + </property> + <property name="frameShape"> + <enum>QFrame::NoFrame</enum> + </property> + <property name="currentIndex"> + <number>3</number> + </property> + <property name="tabSpacing"> + <number>6</number> + </property> + <widget class="QWidget" name="page"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>399</width> + <height>439</height> + </rect> + </property> + <attribute name="label"> + <string>Generate Prototypes</string> + </attribute> + <layout class="QGridLayout" name="gridLayout_5"> + <item row="2" column="0" colspan="2"> + <widget class="QToolBox" name="toolBox"> + <property name="toolTipDuration"> + <number>0</number> + </property> + <property name="currentIndex"> + <number>0</number> + </property> + <widget class="QWidget" name="Defaults"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>381</width> + <height>359</height> + </rect> + </property> + <attribute name="label"> + <string>Defaults</string> + </attribute> + <layout class="QGridLayout" name="gridLayout_27"> + <item row="0" column="0"> + <widget class="QLabel" name="inputImageOneLabel"> + <property name="text"> + <string>Extract from</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QmitkDataStorageComboBox" name="m_BundleBox"/> + </item> + <item row="1" column="0"> + <widget class="QPushButton" name="m_SFFPrototypesButton"> + <property name="text"> + <string>SFF Extraction</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <spacer name="verticalSpacer_23"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <widget class="QWidget" name="page_17"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>273</width> + <height>171</height> + </rect> + </property> + <attribute name="label"> + <string>Advanced Settings</string> + </attribute> + <layout class="QGridLayout" name="gridLayout_29"> + <item row="0" column="0" colspan="2"> + <widget class="QLabel" name="inputImageOneLabel_3"> + <property name="text"> + <string>Number of Prototypes</string> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QSpinBox" name="m_NumPrototypes"> + <property name="minimum"> + <number>10</number> + </property> + <property name="maximum"> + <number>200</number> + </property> + <property name="value"> + <number>100</number> + </property> + </widget> + </item> + <item row="1" column="0" colspan="2"> + <widget class="QPushButton" name="m_RandomPrototypesButton"> + <property name="text"> + <string>Random Extraction</string> + </property> + </widget> + </item> + <item row="2" column="0" colspan="2"> + <widget class="QPushButton" name="m_ResampleButton"> + <property name="text"> + <string>Resample Bundle</string> + </property> + </widget> + </item> + <item row="3" column="0" colspan="2"> + <widget class="QRadioButton" name="m_useStandardP"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="text"> + <string>Use Standard Prototypes</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="inputImageOneLabel_2"> + <property name="text"> + <string>Choose own Prototypes</string> + </property> + </widget> + </item> + <item row="4" column="1" colspan="2"> + <widget class="QmitkDataStorageComboBox" name="m_PrototypeBox"/> + </item> + <item row="5" column="0"> + <spacer name="verticalSpacer_5"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>170</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="page_3"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>399</width> + <height>439</height> + </rect> + </property> + <attribute name="label"> + <string>Fiber Creation</string> + </attribute> + <layout class="QGridLayout" name="gridLayout_7"> + <item row="0" column="0"> + <widget class="QFrame" name="frame"> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Raised</enum> + </property> + <layout class="QGridLayout" name="gridLayout_11"> + <item row="0" column="0"> + <widget class="QLabel" name="m_selectedPointSetLabel"> + <property name="text"> + <string>Selected Streamline Pointset</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <spacer name="horizontalSpacer_14"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="4" column="0" colspan="2"> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Streamline Points</string> + </property> + <layout class="QGridLayout" name="gridLayout_10"> + <item row="0" column="0"> + <widget class="QmitkPointListWidget" name="m_poinSetListWidget" native="true"/> + </item> + <item row="1" column="0"> + <spacer name="verticalSpacer_7"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + <item row="1" column="1"> + <spacer name="horizontalSpacer_13"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="1"> + <spacer name="horizontalSpacer_12"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="2" column="0"> + <widget class="QPushButton" name="m_addPointSetPushButton"> + <property name="text"> + <string>Add new Streamline Pointset</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QmitkSingleNodeSelectionWidget" name="m_selectedPointSetWidget" native="true"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>40</height> + </size> + </property> + </widget> + </item> + <item row="6" column="0"> + <spacer name="verticalSpacer_3"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item row="7" column="0"> + <widget class="QPushButton" name="m_StreamlineCreation"> + <property name="text"> + <string>Create Streamline</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="page_2"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>399</width> + <height>439</height> + </rect> + </property> + <property name="accessibleName"> + <string/> + </property> + <attribute name="label"> + <string>Fiber Labelling</string> + </attribute> + <attribute name="toolTip"> + <string>Dissect/Eraze Fibers by Erasion and Highlighting</string> + </attribute> + <layout class="QGridLayout" name="gridLayout_13"> + <item row="1" column="0"> + <widget class="QFrame" name="m_LabelFrame"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="cursor"> + <cursorShape>ArrowCursor</cursorShape> + </property> + <property name="frameShape"> + <enum>QFrame::NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Raised</enum> + </property> + <layout class="QGridLayout" name="gridLayout_4"> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Label individual Streamlines</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="4" column="0"> + <spacer name="verticalSpacer_4"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Streamlines to be labeled</string> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QFrame" name="m_ExtractionToolsFrame"> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Raised</enum> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="3" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>Label Streamlines</string> + </property> + </widget> + </item> + <item row="6" column="0"> + <widget class="QLabel" name="label_10"> + <property name="text"> + <string>Unlabel: Leftclick + shift/alt</string> + </property> + </widget> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="label_6"> + <property name="text"> + <string>Reject: Rightclick + shift</string> + </property> + </widget> + </item> + <item row="3" column="1" colspan="2"> + <widget class="QPushButton" name="m_ErazorButton"> + <property name="maximumSize"> + <size> + <width>30</width> + <height>30</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="icon"> + <iconset> + <normaloff>:/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/eraze.png</normaloff>:/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/eraze.png</iconset> + </property> + <property name="iconSize"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="0" column="4" rowspan="3"> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="5" column="0"> + <widget class="QLabel" name="label_8"> + <property name="text"> + <string>Accept: Rightclick + alt</string> + </property> + </widget> + </item> + <item row="0" column="1" rowspan="3" colspan="2"> + <widget class="QSpinBox" name="m_NumRandomFibers"> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>2000</number> + </property> + <property name="value"> + <number>20</number> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label_7"> + <property name="text"> + <string>Random Streamlines</string> + </property> + </widget> + </item> + <item row="7" column="0"> + <spacer name="verticalSpacer_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="3" rowspan="3"> + <widget class="QPushButton" name="m_AddRandomFibers"> + <property name="text"> + <string>Add</string> + </property> + </widget> + </item> + <item row="3" column="3"> + <widget class="QPushButton" name="m_BrushButton"> + <property name="maximumSize"> + <size> + <width>30</width> + <height>30</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="icon"> + <iconset> + <normaloff>:/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/brush.png</normaloff>:/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/brush.png</iconset> + </property> + <property name="iconSize"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="page_4"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>399</width> + <height>439</height> + </rect> + </property> + <attribute name="label"> + <string>Active Learning</string> + </attribute> + <widget class="QFrame" name="frame_2"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>381</width> + <height>391</height> + </rect> + </property> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Raised</enum> + </property> + <layout class="QGridLayout" name="gridLayout_6"> + <item row="8" column="1"> + <widget class="QToolBox" name="toolBox_2"> + <property name="currentIndex"> + <number>0</number> + </property> + <widget class="QWidget" name="page_16"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>361</width> + <height>309</height> + </rect> + </property> + <attribute name="label"> + <string>Default</string> + </attribute> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="1" column="4"> + <spacer name="horizontalSpacer_29"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>57</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="2" column="4"> + <spacer name="horizontalSpacer_4"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>57</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="2" column="2" colspan="2"> + <widget class="QPushButton" name="m_AddUncertainFibers"> + <property name="text"> + <string>Add </string> + </property> + </widget> + </item> + <item row="0" column="4"> + <spacer name="horizontalSpacer_30"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>57</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="3" column="0" colspan="2"> + <widget class="QLabel" name="label_35"> + <property name="text"> + <string>Label from Uncertainy Node</string> + </property> + </widget> + </item> + <item row="0" column="0" colspan="2"> + <widget class="QPushButton" name="m_TrainClassifier"> + <property name="text"> + <string>Train Classifier</string> + </property> + </widget> + </item> + <item row="4" column="2"> + <widget class="QPushButton" name="m_predlabeling"> + <property name="maximumSize"> + <size> + <width>30</width> + <height>30</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="icon"> + <iconset> + <normaloff>:/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/eraze.png</normaloff>:/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/eraze.png</iconset> + </property> + <property name="iconSize"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string>Unc: to label</string> + </property> + </widget> + </item> + <item row="4" column="0" colspan="2"> + <widget class="QLabel" name="label_36"> + <property name="text"> + <string>Label from Prediction Node</string> + </property> + </widget> + </item> + <item row="3" column="4"> + <spacer name="horizontalSpacer_5"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>57</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="4" column="3"> + <widget class="QPushButton" name="m_predlabelingBrush"> + <property name="maximumSize"> + <size> + <width>30</width> + <height>30</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="icon"> + <iconset> + <normaloff>:/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/brush.png</normaloff>:/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/brush.png</iconset> + </property> + <property name="iconSize"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="0" colspan="2"> + <widget class="QPushButton" name="m_CreatePrediction"> + <property name="text"> + <string>Create Prediction</string> + </property> + </widget> + </item> + <item row="3" column="2"> + <widget class="QPushButton" name="m_unclabeling"> + <property name="maximumSize"> + <size> + <width>30</width> + <height>30</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="icon"> + <iconset> + <normaloff>:/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/eraze.png</normaloff>:/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/eraze.png</iconset> + </property> + <property name="iconSize"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QSpinBox" name="m_Numtolabel"> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>2000</number> + </property> + <property name="singleStep"> + <number>0</number> + </property> + <property name="value"> + <number>20</number> + </property> + </widget> + </item> + <item row="3" column="3"> + <widget class="QPushButton" name="m_unclabelingBrush"> + <property name="maximumSize"> + <size> + <width>30</width> + <height>30</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="icon"> + <iconset> + <normaloff>:/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/brush.png</normaloff>:/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/brush.png</iconset> + </property> + <property name="iconSize"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="4" column="4"> + <spacer name="horizontalSpacer_6"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>57</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="5" column="0" colspan="2"> + <widget class="QPushButton" name="m_resetClassifier"> + <property name="text"> + <string>Reset Classifier</string> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="page_18"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>337</width> + <height>173</height> + </rect> + </property> + <attribute name="label"> + <string>Advanced</string> + </attribute> + <layout class="QGridLayout" name="gridLayout_30"> + <item row="6" column="0" colspan="4"> + <widget class="QLabel" name="label_37"> + <property name="text"> + <string>Label from Current Selection</string> + </property> + </widget> + </item> + <item row="0" column="0" colspan="3"> + <widget class="QPushButton" name="m_CreateUncertantyMap"> + <property name="text"> + <string>Create Uncertanty Map</string> + </property> + </widget> + </item> + <item row="0" column="5"> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="2" column="0" colspan="6"> + <widget class="QPushButton" name="m_distlabeling"> + <property name="text"> + <string>Unc_dis_Label</string> + </property> + </widget> + </item> + <item row="1" column="4" colspan="2"> + <widget class="QPushButton" name="m_AddDistanceFibers"> + <property name="text"> + <string>Add</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QSpinBox" name="m_subsetfft"> + <property name="maximum"> + <number>100</number> + </property> + <property name="value"> + <number>95</number> + </property> + </widget> + </item> + <item row="4" column="0" colspan="3"> + <widget class="QPushButton" name="m_certainData"> + <property name="text"> + <string>Certain Data</string> + </property> + </widget> + </item> + <item row="4" column="3" colspan="2"> + <widget class="QSpinBox" name="spinBox_2"> + <property name="maximum"> + <number>100</number> + </property> + </widget> + </item> + <item row="1" column="2" colspan="2"> + <widget class="QSpinBox" name="m_Numtolabel2"> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>500</number> + </property> + <property name="value"> + <number>20</number> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_9"> + <property name="text"> + <string>Dist: to label</string> + </property> + </widget> + </item> + <item row="7" column="3"> + <spacer name="verticalSpacer_6"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item row="6" column="4" colspan="2"> + <widget class="QPushButton" name="m_sellabeling"> + <property name="text"> + <string>Label</string> + </property> + </widget> + </item> + <item row="4" column="5"> + <widget class="QPushButton" name="m_RemoveCertainData"> + <property name="text"> + <string>Remove</string> + </property> + </widget> + </item> + </layout> + </widget> + </widget> + </item> + </layout> + </widget> + </widget> + <widget class="QWidget" name="page_5"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>399</width> + <height>439</height> + </rect> + </property> + <attribute name="label"> + <string>Validation</string> + </attribute> + <widget class="QFrame" name="frame_3"> + <property name="geometry"> + <rect> + <x>10</x> + <y>20</y> + <width>351</width> + <height>371</height> + </rect> + </property> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Raised</enum> + </property> + <layout class="QGridLayout" name="gridLayout_8"> + <item row="11" column="2"> + <spacer name="verticalSpacer_8"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="1" colspan="2"> + <widget class="QmitkDataStorageComboBox" name="m_PredictionBox"/> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label_11"> + <property name="text"> + <string>Prediction</string> + </property> + </widget> + </item> + <item row="1" column="1" colspan="2"> + <widget class="QmitkDataStorageComboBox" name="m_GroundtruthBox"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_12"> + <property name="text"> + <string>Groundtrouth</string> + </property> + </widget> + </item> + <item row="9" column="0" colspan="3"> + <widget class="QPushButton" name="m_validate"> + <property name="text"> + <string>Validate</string> + </property> + </widget> + </item> + <item row="10" column="0" colspan="3"> + <widget class="QPushButton" name="m_automaticLabelling"> + <property name="text"> + <string>Merge Prediction with Labled Data</string> + </property> + </widget> + </item> + </layout> + </widget> + </widget> + </widget> + </item> + <item row="0" column="0" rowspan="2"> + <widget class="QGroupBox" name="m_InputData"> + <property name="title"> + <string>Please Select Input Data</string> + </property> + <layout class="QGridLayout" name="gridLayout_9"> + <item row="1" column="0"> + <widget class="QLabel" name="label_13"> + <property name="text"> + <string>Training Fiber Bundle:</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label_2"> + <property name="toolTip"> + <string>Input DTI</string> + </property> + <property name="text"> + <string>Selectd Fiber Bundle:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QmitkDataStorageComboBox" name="m_TestBundleBox"/> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="m_FibLabel"> + <property name="text"> + <string><html><head/><body><p><span style=" color:#ff0000;">mandatory</span></p></body></html></string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>QmitkDataStorageComboBox</class> + <extends>QComboBox</extends> + <header location="global">QmitkDataStorageComboBox.h</header> + </customwidget> + <customwidget> + <class>QmitkSingleNodeSelectionWidget</class> + <extends>QWidget</extends> + <header location="global">QmitkSingleNodeSelectionWidget.h</header> + <container>1</container> + </customwidget> + <customwidget> + <class>QmitkPointListWidget</class> + <extends>QWidget</extends> + <header location="global">QmitkPointListWidget.h</header> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/mitkPluginActivator.cpp index 042b6c0..666fd1c 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/mitkPluginActivator.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/mitkPluginActivator.cpp @@ -1,51 +1,53 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkPluginActivator.h" #include "src/internal/Perspectives/QmitkFiberProcessingPerspective.h" #include "src/internal/QmitkFiberProcessingView.h" #include "src/internal/QmitkFiberQuantificationView.h" +#include "src/internal/QmitkInteractiveFiberDissectionView.h" #include "src/internal/QmitkFiberClusteringView.h" #include "src/internal/QmitkFiberFitView.h" #include "src/internal/QmitkTractometryView.h" ctkPluginContext* mitk::PluginActivator::m_Context = nullptr; ctkPluginContext* mitk::PluginActivator::GetContext() { return m_Context; } void mitk::PluginActivator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(QmitkFiberProcessingPerspective, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkFiberQuantificationView, context) + BERRY_REGISTER_EXTENSION_CLASS(QmitkInteractiveFiberDissectionView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkFiberProcessingView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkFiberClusteringView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkFiberFitView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkTractometryView, context) m_Context = context; } void mitk::PluginActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) m_Context = nullptr; }