diff --git a/Modules/DiffusionImaging/DiffusionCore/autoload/IO/mitkDiffusionCoreIOMimeTypes.cpp b/Modules/DiffusionImaging/DiffusionCore/autoload/IO/mitkDiffusionCoreIOMimeTypes.cpp index 8da13579db..b05a53cc8d 100644 --- a/Modules/DiffusionImaging/DiffusionCore/autoload/IO/mitkDiffusionCoreIOMimeTypes.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/autoload/IO/mitkDiffusionCoreIOMimeTypes.cpp @@ -1,494 +1,515 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. 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 "mitkDiffusionCoreIOMimeTypes.h" #include "mitkIOMimeTypes.h" #include #include #include #include #include #include #include #include +#include namespace mitk { std::vector DiffusionCoreIOMimeTypes::Get() { std::vector mimeTypes; // order matters here (descending rank for mime types) mimeTypes.push_back(DWI_NRRD_MIMETYPE().Clone()); mimeTypes.push_back(DWI_NIFTI_MIMETYPE().Clone()); mimeTypes.push_back(DWI_FSL_MIMETYPE().Clone()); mimeTypes.push_back(DWI_DICOM_MIMETYPE().Clone()); mimeTypes.push_back(DTI_MIMETYPE().Clone()); mimeTypes.push_back(ODF_MIMETYPE().Clone()); + mimeTypes.push_back(PEAK_MIMETYPE().Clone()); return mimeTypes; } // Mime Types DiffusionCoreIOMimeTypes::DiffusionImageNrrdMimeType::DiffusionImageNrrdMimeType() : CustomMimeType(DWI_NRRD_MIMETYPE_NAME()) { std::string category = "Diffusion Weighted Images"; this->SetCategory(category); this->SetComment("Diffusion Weighted Images"); this->AddExtension("dwi"); //this->AddExtension("hdwi"); // saving with detached header does not work out of the box this->AddExtension("nrrd"); } bool DiffusionCoreIOMimeTypes::DiffusionImageNrrdMimeType::AppliesTo(const std::string &path) const { bool canRead( CustomMimeType::AppliesTo(path) ); // fix for bug 18572 // Currently this function is called for writing as well as reading, in that case // the image information can of course not be read // This is a bug, this function should only be called for reading. if( ! itksys::SystemTools::FileExists( path.c_str() ) ) { return canRead; } //end fix for bug 18572 std::string ext = this->GetExtension( path ); ext = itksys::SystemTools::LowerCase( ext ); // Simple NRRD files should only be considered for this mime type if they contain // corresponding tags if( ext == ".nrrd" ) { itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New(); io->SetFileName(path); try { io->ReadImageInformation(); itk::MetaDataDictionary imgMetaDictionary = io->GetMetaDataDictionary(); std::vector imgMetaKeys = imgMetaDictionary.GetKeys(); std::vector::const_iterator itKey = imgMetaKeys.begin(); std::string metaString; for (; itKey != imgMetaKeys.end(); itKey ++) { itk::ExposeMetaData (imgMetaDictionary, *itKey, metaString); if (itKey->find("modality") != std::string::npos) { if (metaString.find("DWMRI") != std::string::npos) { return canRead; } } } } catch( const itk::ExceptionObject &e ) { MITK_ERROR << "ITK Exception: " << e.what(); } canRead = false; } return canRead; } DiffusionCoreIOMimeTypes::DiffusionImageNrrdMimeType* DiffusionCoreIOMimeTypes::DiffusionImageNrrdMimeType::Clone() const { return new DiffusionImageNrrdMimeType(*this); } DiffusionCoreIOMimeTypes::DiffusionImageNrrdMimeType DiffusionCoreIOMimeTypes::DWI_NRRD_MIMETYPE() { return DiffusionImageNrrdMimeType(); } DiffusionCoreIOMimeTypes::DiffusionImageNiftiMimeType::DiffusionImageNiftiMimeType() : CustomMimeType(DWI_NIFTI_MIMETYPE_NAME()) { std::string category = "Diffusion Weighted Images"; this->SetCategory(category); this->SetComment("Diffusion Weighted Images"); this->AddExtension("nii.gz"); this->AddExtension("nii"); } bool DiffusionCoreIOMimeTypes::DiffusionImageNiftiMimeType::AppliesTo(const std::string &path) const { bool canRead(CustomMimeType::AppliesTo(path)); // fix for bug 18572 // Currently this function is called for writing as well as reading, in that case // the image information can of course not be read // This is a bug, this function should only be called for reading. if (!itksys::SystemTools::FileExists(path.c_str())) { return canRead; } //end fix for bug 18572 std::string ext = this->GetExtension(path); ext = itksys::SystemTools::LowerCase(ext); // Nifti files should only be considered for this mime type if they are // accompanied by bvecs and bvals files defining the diffusion information if (ext == ".nii" || ext == ".nii.gz") { std::string base_path = itksys::SystemTools::GetFilenamePath(path); std::string base = this->GetFilenameWithoutExtension(path); std::string filename = base; if (!base_path.empty()) { base = base_path + "/" + base; base_path += "/"; } if (itksys::SystemTools::FileExists(std::string(base + ".bvec").c_str()) && itksys::SystemTools::FileExists(std::string(base + ".bval").c_str()) ) { return canRead; } if (itksys::SystemTools::FileExists(std::string(base + ".bvecs").c_str()) && itksys::SystemTools::FileExists(std::string(base + ".bvals").c_str()) ) { return canRead; } // hack for HCP data if ( filename=="data" && itksys::SystemTools::FileExists(std::string(base_path + "bvec").c_str()) && itksys::SystemTools::FileExists(std::string(base_path + "bval").c_str()) ) { return canRead; } if ( filename=="data" && itksys::SystemTools::FileExists(std::string(base_path + "bvecs").c_str()) && itksys::SystemTools::FileExists(std::string(base_path + "bvals").c_str()) ) { return canRead; } canRead = false; } return canRead; } DiffusionCoreIOMimeTypes::DiffusionImageNiftiMimeType* DiffusionCoreIOMimeTypes::DiffusionImageNiftiMimeType::Clone() const { return new DiffusionImageNiftiMimeType(*this); } DiffusionCoreIOMimeTypes::DiffusionImageNiftiMimeType DiffusionCoreIOMimeTypes::DWI_NIFTI_MIMETYPE() { return DiffusionImageNiftiMimeType(); } DiffusionCoreIOMimeTypes::DiffusionImageFslMimeType::DiffusionImageFslMimeType() : CustomMimeType(DWI_FSL_MIMETYPE_NAME()) { std::string category = "Diffusion Weighted Image"; this->SetCategory(category); this->SetComment("Diffusion Weighted Images"); this->AddExtension("fslgz"); this->AddExtension("fsl"); } bool DiffusionCoreIOMimeTypes::DiffusionImageFslMimeType::AppliesTo(const std::string &path) const { bool canRead(CustomMimeType::AppliesTo(path)); // fix for bug 18572 // Currently this function is called for writing as well as reading, in that case // the image information can of course not be read // This is a bug, this function should only be called for reading. if (!itksys::SystemTools::FileExists(path.c_str())) { return canRead; } //end fix for bug 18572 std::string ext = this->GetExtension(path); ext = itksys::SystemTools::LowerCase(ext); // Nifti files should only be considered for this mime type if they are // accompanied by bvecs and bvals files defining the diffusion information if (ext == ".fsl" || ext == ".fslgz") { std::string base_path = itksys::SystemTools::GetFilenamePath(path); std::string base = this->GetFilenameWithoutExtension(path); if (!base_path.empty()) base = base_path + "/" + base; if (itksys::SystemTools::FileExists(std::string(base + ".bvec").c_str()) && itksys::SystemTools::FileExists(std::string(base + ".bval").c_str()) ) { return canRead; } if (itksys::SystemTools::FileExists(std::string(base + ".bvecs").c_str()) && itksys::SystemTools::FileExists(std::string(base + ".bvals").c_str()) ) { return canRead; } if (itksys::SystemTools::FileExists(std::string(base + ext + ".bvec").c_str()) && itksys::SystemTools::FileExists(std::string(base + ext + ".bval").c_str()) ) { return canRead; } if (itksys::SystemTools::FileExists(std::string(base + ext + ".bvecs").c_str()) && itksys::SystemTools::FileExists(std::string(base + ext + ".bvals").c_str()) ) { return canRead; } canRead = false; } return canRead; } DiffusionCoreIOMimeTypes::DiffusionImageFslMimeType* DiffusionCoreIOMimeTypes::DiffusionImageFslMimeType::Clone() const { return new DiffusionImageFslMimeType(*this); } DiffusionCoreIOMimeTypes::DiffusionImageFslMimeType DiffusionCoreIOMimeTypes::DWI_FSL_MIMETYPE() { return DiffusionImageFslMimeType(); } DiffusionCoreIOMimeTypes::DiffusionImageDicomMimeType::DiffusionImageDicomMimeType() : CustomMimeType(DWI_DICOM_MIMETYPE_NAME()) { std::string category = "Diffusion Weighted Images"; this->SetCategory(category); this->SetComment("Diffusion Weighted Images"); this->AddExtension("gdcm"); this->AddExtension("dcm"); this->AddExtension("DCM"); this->AddExtension("dc3"); this->AddExtension("DC3"); this->AddExtension("ima"); this->AddExtension("img"); } bool DiffusionCoreIOMimeTypes::DiffusionImageDicomMimeType::AppliesTo(const std::string &path) const { itk::GDCMImageIO::Pointer gdcmIO = itk::GDCMImageIO::New(); bool canRead = gdcmIO->CanReadFile(path.c_str()); if (!canRead) return canRead; mitk::DICOMDCMTKTagScanner::Pointer scanner = mitk::DICOMDCMTKTagScanner::New(); mitk::DICOMTag ImageTypeTag(0x0008, 0x0008); mitk::StringList relevantFiles; relevantFiles.push_back(path); scanner->AddTag(ImageTypeTag); scanner->SetInputFiles(relevantFiles); scanner->Scan(); mitk::DICOMTagCache::Pointer tagCache = scanner->GetScanCache(); mitk::DICOMImageFrameList imageFrameList = mitk::ConvertToDICOMImageFrameList(tagCache->GetFrameInfoList()); mitk::DICOMImageFrameInfo *firstFrame = imageFrameList.begin()->GetPointer(); std::string byteString = tagCache->GetTagValue(firstFrame, ImageTypeTag).value; if (byteString.empty()) { return false; } std::size_t found = byteString.find("DIFFUSION"); if (found==std::string::npos) return false; found = byteString.find("NONE"); if (found==std::string::npos) return false; return canRead; } DiffusionCoreIOMimeTypes::DiffusionImageDicomMimeType* DiffusionCoreIOMimeTypes::DiffusionImageDicomMimeType::Clone() const { return new DiffusionImageDicomMimeType(*this); } DiffusionCoreIOMimeTypes::DiffusionImageDicomMimeType DiffusionCoreIOMimeTypes::DWI_DICOM_MIMETYPE() { return DiffusionImageDicomMimeType(); } -DiffusionCoreIOMimeTypes::PeakImageMimeType::PeakImageMimeType() - : CustomMimeType(PEAK_MIMETYPE_NAME()) +DiffusionCoreIOMimeTypes::PeakImageMimeType::PeakImageMimeType() : CustomMimeType(PEAK_MIMETYPE_NAME()) { std::string category = "Peak Image"; this->SetCategory(category); this->SetComment("Peak Image"); - this->AddExtension(".nrrd"); - this->AddExtension(".nii"); - this->AddExtension(".nii.gz"); + this->AddExtension("nrrd"); + this->AddExtension("nii"); + this->AddExtension("nii.gz"); } bool DiffusionCoreIOMimeTypes::PeakImageMimeType::AppliesTo(const std::string &path) const { - MITK_INFO << path; - return true; + { + itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New(); + if ( io->CanReadFile( path.c_str() ) ) + { + io->SetFileName( path.c_str() ); + io->ReadImageInformation(); + if ( io->GetPixelType() == itk::ImageIOBase::SCALAR && io->GetNumberOfDimensions()==4 && io->GetDimensions(3)%3==0) + return true; + } + } + { + itk::NiftiImageIO::Pointer io = itk::NiftiImageIO::New(); + if ( io->CanReadFile( path.c_str() ) ) + { + io->SetFileName( path.c_str() ); + io->ReadImageInformation(); + if ( io->GetPixelType() == itk::ImageIOBase::SCALAR && io->GetNumberOfDimensions()==4 && io->GetDimensions(3)%3==0) + return true; + } + } + + return false; } DiffusionCoreIOMimeTypes::PeakImageMimeType* DiffusionCoreIOMimeTypes::PeakImageMimeType::Clone() const { return new PeakImageMimeType(*this); } DiffusionCoreIOMimeTypes::PeakImageMimeType DiffusionCoreIOMimeTypes::PEAK_MIMETYPE() { return PeakImageMimeType(); } CustomMimeType DiffusionCoreIOMimeTypes::DTI_MIMETYPE() { CustomMimeType mimeType(DTI_MIMETYPE_NAME()); std::string category = "Tensor Images"; mimeType.SetComment("Diffusion Tensor Images"); mimeType.SetCategory(category); mimeType.AddExtension("dti"); return mimeType; } CustomMimeType DiffusionCoreIOMimeTypes::ODF_MIMETYPE() { CustomMimeType mimeType(ODF_MIMETYPE_NAME()); std::string category = "ODF Images"; mimeType.SetComment("Diffusion ODF Images"); mimeType.SetCategory(category); mimeType.AddExtension("odf"); mimeType.AddExtension("qbi"); // legacy support return mimeType; } // Names std::string DiffusionCoreIOMimeTypes::PEAK_MIMETYPE_NAME() { static std::string name = IOMimeTypes::DEFAULT_BASE_NAME() + ".nrrd"; return name; } std::string DiffusionCoreIOMimeTypes::DWI_NRRD_MIMETYPE_NAME() { static std::string name = IOMimeTypes::DEFAULT_BASE_NAME() + ".dwi"; return name; } std::string DiffusionCoreIOMimeTypes::DWI_NIFTI_MIMETYPE_NAME() { static std::string name = IOMimeTypes::DEFAULT_BASE_NAME() + ".nii.gz"; return name; } std::string DiffusionCoreIOMimeTypes::DWI_FSL_MIMETYPE_NAME() { static std::string name = IOMimeTypes::DEFAULT_BASE_NAME() + ".fslgz"; return name; } std::string DiffusionCoreIOMimeTypes::DWI_DICOM_MIMETYPE_NAME() { static std::string name = IOMimeTypes::DEFAULT_BASE_NAME() + ".IMA"; return name; } std::string DiffusionCoreIOMimeTypes::DTI_MIMETYPE_NAME() { static std::string name = IOMimeTypes::DEFAULT_BASE_NAME() + ".dti"; return name; } std::string DiffusionCoreIOMimeTypes::ODF_MIMETYPE_NAME() { static std::string name = IOMimeTypes::DEFAULT_BASE_NAME() + ".odf"; return name; } // Descriptions std::string DiffusionCoreIOMimeTypes::PEAK_MIMETYPE_DESCRIPTION() { static std::string description = "Peak Image"; return description; } std::string DiffusionCoreIOMimeTypes::DWI_NRRD_MIMETYPE_DESCRIPTION() { static std::string description = "Diffusion Weighted Images"; return description; } std::string DiffusionCoreIOMimeTypes::DWI_NIFTI_MIMETYPE_DESCRIPTION() { static std::string description = "Diffusion Weighted Images"; return description; } std::string DiffusionCoreIOMimeTypes::DWI_FSL_MIMETYPE_DESCRIPTION() { static std::string description = "Diffusion Weighted Images"; return description; } std::string DiffusionCoreIOMimeTypes::DWI_DICOM_MIMETYPE_DESCRIPTION() { static std::string description = "Diffusion Weighted Images"; return description; } std::string DiffusionCoreIOMimeTypes::DTI_MIMETYPE_DESCRIPTION() { static std::string description = "Diffusion Tensor Images"; return description; } std::string DiffusionCoreIOMimeTypes::ODF_MIMETYPE_DESCRIPTION() { static std::string description = "ODF Images"; return description; } } diff --git a/Modules/DiffusionImaging/DiffusionCore/include/Algorithms/itkFlipPeaksFilter.cpp b/Modules/DiffusionImaging/DiffusionCore/include/Algorithms/itkFlipPeaksFilter.cpp index 195bee9e96..0e1fc33aa9 100644 --- a/Modules/DiffusionImaging/DiffusionCore/include/Algorithms/itkFlipPeaksFilter.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/include/Algorithms/itkFlipPeaksFilter.cpp @@ -1,100 +1,99 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. 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 __itkFlipPeaksFilter_cpp #define __itkFlipPeaksFilter_cpp #include "itkFlipPeaksFilter.h" #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace boost::math; namespace itk { template< class PixelType > FlipPeaksFilter< PixelType>::FlipPeaksFilter() { this->SetNumberOfRequiredInputs(1); } template< class PixelType > void FlipPeaksFilter< PixelType> ::BeforeThreadedGenerateData() { typename InputImageType::Pointer input = static_cast< InputImageType* >( this->ProcessObject::GetInput(0) ); // typename OutputImageType::Pointer output = OutputImageType::New(); // output->SetSpacing( input->GetSpacing() ); // output->SetOrigin( input->GetOrigin() ); // output->SetDirection( input->GetDirection() ); // output->SetRegions( input->GetLargestPossibleRegion() ); // output->Allocate(); // output->FillBuffer(0.0); } template< class PixelType > void FlipPeaksFilter< PixelType> ::AfterThreadedGenerateData() { } template< class PixelType > void FlipPeaksFilter< PixelType> -::ThreadedGenerateData( const OutputImageRegionType& outputRegionForThread, ThreadIdType threadID ) +::ThreadedGenerateData( const OutputImageRegionType& outputRegionForThread, ThreadIdType ) { typename InputImageType::Pointer input_image = static_cast< InputImageType* >( this->ProcessObject::GetInput(0) ); typename OutputImageType::Pointer output_image = static_cast< OutputImageType* >( this->ProcessObject::GetOutput(0) ); ImageRegionIterator< InputImageType > iit(input_image, outputRegionForThread ); ImageRegionIterator< OutputImageType > oit(output_image, outputRegionForThread ); while( !iit.IsAtEnd() ) { typename InputImageType::IndexType idx = iit.GetIndex(); oit.Set(iit.Get()); if (m_FlipX && idx[3]%3==0) oit.Set(-1*iit.Get()); if (m_FlipY && idx[3]%3==1) oit.Set(-1*iit.Get()); if (m_FlipZ && idx[3]%3==2) oit.Set(-1*iit.Get()); ++iit; ++oit; } - MITK_INFO << "Thread " << threadID << " finished extraction"; } } #endif // __itkFlipPeaksFilter_cpp diff --git a/Modules/DiffusionImaging/DiffusionCore/include/IODataStructures/mitkPeakImage.h b/Modules/DiffusionImaging/DiffusionCore/include/IODataStructures/mitkPeakImage.h index 4df6f1d2e1..0904e739d6 100644 --- a/Modules/DiffusionImaging/DiffusionCore/include/IODataStructures/mitkPeakImage.h +++ b/Modules/DiffusionImaging/DiffusionCore/include/IODataStructures/mitkPeakImage.h @@ -1,64 +1,65 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. 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 __mitkPeakImage__h #define __mitkPeakImage__h #include "mitkImage.h" #include #include #include namespace mitk { /** * \brief this class encapsulates tensor images */ class MITKDIFFUSIONCORE_EXPORT PeakImage : public Image { public: typedef itk::Image ItkPeakImageType; mitkClassMacro( PeakImage, Image ) itkFactorylessNewMacro(Self) itkCloneMacro(Self) void ConstructPolydata(); vtkSmartPointer< vtkPolyData > GetPolyData() { if (m_PolyData==nullptr) this->ConstructPolydata(); return m_PolyData; } + void SetCustomColor(float r, float g, float b); + void ColorByOrientation(); + protected: PeakImage(); virtual ~PeakImage(); - void ColorByOrientation(); - mutable vtkSmartPointer< vtkPolyData > m_PolyData; }; } // namespace mitk #endif /* __mitkPeakImage__h */ diff --git a/Modules/DiffusionImaging/DiffusionCore/src/IODataStructures/mitkPeakImage.cpp b/Modules/DiffusionImaging/DiffusionCore/src/IODataStructures/mitkPeakImage.cpp index 9655dc598f..ce9d1938ee 100644 --- a/Modules/DiffusionImaging/DiffusionCore/src/IODataStructures/mitkPeakImage.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/src/IODataStructures/mitkPeakImage.cpp @@ -1,189 +1,221 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. 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 "mitkPeakImage.h" #include "mitkImageDataItem.h" #include "mitkImageCast.h" #include #include #include #include #include mitk::PeakImage::PeakImage() : Image() { m_PolyData = nullptr; } mitk::PeakImage::~PeakImage() { } void mitk::PeakImage::ConstructPolydata() { MITK_INFO << "PeakImage constructing polydata"; + if (this->GetDimensions()[3]%3!=0) + mitkThrow() << "Fourth dimension needs to be a multiple of 3"; typedef mitk::ImageToItk< ItkPeakImageType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(this); caster->Update(); ItkPeakImageType::ConstPointer itkImg = caster->GetOutput(); int sz_x = this->GetDimensions()[0]; int sz_y = this->GetDimensions()[1]; int sz_z = this->GetDimensions()[2]; unsigned int num_dirs = this->GetDimensions()[3]/3; double minSpacing = 1; ItkPeakImageType::SpacingType spacing = itkImg->GetSpacing(); if(spacing[0] m_VtkCellArray = vtkSmartPointer::New(); vtkSmartPointer m_VtkPoints = vtkSmartPointer::New(); #ifdef WIN32 #pragma omp parallel for #else #pragma omp parallel for collapse(3) #endif for (int x=0; x idx4; idx4[0] = x; idx4[1] = y; idx4[2] = z; for (unsigned int i=0; i center; center[0] = idx4[0]; center[1] = idx4[1]; center[2] = idx4[2]; center[3] = 0; itk::Point worldCenter; itkImg->TransformContinuousIndexToPhysicalPoint( center, worldCenter ); idx4[3] = 0; vnl_vector_fixed< float, 3 > dir; idx4[3] = i*3; dir[0] = itkImg->GetPixel(idx4); idx4[3] += 1; dir[1] = itkImg->GetPixel(idx4); idx4[3] += 1; dir[2] = itkImg->GetPixel(idx4); if (dir.magnitude()<0.001) continue; #pragma omp critical { vtkSmartPointer container = vtkSmartPointer::New(); // add direction to vector field (with spacing compensation) itk::Point worldStart; worldStart[0] = worldCenter[0]-dir[0]/2*minSpacing; worldStart[1] = worldCenter[1]-dir[1]/2*minSpacing; worldStart[2] = worldCenter[2]-dir[2]/2*minSpacing; vtkIdType id = m_VtkPoints->InsertNextPoint(worldStart.GetDataPointer()); container->GetPointIds()->InsertNextId(id); itk::Point worldEnd; worldEnd[0] = worldCenter[0]+dir[0]/2*minSpacing; worldEnd[1] = worldCenter[1]+dir[1]/2*minSpacing; worldEnd[2] = worldCenter[2]+dir[2]/2*minSpacing; id = m_VtkPoints->InsertNextPoint(worldEnd.GetDataPointer()); container->GetPointIds()->InsertNextId(id); m_VtkCellArray->InsertNextCell(container); } } } m_PolyData = vtkSmartPointer::New(); m_PolyData->SetPoints(m_VtkPoints); m_PolyData->SetLines(m_VtkCellArray); MITK_INFO << "PeakImage finished constructing polydata"; ColorByOrientation(); this->Modified(); } +void mitk::PeakImage::SetCustomColor(float r, float g, float b) +{ + vtkPoints* extrPoints = nullptr; + extrPoints = m_PolyData->GetPoints(); + int numOfPoints = 0; + if (extrPoints!=nullptr) + numOfPoints = extrPoints->GetNumberOfPoints(); + + int componentSize = 4; + + vtkSmartPointer colors = vtkSmartPointer::New(); + colors->Allocate(numOfPoints * componentSize); + colors->SetNumberOfComponents(componentSize); + colors->SetName("FIBER_COLORS"); + + unsigned char rgba[4] = {0,0,0,0}; + for(long i=0; iGetNumberOfPoints(); ++i) + { + rgba[0] = (unsigned char) r; + rgba[1] = (unsigned char) g; + rgba[2] = (unsigned char) b; + rgba[3] = (unsigned char) 255; + colors->InsertTypedTuple(i, rgba); + } + + m_PolyData->GetPointData()->AddArray(colors); + this->Modified(); +} + void mitk::PeakImage::ColorByOrientation() { //===== 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 = nullptr; extrPoints = m_PolyData->GetPoints(); int 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}; int componentSize = 4; vtkSmartPointer colors = vtkSmartPointer::New(); colors->Allocate(numOfPoints * componentSize); colors->SetNumberOfComponents(componentSize); colors->SetName("FIBER_COLORS"); int num_peaks = m_PolyData->GetNumberOfLines(); if (num_peaks < 1) return; vtkCellArray* fiberList = m_PolyData->GetLines(); fiberList->InitTraversal(); for (int fi=0; fiGetNextCell(num_points, idList); if (num_points == 2) { vnl_vector_fixed< double, 3 > currentPntvtk(extrPoints->GetPoint(idList[0])[0], extrPoints->GetPoint(idList[0])[1],extrPoints->GetPoint(idList[0])[2]); vnl_vector_fixed< double, 3 > nextPntvtk(extrPoints->GetPoint(idList[1])[0], extrPoints->GetPoint(idList[1])[1], extrPoints->GetPoint(idList[1])[2]); vnl_vector_fixed< double, 3 > diff1; diff1 = currentPntvtk - nextPntvtk; diff1.normalize(); rgba[0] = (unsigned char) (255.0 * std::fabs(diff1[0])); rgba[1] = (unsigned char) (255.0 * std::fabs(diff1[1])); rgba[2] = (unsigned char) (255.0 * std::fabs(diff1[2])); rgba[3] = (unsigned char) (255.0); colors->InsertTypedTuple(idList[0], rgba); colors->InsertTypedTuple(idList[1], rgba); } else { MITK_INFO << "Peak with point number!=2 detected!" ; continue; } } m_PolyData->GetPointData()->AddArray(colors); + this->Modified(); } diff --git a/Modules/DiffusionImaging/DiffusionIO/mitkDiffusionIOMimeTypes.cpp b/Modules/DiffusionImaging/DiffusionIO/mitkDiffusionIOMimeTypes.cpp index d23a1a97b4..bdfe381bad 100644 --- a/Modules/DiffusionImaging/DiffusionIO/mitkDiffusionIOMimeTypes.cpp +++ b/Modules/DiffusionImaging/DiffusionIO/mitkDiffusionIOMimeTypes.cpp @@ -1,250 +1,278 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. 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 "mitkDiffusionIOMimeTypes.h" #include "mitkIOMimeTypes.h" #include #include #include #include #include - -#include "dcmtk/dcmtract/trctractographyresults.h" +#include +#include +#include namespace mitk { std::vector DiffusionIOMimeTypes::Get() { std::vector mimeTypes; // order matters here (descending rank for mime types) mimeTypes.push_back(FIBERBUNDLE_VTK_MIMETYPE().Clone()); mimeTypes.push_back(FIBERBUNDLE_TRK_MIMETYPE().Clone()); mimeTypes.push_back(FIBERBUNDLE_TCK_MIMETYPE().Clone()); mimeTypes.push_back(FIBERBUNDLE_DICOM_MIMETYPE().Clone()); mimeTypes.push_back(CONNECTOMICS_MIMETYPE().Clone()); mimeTypes.push_back(TRACTOGRAPHYFOREST_MIMETYPE().Clone()); mimeTypes.push_back(PLANARFIGURECOMPOSITE_MIMETYPE().Clone()); return mimeTypes; } // Mime Types CustomMimeType DiffusionIOMimeTypes::PLANARFIGURECOMPOSITE_MIMETYPE() { CustomMimeType mimeType(PLANARFIGURECOMPOSITE_MIMETYPE_NAME()); std::string category = "Planar Figure Composite"; mimeType.SetComment("Planar Figure Composite"); mimeType.SetCategory(category); mimeType.AddExtension("pfc"); return mimeType; } CustomMimeType DiffusionIOMimeTypes::TRACTOGRAPHYFOREST_MIMETYPE() { CustomMimeType mimeType(TRACTOGRAPHYFOREST_MIMETYPE_NAME()); std::string category = "Tractography Forest"; mimeType.SetComment("Tractography Forest"); mimeType.SetCategory(category); mimeType.AddExtension("rf"); return mimeType; } CustomMimeType DiffusionIOMimeTypes::FIBERBUNDLE_VTK_MIMETYPE() { CustomMimeType mimeType(FIBERBUNDLE_VTK_MIMETYPE_NAME()); std::string category = "VTK Fibers"; mimeType.SetComment("VTK Fibers"); mimeType.SetCategory(category); mimeType.AddExtension("fib"); mimeType.AddExtension("vtk"); return mimeType; } CustomMimeType DiffusionIOMimeTypes::FIBERBUNDLE_TCK_MIMETYPE() { CustomMimeType mimeType(FIBERBUNDLE_TCK_MIMETYPE_NAME()); std::string category = "MRtrix Fibers"; mimeType.SetComment("MRtrix Fibers"); mimeType.SetCategory(category); mimeType.AddExtension("tck"); return mimeType; } CustomMimeType DiffusionIOMimeTypes::FIBERBUNDLE_TRK_MIMETYPE() { CustomMimeType mimeType(FIBERBUNDLE_TRK_MIMETYPE_NAME()); std::string category = "TrackVis Fibers"; mimeType.SetComment("TrackVis Fibers"); mimeType.SetCategory(category); mimeType.AddExtension("trk"); return mimeType; } DiffusionIOMimeTypes::FiberBundleDicomMimeType::FiberBundleDicomMimeType() : CustomMimeType(FIBERBUNDLE_DICOM_MIMETYPE_NAME()) { std::string category = "DICOM Fibers"; this->SetCategory(category); this->SetComment("DICOM Fibers"); this->AddExtension("dcm"); this->AddExtension("DCM"); this->AddExtension("gdcm"); this->AddExtension("dc3"); this->AddExtension("DC3"); this->AddExtension("ima"); this->AddExtension("img"); } bool DiffusionIOMimeTypes::FiberBundleDicomMimeType::AppliesTo(const std::string &path) const { - OFCondition result; - TrcTractographyResults *trc = NULL; - result = TrcTractographyResults::loadFile(path.c_str(), trc); - if (result.bad()) - return false; - - return true; + try + { + mitk::DICOMDCMTKTagScanner::Pointer scanner = mitk::DICOMDCMTKTagScanner::New(); + mitk::DICOMTag SOPInstanceUID(0x0008, 0x0016); + + mitk::StringList relevantFiles; + relevantFiles.push_back(path); + + scanner->AddTag(SOPInstanceUID); + scanner->SetInputFiles(relevantFiles); + scanner->Scan(); + mitk::DICOMTagCache::Pointer tagCache = scanner->GetScanCache(); + + mitk::DICOMImageFrameList imageFrameList = mitk::ConvertToDICOMImageFrameList(tagCache->GetFrameInfoList()); + if (imageFrameList.empty()) + return false; + + mitk::DICOMImageFrameInfo *firstFrame = imageFrameList.begin()->GetPointer(); + + std::string tag_value = tagCache->GetTagValue(firstFrame, SOPInstanceUID).value; + if (tag_value.empty()) { + return false; + } + + if (tag_value.compare(UID_TractographyResultsStorage)!=0) + return false; + + return true; + } + catch (std::exception& e) + { + MITK_INFO << e.what(); + } + return false; } DiffusionIOMimeTypes::FiberBundleDicomMimeType* DiffusionIOMimeTypes::FiberBundleDicomMimeType::Clone() const { return new FiberBundleDicomMimeType(*this); } DiffusionIOMimeTypes::FiberBundleDicomMimeType DiffusionIOMimeTypes::FIBERBUNDLE_DICOM_MIMETYPE() { return FiberBundleDicomMimeType(); } CustomMimeType DiffusionIOMimeTypes::CONNECTOMICS_MIMETYPE() { CustomMimeType mimeType(CONNECTOMICS_MIMETYPE_NAME()); std::string category = "Connectomics Networks"; mimeType.SetComment("Connectomics Networks Files"); mimeType.SetCategory(category); mimeType.AddExtension("cnf"); return mimeType; } CustomMimeType DiffusionIOMimeTypes::CONNECTOMICS_MATRIX_MIMETYPE() { CustomMimeType mimeType(CONNECTOMICS_MATRIX_MIMETYPE_NAME()); std::string category = "Connectomics Networks export"; mimeType.SetComment("Connectomics Matrix Files"); mimeType.SetCategory(category); mimeType.AddExtension("mat"); return mimeType; } CustomMimeType DiffusionIOMimeTypes::CONNECTOMICS_LIST_MIMETYPE() { CustomMimeType mimeType(CONNECTOMICS_LIST_MIMETYPE_NAME()); std::string category = "Connectomics Networks export"; mimeType.SetComment("Connectomics Connection Lists"); mimeType.SetCategory(category); mimeType.AddExtension("txt"); return mimeType; } // Names std::string DiffusionIOMimeTypes::FIBERBUNDLE_VTK_MIMETYPE_NAME() { static std::string name = IOMimeTypes::DEFAULT_BASE_NAME() + ".FiberBundle.vtk"; return name; } std::string DiffusionIOMimeTypes::FIBERBUNDLE_TCK_MIMETYPE_NAME() { static std::string name = IOMimeTypes::DEFAULT_BASE_NAME() + ".FiberBundle.tck"; return name; } std::string DiffusionIOMimeTypes::FIBERBUNDLE_TRK_MIMETYPE_NAME() { static std::string name = IOMimeTypes::DEFAULT_BASE_NAME() + ".FiberBundle.trk"; return name; } std::string DiffusionIOMimeTypes::FIBERBUNDLE_DICOM_MIMETYPE_NAME() { static std::string name = IOMimeTypes::DEFAULT_BASE_NAME() + ".FiberBundle.dcm"; return name; } std::string DiffusionIOMimeTypes::CONNECTOMICS_MIMETYPE_NAME() { static std::string name = IOMimeTypes::DEFAULT_BASE_NAME() + ".cnf"; return name; } std::string DiffusionIOMimeTypes::CONNECTOMICS_MATRIX_MIMETYPE_NAME() { static std::string name = IOMimeTypes::DEFAULT_BASE_NAME() + ".mat"; return name; } std::string DiffusionIOMimeTypes::CONNECTOMICS_LIST_MIMETYPE_NAME() { static std::string name = IOMimeTypes::DEFAULT_BASE_NAME() + ".txt"; return name; } std::string DiffusionIOMimeTypes::PLANARFIGURECOMPOSITE_MIMETYPE_NAME() { static std::string name = IOMimeTypes::DEFAULT_BASE_NAME() + ".pfc"; return name; } std::string DiffusionIOMimeTypes::TRACTOGRAPHYFOREST_MIMETYPE_NAME() { static std::string name = IOMimeTypes::DEFAULT_BASE_NAME() + ".rf"; return name; } // Descriptions std::string DiffusionIOMimeTypes::FIBERBUNDLE_MIMETYPE_DESCRIPTION() { static std::string description = "Fiberbundles"; return description; } std::string DiffusionIOMimeTypes::CONNECTOMICS_MIMETYPE_DESCRIPTION() { static std::string description = "Connectomics Networks"; return description; } std::string DiffusionIOMimeTypes::PLANARFIGURECOMPOSITE_MIMETYPE_DESCRIPTION() { static std::string description = "Planar Figure Composite"; return description; } std::string DiffusionIOMimeTypes::TRACTOGRAPHYFOREST_MIMETYPE_DESCRIPTION() { static std::string description = "Tractography Forest"; return description; } } diff --git a/Modules/DiffusionImaging/DiffusionIO/mitkPeakImageMapper2D.cpp b/Modules/DiffusionImaging/DiffusionIO/mitkPeakImageMapper2D.cpp index 608d7908fa..d8209d1276 100644 --- a/Modules/DiffusionImaging/DiffusionIO/mitkPeakImageMapper2D.cpp +++ b/Modules/DiffusionImaging/DiffusionIO/mitkPeakImageMapper2D.cpp @@ -1,235 +1,239 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. 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 "mitkPeakImageMapper2D.h" #include "mitkBaseRenderer.h" #include "mitkDataNode.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class vtkPeakShaderCallback : public vtkCommand { public: static vtkPeakShaderCallback *New() { return new vtkPeakShaderCallback; } mitk::BaseRenderer *renderer; mitk::DataNode *node; virtual void Execute(vtkObject *, unsigned long, void*cbo) { vtkOpenGLHelper *cellBO = reinterpret_cast(cbo); mitk::Image* image = dynamic_cast(node->GetData()); mitk::Vector3D spacing = image->GetGeometry()->GetSpacing(); float minSpacing = 1; if(spacing[0]GetOpacity(peakOpacity, nullptr); cellBO->Program->SetUniformf("peakOpacity", peakOpacity); cellBO->Program->SetUniformf("clippingPlaneThickness", minSpacing/2); if (this->renderer) { //get information about current position of views mitk::SliceNavigationController::Pointer sliceContr = renderer->GetSliceNavigationController(); mitk::PlaneGeometry::ConstPointer planeGeo = sliceContr->GetCurrentPlaneGeometry(); //generate according cutting planes based on the view position float planeNormal[3]; planeNormal[0] = planeGeo->GetNormal()[0]; planeNormal[1] = planeGeo->GetNormal()[1]; planeNormal[2] = planeGeo->GetNormal()[2]; float tmp1 = planeGeo->GetOrigin()[0] * planeNormal[0]; float tmp2 = planeGeo->GetOrigin()[1] * planeNormal[1]; float tmp3 = planeGeo->GetOrigin()[2] * planeNormal[2]; float thickness = tmp1 + tmp2 + tmp3; //attention, correct normalvector float* a = new float[4]; for (int i = 0; i < 3; ++i) a[i] = planeNormal[i]; a[3] = thickness; cellBO->Program->SetUniform4f("slicingPlane", a); } } vtkPeakShaderCallback() { this->renderer = 0; } }; mitk::PeakImageMapper2D::PeakImageMapper2D() { m_lut = vtkLookupTable::New(); m_lut->Build(); } mitk::PeakImageMapper2D::~PeakImageMapper2D() { } mitk::PeakImage* mitk::PeakImageMapper2D::GetInput() { return dynamic_cast< mitk::PeakImage * > ( GetDataNode()->GetData() ); } void mitk::PeakImageMapper2D::UpdateVtkTransform(mitk::BaseRenderer *) { // don't apply transform since the peak polydata is already in world coordinates. return; } void mitk::PeakImageMapper2D::Update(mitk::BaseRenderer * renderer) { mitk::DataNode* node = this->GetDataNode(); if (node == nullptr) return; bool visible = true; node->GetVisibility(visible, renderer, "visible"); if ( !visible ) return; this->GenerateDataForRenderer( renderer ); } void mitk::PeakImageMapper2D::UpdateShaderParameter(mitk::BaseRenderer *) { // see new vtkPeakShaderCallback } // vtkActors and Mappers are feeded here void mitk::PeakImageMapper2D::GenerateDataForRenderer(mitk::BaseRenderer *renderer) { mitk::PeakImage* peakImage = this->GetInput(); //the handler of local storage gets feeded in this method with requested data for related renderwindow FBXLocalStorage *localStorage = m_LocalStorageHandler.GetLocalStorage(renderer); vtkSmartPointer polyData = peakImage->GetPolyData(); if (polyData == nullptr) return; localStorage->m_Mapper->ScalarVisibilityOn(); localStorage->m_Mapper->SetScalarModeToUsePointFieldData(); localStorage->m_Mapper->SetLookupTable(m_lut); //apply the properties after the slice was set // localStorage->m_PointActor->GetProperty()->SetOpacity(0.999); localStorage->m_Mapper->SelectColorArray("FIBER_COLORS"); localStorage->m_Mapper->SetInputData(polyData); localStorage->m_Mapper->SetVertexShaderCode( "//VTK::System::Dec\n" "attribute vec4 vertexMC;\n" "//VTK::Normal::Dec\n" "uniform mat4 MCDCMatrix;\n" "//VTK::Color::Dec\n" "varying vec4 positionWorld;\n" "varying vec4 colorVertex;\n" "void main(void)\n" "{\n" " colorVertex = scalarColor;\n" " positionWorld = vertexMC;\n" " gl_Position = MCDCMatrix * vertexMC;\n" "}\n" ); localStorage->m_Mapper->SetFragmentShaderCode( "//VTK::System::Dec\n" // always start with this line "//VTK::Output::Dec\n" // always have this line in your FS "uniform vec4 slicingPlane;\n" "uniform float clippingPlaneThickness;\n" "uniform float peakOpacity;\n" "varying vec4 positionWorld;\n" "varying vec4 colorVertex;\n" "void main(void)\n" "{\n" " float r1 = dot(positionWorld.xyz, slicingPlane.xyz) - slicingPlane.w;\n" " if (abs(r1) >= clippingPlaneThickness)\n" " discard;\n" " gl_FragColor = vec4(colorVertex.xyz,peakOpacity);\n" "}\n" ); vtkSmartPointer myCallback = vtkSmartPointer::New(); myCallback->renderer = renderer; myCallback->node = this->GetDataNode(); localStorage->m_Mapper->AddObserver(vtkCommand::UpdateShaderEvent,myCallback); localStorage->m_PointActor->SetMapper(localStorage->m_Mapper); localStorage->m_PointActor->GetProperty()->ShadingOn(); -// localStorage->m_PointActor->GetProperty()->SetLineWidth(m_LineWidth); + + float linewidth = 1.0; + this->GetDataNode()->GetFloatProperty("shape.linewidth",linewidth); + localStorage->m_PointActor->GetProperty()->SetLineWidth(linewidth); // We have been modified => save this for next Update() localStorage->m_LastUpdateTime.Modified(); } vtkProp* mitk::PeakImageMapper2D::GetVtkProp(mitk::BaseRenderer *renderer) { this->Update(renderer); return m_LocalStorageHandler.GetLocalStorage(renderer)->m_PointActor; } void mitk::PeakImageMapper2D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { Superclass::SetDefaultProperties(node, renderer, overwrite); //add other parameters to propertylist node->AddProperty( "color", mitk::ColorProperty::New(1.0,1.0,1.0), renderer, overwrite); + node->AddProperty( "shape.linewidth", mitk::FloatProperty::New(1.0), renderer, overwrite); } mitk::PeakImageMapper2D::FBXLocalStorage::FBXLocalStorage() { m_PointActor = vtkSmartPointer::New(); m_Mapper = vtkSmartPointer::New(); } diff --git a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp index 5e8eaa3a58..8ccc04c04a 100644 --- a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp +++ b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp @@ -1,1180 +1,1189 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. 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 "QmitkDataManagerView.h" //# Own Includes //## mitk #include "mitkDataStorageEditorInput.h" #include "mitkIDataStorageReference.h" #include "mitkNodePredicateDataType.h" #include "mitkCoreObjectFactory.h" #include "mitkColorProperty.h" #include "mitkCommon.h" #include "mitkNodePredicateData.h" #include "mitkNodePredicateNot.h" #include "mitkNodePredicateOr.h" #include "mitkNodePredicateProperty.h" #include "mitkEnumerationProperty.h" #include "mitkLookupTableProperty.h" #include "mitkProperties.h" #include #include #include #include #include //## Qmitk #include #include #include #include #include #include #include #include "src/internal/QmitkNodeTableViewKeyFilter.h" #include "src/internal/QmitkInfoDialog.h" #include "src/internal/QmitkDataManagerItemDelegate.h" //## Berry #include #include #include #include #include #include #include #include //# Toolkit Includes #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "mitkDataNodeObject.h" #include "mitkIContextMenuAction.h" #include "berryIExtensionRegistry.h" #include "mitkRenderingModeProperty.h" const QString QmitkDataManagerView::VIEW_ID = "org.mitk.views.datamanager"; QmitkDataManagerView::QmitkDataManagerView() : m_GlobalReinitOnNodeDelete(true), m_ItemDelegate(nullptr) { } QmitkDataManagerView::~QmitkDataManagerView() { //Remove all registered actions from each descriptor for (std::vector< std::pair< QmitkNodeDescriptor*, QAction* > >::iterator it = m_DescriptorActionList.begin();it != m_DescriptorActionList.end(); it++) { // first== the NodeDescriptor; second== the registered QAction (it->first)->RemoveAction(it->second); } } void QmitkDataManagerView::CreateQtPartControl(QWidget* parent) { m_CurrentRowCount = 0; m_Parent = parent; //# Preferences berry::IPreferencesService* prefService = berry::Platform::GetPreferencesService(); berry::IBerryPreferences::Pointer prefs = (prefService->GetSystemPreferences()->Node(VIEW_ID)) .Cast(); assert( prefs ); prefs->OnChanged.AddListener( berry::MessageDelegate1( this , &QmitkDataManagerView::OnPreferencesChanged ) ); //# GUI m_NodeTreeModel = new QmitkDataStorageTreeModel(this->GetDataStorage()); m_NodeTreeModel->setParent( parent ); m_NodeTreeModel->SetPlaceNewNodesOnTop( prefs->GetBool("Place new nodes on top", true) ); m_NodeTreeModel->SetAllowHierarchyChange( prefs->GetBool("Allow changing of parent node", false)); m_SurfaceDecimation = prefs->GetBool("Use surface decimation", false); // Prepare filters m_HelperObjectFilterPredicate = mitk::NodePredicateOr::New( mitk::NodePredicateProperty::New("helper object", mitk::BoolProperty::New(true)), mitk::NodePredicateProperty::New("hidden object", mitk::BoolProperty::New(true))); m_NodeWithNoDataFilterPredicate = mitk::NodePredicateData::New(0); m_FilterModel = new QmitkDataStorageFilterProxyModel(); m_FilterModel->setSourceModel(m_NodeTreeModel); m_FilterModel->AddFilterPredicate(m_HelperObjectFilterPredicate); m_FilterModel->AddFilterPredicate(m_NodeWithNoDataFilterPredicate); //# Tree View (experimental) m_NodeTreeView = new QTreeView; m_NodeTreeView->setHeaderHidden(true); m_NodeTreeView->setSelectionMode( QAbstractItemView::ExtendedSelection ); m_NodeTreeView->setSelectionBehavior( QAbstractItemView::SelectRows ); m_NodeTreeView->setAlternatingRowColors(true); m_NodeTreeView->setDragEnabled(true); m_NodeTreeView->setDropIndicatorShown(true); m_NodeTreeView->setAcceptDrops(true); m_NodeTreeView->setContextMenuPolicy(Qt::CustomContextMenu); m_NodeTreeView->setModel(m_FilterModel); m_NodeTreeView->setTextElideMode(Qt::ElideMiddle); m_NodeTreeView->installEventFilter(new QmitkNodeTableViewKeyFilter(this)); m_ItemDelegate = new QmitkDataManagerItemDelegate(m_NodeTreeView); m_NodeTreeView->setItemDelegate(m_ItemDelegate); QObject::connect( m_NodeTreeView, SIGNAL(customContextMenuRequested(const QPoint&)) , this, SLOT(NodeTableViewContextMenuRequested(const QPoint&)) ); QObject::connect( m_NodeTreeModel, SIGNAL(rowsInserted (const QModelIndex&, int, int)) , this, SLOT(NodeTreeViewRowsInserted ( const QModelIndex&, int, int )) ); QObject::connect( m_NodeTreeModel, SIGNAL(rowsRemoved (const QModelIndex&, int, int)) , this, SLOT(NodeTreeViewRowsRemoved( const QModelIndex&, int, int )) ); QObject::connect( m_NodeTreeView->selectionModel() , SIGNAL( selectionChanged ( const QItemSelection &, const QItemSelection & ) ) , this , SLOT( NodeSelectionChanged ( const QItemSelection &, const QItemSelection & ) ) ); //# m_NodeMenu m_NodeMenu = new QMenu(m_NodeTreeView); // # Actions berry::IEditorRegistry* editorRegistry = berry::PlatformUI::GetWorkbench()->GetEditorRegistry(); QList editors = editorRegistry->GetEditors("*.mitk"); if (editors.size() > 1) { m_ShowInMapper = new QSignalMapper(this); foreach(berry::IEditorDescriptor::Pointer descriptor, editors) { QAction* action = new QAction(descriptor->GetLabel(), this); m_ShowInActions << action; m_ShowInMapper->connect(action, SIGNAL(triggered()), m_ShowInMapper, SLOT(map())); m_ShowInMapper->setMapping(action, descriptor->GetId()); } connect(m_ShowInMapper, SIGNAL(mapped(QString)), this, SLOT(ShowIn(QString))); } auto unknownDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetUnknownDataNodeDescriptor(); auto imageDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("Image"); auto multiComponentImageDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("MultiComponentImage"); auto diffusionImageDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("DiffusionImage"); auto fiberBundleDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("FiberBundle"); + auto peakImageDataNodeDescriptor = + QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PeakImage"); + auto surfaceDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("Surface"); auto pointSetNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PointSet"); auto planarLineNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarLine"); auto planarCircleNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarCircle"); auto planarEllipseNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarEllipse"); auto planarAngleNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarAngle"); auto planarFourPointAngleNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarFourPointAngle"); auto planarRectangleNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarRectangle"); auto planarPolygonNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarPolygon"); auto planarPathNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarPath"); auto planarDoubleEllipseNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarDoubleEllipse"); auto planarBezierCurveNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarBezierCurve"); auto planarSubdivisionPolygonNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarSubdivisionPolygon"); QAction* globalReinitAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/Refresh_48.png"), tr("Global Reinit"), this); QObject::connect( globalReinitAction, SIGNAL( triggered(bool) ) , this, SLOT( GlobalReinit(bool) ) ); unknownDataNodeDescriptor->AddAction(globalReinitAction); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor, globalReinitAction)); QAction* saveAction = new QmitkFileSaveAction(QIcon(":/org.mitk.gui.qt.datamanager/Save_48.png"), this->GetSite()->GetWorkbenchWindow()); unknownDataNodeDescriptor->AddAction(saveAction); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,saveAction)); QAction* removeAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/Remove_48.png"), tr("Remove"), this); QObject::connect( removeAction, SIGNAL( triggered(bool) ) , this, SLOT( RemoveSelectedNodes(bool) ) ); unknownDataNodeDescriptor->AddAction(removeAction); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,removeAction)); QAction* reinitAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/Refresh_48.png"), tr("Reinit"), this); QObject::connect( reinitAction, SIGNAL( triggered(bool) ) , this, SLOT( ReinitSelectedNodes(bool) ) ); unknownDataNodeDescriptor->AddAction(reinitAction); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,reinitAction)); // find contextMenuAction extension points and add them to the node descriptor berry::IExtensionRegistry* extensionPointService = berry::Platform::GetExtensionRegistry(); QList customMenuConfigs = extensionPointService->GetConfigurationElementsFor("org.mitk.gui.qt.datamanager.contextMenuActions"); // Prepare all custom QActions m_ConfElements.clear(); DescriptorActionListType customMenuEntries; for (auto& customMenuConfig : customMenuConfigs) { QString actionNodeDescriptorName = customMenuConfig->GetAttribute("nodeDescriptorName"); QString actionLabel = customMenuConfig->GetAttribute("label"); QString actionClass = customMenuConfig->GetAttribute("class"); if (actionNodeDescriptorName.isEmpty() || actionLabel.isEmpty() || actionClass.isEmpty()) { continue; } QString actionIconName = customMenuConfig->GetAttribute("icon"); // Find matching descriptor auto nodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor(actionNodeDescriptorName); if ( nodeDescriptor == nullptr) { MITK_WARN << "Cannot add action \"" << actionLabel << "\" because descriptor " << actionNodeDescriptorName << " does not exist."; continue; } // Create action with or without icon QAction* contextMenuAction; if ( !actionIconName.isEmpty() ) { QIcon actionIcon; if ( QFile::exists(actionIconName) ) { actionIcon = QIcon(actionIconName); } else { actionIcon = berry::AbstractUICTKPlugin::ImageDescriptorFromPlugin( customMenuConfig->GetContributor()->GetName(), actionIconName); } contextMenuAction = new QAction(actionIcon, actionLabel, parent); } else { contextMenuAction = new QAction(actionLabel, parent); } // Define menu handler to trigger on click connect(contextMenuAction, static_cast(&QAction::triggered), this, &QmitkDataManagerView::ContextMenuActionTriggered); // Mark configuration element into lookup list for context menu handler m_ConfElements[contextMenuAction] = customMenuConfig; // Mark new action in sortable list for addition to descriptor customMenuEntries.emplace_back(nodeDescriptor, contextMenuAction); } // Sort all custom QActions by their texts { using ListEntryType = std::pair; std::sort(customMenuEntries.begin(), customMenuEntries.end(), [](const ListEntryType& left, const ListEntryType& right) -> bool { assert (left.second != nullptr && right.second != nullptr); // unless we messed up above return left.second->text() < right.second->text(); }); } // Add custom QActions in sorted order int globalAddedMenuIndex=1; for (auto& menuEntryToAdd : customMenuEntries) { auto& nodeDescriptor = menuEntryToAdd.first; auto& contextMenuAction = menuEntryToAdd.second; // TODO is the action "data" used by anything? Otherwise remove! contextMenuAction->setData(static_cast(globalAddedMenuIndex)); ++globalAddedMenuIndex; // Really add this action to that descriptor (in pre-defined order) nodeDescriptor->AddAction(contextMenuAction); // Mark new action into list of descriptors to remove in d'tor m_DescriptorActionList.push_back(menuEntryToAdd); } m_OpacitySlider = new QSlider; m_OpacitySlider->setMinimum(0); m_OpacitySlider->setMaximum(100); m_OpacitySlider->setOrientation(Qt::Horizontal); QObject::connect( m_OpacitySlider, SIGNAL( valueChanged(int) ) , this, SLOT( OpacityChanged(int) ) ); QLabel* _OpacityLabel = new QLabel(tr("Opacity: ")); QHBoxLayout* _OpacityWidgetLayout = new QHBoxLayout; _OpacityWidgetLayout->setContentsMargins(4,4,4,4); _OpacityWidgetLayout->addWidget(_OpacityLabel); _OpacityWidgetLayout->addWidget(m_OpacitySlider); QWidget* _OpacityWidget = new QWidget; _OpacityWidget->setLayout(_OpacityWidgetLayout); QWidgetAction* opacityAction = new QWidgetAction(this); opacityAction ->setDefaultWidget(_OpacityWidget); QObject::connect( opacityAction , SIGNAL( changed() ) , this, SLOT( OpacityActionChanged() ) ); unknownDataNodeDescriptor->AddAction(opacityAction , false); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,opacityAction)); m_ColorButton = new QPushButton; m_ColorButton->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Minimum); //m_ColorButton->setText("Change color"); QObject::connect( m_ColorButton, SIGNAL( clicked() ) , this, SLOT( ColorChanged() ) ); QLabel* _ColorLabel = new QLabel(tr("Color: ")); _ColorLabel->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); QHBoxLayout* _ColorWidgetLayout = new QHBoxLayout; _ColorWidgetLayout->setContentsMargins(4,4,4,4); _ColorWidgetLayout->addWidget(_ColorLabel); _ColorWidgetLayout->addWidget(m_ColorButton); QWidget* _ColorWidget = new QWidget; _ColorWidget->setLayout(_ColorWidgetLayout); QWidgetAction* colorAction = new QWidgetAction(this); colorAction->setDefaultWidget(_ColorWidget); QObject::connect( colorAction, SIGNAL( changed() ) , this, SLOT( ColorActionChanged() ) ); { // only give the color context menu option where appropriate if (imageDataNodeDescriptor != nullptr) { imageDataNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back( std::pair(imageDataNodeDescriptor, colorAction)); } if (multiComponentImageDataNodeDescriptor != nullptr) { multiComponentImageDataNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back( std::pair(multiComponentImageDataNodeDescriptor, colorAction)); } if (diffusionImageDataNodeDescriptor != nullptr) { diffusionImageDataNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back( std::pair(diffusionImageDataNodeDescriptor, colorAction)); } if (fiberBundleDataNodeDescriptor != nullptr) { fiberBundleDataNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back( std::pair(fiberBundleDataNodeDescriptor, colorAction)); } + if (peakImageDataNodeDescriptor != nullptr) + { + peakImageDataNodeDescriptor->AddAction(colorAction, false); + m_DescriptorActionList.push_back( + std::pair(peakImageDataNodeDescriptor, colorAction)); + } if (surfaceDataNodeDescriptor != nullptr) { surfaceDataNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back( std::pair(surfaceDataNodeDescriptor, colorAction)); } if (pointSetNodeDescriptor != nullptr) { pointSetNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back( std::pair(pointSetNodeDescriptor, colorAction)); } if (planarLineNodeDescriptor != nullptr) { planarLineNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back( std::pair(planarLineNodeDescriptor, colorAction)); } if (planarCircleNodeDescriptor != nullptr) { planarCircleNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back( std::pair(planarCircleNodeDescriptor, colorAction)); } if (planarEllipseNodeDescriptor != nullptr) { planarEllipseNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back( std::pair(planarEllipseNodeDescriptor, colorAction)); } if (planarAngleNodeDescriptor != nullptr) { planarAngleNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back( std::pair(planarAngleNodeDescriptor, colorAction)); } if (planarFourPointAngleNodeDescriptor != nullptr) { planarFourPointAngleNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back( std::pair(planarFourPointAngleNodeDescriptor, colorAction)); } if (planarRectangleNodeDescriptor != nullptr) { planarRectangleNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back( std::pair(planarRectangleNodeDescriptor, colorAction)); } if (planarPolygonNodeDescriptor != nullptr) { planarPolygonNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back( std::pair(planarPolygonNodeDescriptor, colorAction)); } if (planarPathNodeDescriptor != nullptr) { planarPathNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back( std::pair(planarPathNodeDescriptor, colorAction)); } if (planarDoubleEllipseNodeDescriptor != nullptr) { planarDoubleEllipseNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back( std::pair(planarDoubleEllipseNodeDescriptor, colorAction)); } if (planarBezierCurveNodeDescriptor != nullptr) { planarBezierCurveNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back( std::pair(planarBezierCurveNodeDescriptor, colorAction)); } if (planarSubdivisionPolygonNodeDescriptor != nullptr) { planarSubdivisionPolygonNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back( std::pair(planarSubdivisionPolygonNodeDescriptor, colorAction)); } } m_ComponentSlider = new QmitkNumberPropertySlider; m_ComponentSlider->setOrientation(Qt::Horizontal); //QObject::connect( m_OpacitySlider, SIGNAL( valueChanged(int) ) // , this, SLOT( OpacityChanged(int) ) ); QLabel* _ComponentLabel = new QLabel(tr("Component: ")); QHBoxLayout* _ComponentWidgetLayout = new QHBoxLayout; _ComponentWidgetLayout->setContentsMargins(4,4,4,4); _ComponentWidgetLayout->addWidget(_ComponentLabel); _ComponentWidgetLayout->addWidget(m_ComponentSlider); QLabel* _ComponentValueLabel = new QLabel(); _ComponentWidgetLayout->addWidget(_ComponentValueLabel); connect(m_ComponentSlider, SIGNAL(valueChanged(int)), _ComponentValueLabel, SLOT(setNum(int))); QWidget* _ComponentWidget = new QWidget; _ComponentWidget->setLayout(_ComponentWidgetLayout); QWidgetAction* componentAction = new QWidgetAction(this); componentAction->setDefaultWidget(_ComponentWidget); QObject::connect( componentAction , SIGNAL( changed() ) , this, SLOT( ComponentActionChanged() ) ); multiComponentImageDataNodeDescriptor->AddAction(componentAction, false); m_DescriptorActionList.push_back(std::pair(multiComponentImageDataNodeDescriptor,componentAction)); if (diffusionImageDataNodeDescriptor!=nullptr) { diffusionImageDataNodeDescriptor->AddAction(componentAction, false); m_DescriptorActionList.push_back(std::pair(diffusionImageDataNodeDescriptor,componentAction)); } m_TextureInterpolation = new QAction(tr("Texture Interpolation"), this); m_TextureInterpolation->setCheckable ( true ); QObject::connect( m_TextureInterpolation, SIGNAL( changed() ) , this, SLOT( TextureInterpolationChanged() ) ); QObject::connect( m_TextureInterpolation, SIGNAL( toggled(bool) ) , this, SLOT( TextureInterpolationToggled(bool) ) ); imageDataNodeDescriptor->AddAction(m_TextureInterpolation, false); m_DescriptorActionList.push_back(std::pair(imageDataNodeDescriptor,m_TextureInterpolation)); if (diffusionImageDataNodeDescriptor!=nullptr) { diffusionImageDataNodeDescriptor->AddAction(m_TextureInterpolation, false); m_DescriptorActionList.push_back(std::pair(diffusionImageDataNodeDescriptor,m_TextureInterpolation)); } m_ColormapAction = new QAction(tr("Colormap"), this); m_ColormapAction->setMenu(new QMenu); QObject::connect( m_ColormapAction->menu(), SIGNAL( aboutToShow() ) , this, SLOT( ColormapMenuAboutToShow() ) ); imageDataNodeDescriptor->AddAction(m_ColormapAction, false); m_DescriptorActionList.push_back(std::pair(imageDataNodeDescriptor, m_ColormapAction)); if (diffusionImageDataNodeDescriptor!=nullptr) { diffusionImageDataNodeDescriptor->AddAction(m_ColormapAction, false); m_DescriptorActionList.push_back(std::pair(diffusionImageDataNodeDescriptor, m_ColormapAction)); } m_SurfaceRepresentation = new QAction(tr("Surface Representation"), this); m_SurfaceRepresentation->setMenu(new QMenu(m_NodeTreeView)); QObject::connect( m_SurfaceRepresentation->menu(), SIGNAL( aboutToShow() ) , this, SLOT( SurfaceRepresentationMenuAboutToShow() ) ); surfaceDataNodeDescriptor->AddAction(m_SurfaceRepresentation, false); m_DescriptorActionList.push_back(std::pair(surfaceDataNodeDescriptor, m_SurfaceRepresentation)); QAction* showOnlySelectedNodes = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/ShowSelectedNode_48.png") , tr("Show only selected nodes"), this); QObject::connect( showOnlySelectedNodes, SIGNAL( triggered(bool) ) , this, SLOT( ShowOnlySelectedNodes(bool) ) ); unknownDataNodeDescriptor->AddAction(showOnlySelectedNodes); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor, showOnlySelectedNodes)); QAction* toggleSelectedVisibility = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/InvertShowSelectedNode_48.png") , tr("Toggle visibility"), this); QObject::connect( toggleSelectedVisibility, SIGNAL( triggered(bool) ) , this, SLOT( ToggleVisibilityOfSelectedNodes(bool) ) ); unknownDataNodeDescriptor->AddAction(toggleSelectedVisibility); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,toggleSelectedVisibility)); QAction* actionShowInfoDialog = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/ShowDataInfo_48.png") , tr("Details..."), this); QObject::connect( actionShowInfoDialog, SIGNAL( triggered(bool) ) , this, SLOT( ShowInfoDialogForSelectedNodes(bool) ) ); unknownDataNodeDescriptor->AddAction(actionShowInfoDialog); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,actionShowInfoDialog)); QGridLayout* _DndFrameWidgetLayout = new QGridLayout; _DndFrameWidgetLayout->addWidget(m_NodeTreeView, 0, 0); _DndFrameWidgetLayout->setContentsMargins(0,0,0,0); m_DndFrameWidget = new QmitkDnDFrameWidget(m_Parent); m_DndFrameWidget->setLayout(_DndFrameWidgetLayout); QVBoxLayout* layout = new QVBoxLayout(parent); layout->addWidget(m_DndFrameWidget); layout->setContentsMargins(0,0,0,0); m_Parent->setLayout(layout); } void QmitkDataManagerView::SetFocus() { } void QmitkDataManagerView::ContextMenuActionTriggered( bool ) { QAction* action = qobject_cast ( sender() ); std::map::iterator it = m_ConfElements.find( action ); if( it == m_ConfElements.end() ) { MITK_WARN << "associated conf element for action " << action->text().toStdString() << " not found"; return; } berry::IConfigurationElement::Pointer confElem = it->second; mitk::IContextMenuAction* contextMenuAction = confElem->CreateExecutableExtension("class"); QString className = confElem->GetAttribute("class"); QString smoothed = confElem->GetAttribute("smoothed"); contextMenuAction->SetDataStorage(this->GetDataStorage()); if(className == "QmitkCreatePolygonModelAction") { if(smoothed == "false") { contextMenuAction->SetSmoothed(false); } else { contextMenuAction->SetSmoothed(true); } contextMenuAction->SetDecimated(m_SurfaceDecimation); } else if(className == "QmitkStatisticsAction") { contextMenuAction->SetFunctionality(this); } contextMenuAction->Run( this->GetCurrentSelection() ); // run the action } void QmitkDataManagerView::OnPreferencesChanged(const berry::IBerryPreferences* prefs) { if( m_NodeTreeModel->GetPlaceNewNodesOnTopFlag() != prefs->GetBool("Place new nodes on top", true) ) m_NodeTreeModel->SetPlaceNewNodesOnTop( !m_NodeTreeModel->GetPlaceNewNodesOnTopFlag() ); bool hideHelperObjects = !prefs->GetBool("Show helper objects", false); if (m_FilterModel->HasFilterPredicate(m_HelperObjectFilterPredicate) != hideHelperObjects) { if (hideHelperObjects) { m_FilterModel->AddFilterPredicate(m_HelperObjectFilterPredicate); } else { m_FilterModel->RemoveFilterPredicate(m_HelperObjectFilterPredicate); } } bool hideNodesWithNoData = !prefs->GetBool("Show nodes containing no data", false); if (m_FilterModel->HasFilterPredicate(m_NodeWithNoDataFilterPredicate) != hideNodesWithNoData) { if (hideNodesWithNoData) { m_FilterModel->AddFilterPredicate(m_NodeWithNoDataFilterPredicate); } else { m_FilterModel->RemoveFilterPredicate(m_NodeWithNoDataFilterPredicate); } } m_GlobalReinitOnNodeDelete = prefs->GetBool("Call global reinit if node is deleted", true); m_NodeTreeView->expandAll(); m_SurfaceDecimation = prefs->GetBool("Use surface decimation", false); m_NodeTreeModel->SetAllowHierarchyChange( prefs->GetBool("Allow changing of parent node", false)); this->GlobalReinit(); } void QmitkDataManagerView::NodeTableViewContextMenuRequested( const QPoint & pos ) { QModelIndex selectedProxy = m_NodeTreeView->indexAt ( pos ); QModelIndex selected = m_FilterModel->mapToSource(selectedProxy); mitk::DataNode::Pointer node = m_NodeTreeModel->GetNode(selected); QList selectedNodes = this->GetCurrentSelection(); if(!selectedNodes.isEmpty()) { m_NodeMenu->clear(); QList actions; if(selectedNodes.size() == 1 ) { actions = QmitkNodeDescriptorManager::GetInstance()->GetActions(node); for(QList::iterator it = actions.begin(); it != actions.end(); ++it) { (*it)->setData(QVariant::fromValue(node.GetPointer())); } } else actions = QmitkNodeDescriptorManager::GetInstance()->GetActions(selectedNodes); if (!m_ShowInActions.isEmpty()) { QMenu* showInMenu = m_NodeMenu->addMenu(tr("Show In")); showInMenu->addActions(m_ShowInActions); } m_NodeMenu->addActions(actions); m_NodeMenu->popup(QCursor::pos()); } } void QmitkDataManagerView::OpacityChanged(int value) { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); if(node) { float opacity = static_cast(value)/100.0f; node->SetFloatProperty("opacity", opacity); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkDataManagerView::OpacityActionChanged() { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); if(node) { float opacity = 0.0; if(node->GetFloatProperty("opacity", opacity)) { m_OpacitySlider->setValue(static_cast(opacity*100)); } } } void QmitkDataManagerView::ComponentActionChanged() { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); mitk::IntProperty* componentProperty = nullptr; int numComponents = 0; if(node) { componentProperty = dynamic_cast(node->GetProperty("Image.Displayed Component")); mitk::Image* img = dynamic_cast(node->GetData()); if (img != nullptr) { numComponents = img->GetPixelType().GetNumberOfComponents(); } } if (componentProperty && numComponents > 1) { m_ComponentSlider->SetProperty(componentProperty); m_ComponentSlider->setMinValue(0); m_ComponentSlider->setMaxValue(numComponents-1); } else { m_ComponentSlider->SetProperty(static_cast(nullptr)); } } void QmitkDataManagerView::ColorChanged() { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); if(node) { mitk::Color color; mitk::ColorProperty::Pointer colorProp; node->GetProperty(colorProp,"color"); if(colorProp.IsNull()) return; color = colorProp->GetValue(); QColor initial(color.GetRed()*255,color.GetGreen()*255,color.GetBlue()*255); QColor qcolor = QColorDialog::getColor(initial,0,QString(tr("Change color"))); if (!qcolor.isValid()) return; m_ColorButton->setAutoFillBackground(true); node->SetProperty("color",mitk::ColorProperty::New(qcolor.red()/255.0,qcolor.green()/255.0,qcolor.blue()/255.0)); if (node->GetProperty("binaryimage.selectedcolor")) { node->SetProperty("binaryimage.selectedcolor",mitk::ColorProperty::New(qcolor.red()/255.0,qcolor.green()/255.0,qcolor.blue()/255.0)); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkDataManagerView::ColorActionChanged() { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); if(node) { mitk::Color color; mitk::ColorProperty::Pointer colorProp; node->GetProperty(colorProp,"color"); if(colorProp.IsNull()) return; color = colorProp->GetValue(); QString styleSheet = "background-color:rgb("; styleSheet.append(QString::number(color[0]*255)); styleSheet.append(","); styleSheet.append(QString::number(color[1]*255)); styleSheet.append(","); styleSheet.append(QString::number(color[2]*255)); styleSheet.append(")"); m_ColorButton->setStyleSheet(styleSheet); } } void QmitkDataManagerView::TextureInterpolationChanged() { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); if(node) { bool textureInterpolation = false; node->GetBoolProperty("texture interpolation", textureInterpolation); m_TextureInterpolation->setChecked(textureInterpolation); } } void QmitkDataManagerView::TextureInterpolationToggled( bool checked ) { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); if(node) { node->SetBoolProperty("texture interpolation", checked); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkDataManagerView::ColormapActionToggled( bool /*checked*/ ) { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); if(!node) return; mitk::LookupTableProperty::Pointer lookupTableProperty = dynamic_cast(node->GetProperty("LookupTable")); if (!lookupTableProperty) return; QAction* senderAction = qobject_cast(QObject::sender()); if(!senderAction) return; std::string activatedItem = senderAction->text().toStdString(); mitk::LookupTable::Pointer lookupTable = lookupTableProperty->GetValue(); if (!lookupTable) return; lookupTable->SetType(activatedItem); lookupTableProperty->SetValue(lookupTable); mitk::RenderingModeProperty::Pointer renderingMode = dynamic_cast(node->GetProperty("Image Rendering.Mode")); renderingMode->SetValue(mitk::RenderingModeProperty::LOOKUPTABLE_LEVELWINDOW_COLOR); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkDataManagerView::ColormapMenuAboutToShow() { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); if(!node) return; mitk::LookupTableProperty::Pointer lookupTableProperty = dynamic_cast(node->GetProperty("LookupTable")); if (!lookupTableProperty) { mitk::LookupTable::Pointer mitkLut = mitk::LookupTable::New(); lookupTableProperty = mitk::LookupTableProperty::New(); lookupTableProperty->SetLookupTable(mitkLut); node->SetProperty("LookupTable", lookupTableProperty); } mitk::LookupTable::Pointer lookupTable = lookupTableProperty->GetValue(); if (!lookupTable) return; m_ColormapAction->menu()->clear(); QAction* tmp; int i = 0; std::string lutType = lookupTable->typenameList[i]; while (lutType != "END_OF_ARRAY") { tmp = m_ColormapAction->menu()->addAction(QString::fromStdString(lutType)); tmp->setCheckable(true); if (lutType == lookupTable->GetActiveTypeAsString()) { tmp->setChecked(true); } QObject::connect(tmp, SIGNAL(triggered(bool)), this, SLOT(ColormapActionToggled(bool))); lutType = lookupTable->typenameList[++i]; } } void QmitkDataManagerView::SurfaceRepresentationMenuAboutToShow() { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); if(!node) return; mitk::EnumerationProperty* representationProp = dynamic_cast (node->GetProperty("material.representation")); if(!representationProp) return; // clear menu m_SurfaceRepresentation->menu()->clear(); QAction* tmp; // create menu entries for(mitk::EnumerationProperty::EnumConstIterator it=representationProp->Begin(); it!=representationProp->End() ; it++) { tmp = m_SurfaceRepresentation->menu()->addAction(QString::fromStdString(it->second)); tmp->setCheckable(true); if(it->second == representationProp->GetValueAsString()) { tmp->setChecked(true); } QObject::connect( tmp, SIGNAL( triggered(bool) ) , this, SLOT( SurfaceRepresentationActionToggled(bool) ) ); } } void QmitkDataManagerView::SurfaceRepresentationActionToggled( bool /*checked*/ ) { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); if(!node) return; mitk::EnumerationProperty* representationProp = dynamic_cast (node->GetProperty("material.representation")); if(!representationProp) return; QAction* senderAction = qobject_cast ( QObject::sender() ); if(!senderAction) return; std::string activatedItem = senderAction->text().toStdString(); if ( activatedItem != representationProp->GetValueAsString() ) { if ( representationProp->IsValidEnumerationValue( activatedItem ) ) { representationProp->SetValue( activatedItem ); representationProp->InvokeEvent( itk::ModifiedEvent() ); representationProp->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } } void QmitkDataManagerView::ReinitSelectedNodes( bool ) { mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart(); if (renderWindow == nullptr) renderWindow = this->OpenRenderWindowPart(false); QList selectedNodes = this->GetCurrentSelection(); foreach(mitk::DataNode::Pointer node, selectedNodes) { mitk::BaseData::Pointer basedata = node->GetData(); if ( basedata.IsNotNull() && basedata->GetTimeGeometry()->IsValid() ) { renderWindow->GetRenderingManager()->InitializeViews( basedata->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); } } } void QmitkDataManagerView::RemoveSelectedNodes( bool ) { QModelIndexList indexesOfSelectedRowsFiltered = m_NodeTreeView->selectionModel()->selectedRows(); QModelIndexList indexesOfSelectedRows; for (int i = 0; i < indexesOfSelectedRowsFiltered.size(); ++i) { indexesOfSelectedRows.push_back(m_FilterModel->mapToSource(indexesOfSelectedRowsFiltered[i])); } if(indexesOfSelectedRows.size() < 1) { return; } std::vector selectedNodes; mitk::DataNode::Pointer node = 0; QString question = tr("Do you really want to remove "); for (QModelIndexList::iterator it = indexesOfSelectedRows.begin() ; it != indexesOfSelectedRows.end(); it++) { node = m_NodeTreeModel->GetNode(*it); // if node is not defined or if the node contains geometry data do not remove it if ( node.IsNotNull() /*& strcmp(node->GetData()->GetNameOfClass(), "PlaneGeometryData") != 0*/ ) { selectedNodes.push_back(node); question.append(QString::fromStdString(node->GetName())); question.append(", "); } } // remove the last two characters = ", " question = question.remove(question.size()-2, 2); question.append(tr(" from data storage?")); QMessageBox::StandardButton answerButton = QMessageBox::question( m_Parent , tr("DataManager") , question , QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); if(answerButton == QMessageBox::Yes) { for (std::vector::iterator it = selectedNodes.begin() ; it != selectedNodes.end(); it++) { node = *it; this->GetDataStorage()->Remove(node); if (m_GlobalReinitOnNodeDelete) this->GlobalReinit(false); } } } void QmitkDataManagerView::MakeAllNodesInvisible( bool ) { QList nodes = m_NodeTreeModel->GetNodeSet(); foreach(mitk::DataNode::Pointer node, nodes) { node->SetVisibility(false); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkDataManagerView::ShowOnlySelectedNodes( bool ) { QList selectedNodes = this->GetCurrentSelection(); QList allNodes = m_NodeTreeModel->GetNodeSet(); foreach(mitk::DataNode::Pointer node, allNodes) { node->SetVisibility(selectedNodes.contains(node)); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkDataManagerView::ToggleVisibilityOfSelectedNodes( bool ) { QList selectedNodes = this->GetCurrentSelection(); bool isVisible = false; foreach(mitk::DataNode::Pointer node, selectedNodes) { isVisible = false; node->GetBoolProperty("visible", isVisible); node->SetVisibility(!isVisible); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkDataManagerView::ShowInfoDialogForSelectedNodes( bool ) { QList selectedNodes = this->GetCurrentSelection(); QmitkInfoDialog _QmitkInfoDialog(selectedNodes, this->m_Parent); _QmitkInfoDialog.exec(); } void QmitkDataManagerView::NodeChanged(const mitk::DataNode* /*node*/) { // m_FilterModel->invalidate(); // fix as proposed by R. Khlebnikov in the mitk-users mail from 02.09.2014 QMetaObject::invokeMethod( m_FilterModel, "invalidate", Qt::QueuedConnection ); } QItemSelectionModel *QmitkDataManagerView::GetDataNodeSelectionModel() const { return m_NodeTreeView->selectionModel(); } void QmitkDataManagerView::GlobalReinit( bool ) { mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart(); if (renderWindow == nullptr) renderWindow = this->OpenRenderWindowPart(false); // no render window available if (renderWindow == nullptr) return; mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(this->GetDataStorage()); } void QmitkDataManagerView::NodeTreeViewRowsRemoved ( const QModelIndex & /*parent*/, int /*start*/, int /*end*/ ) { m_CurrentRowCount = m_NodeTreeModel->rowCount(); } void QmitkDataManagerView::NodeTreeViewRowsInserted( const QModelIndex & parent, int, int ) { QModelIndex viewIndex = m_FilterModel->mapFromSource(parent); m_NodeTreeView->setExpanded(viewIndex, true); // a new row was inserted if( m_CurrentRowCount == 0 && m_NodeTreeModel->rowCount() == 1 ) { this->OpenRenderWindowPart(); m_CurrentRowCount = m_NodeTreeModel->rowCount(); } } void QmitkDataManagerView::NodeSelectionChanged( const QItemSelection & /*selected*/, const QItemSelection & /*deselected*/ ) { QList nodes = m_NodeTreeModel->GetNodeSet(); foreach(mitk::DataNode::Pointer node, nodes) { if ( node.IsNotNull() ) node->SetBoolProperty("selected", false); } nodes.clear(); nodes = this->GetCurrentSelection(); foreach(mitk::DataNode::Pointer node, nodes) { if ( node.IsNotNull() ) node->SetBoolProperty("selected", true); } //changing the selection does NOT require any rendering processes! //mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkDataManagerView::ShowIn(const QString &editorId) { berry::IWorkbenchPage::Pointer page = this->GetSite()->GetPage(); berry::IEditorInput::Pointer input(new mitk::DataStorageEditorInput(this->GetDataStorageReference())); page->OpenEditor(input, editorId, false, berry::IWorkbenchPage::MATCH_ID); } mitk::IRenderWindowPart* QmitkDataManagerView::OpenRenderWindowPart(bool activatedEditor) { if (activatedEditor) { return this->GetRenderWindowPart(QmitkAbstractView::ACTIVATE | QmitkAbstractView::OPEN); } else { return this->GetRenderWindowPart(QmitkAbstractView::BRING_TO_FRONT | QmitkAbstractView::OPEN); } } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesView.cpp index a5dba4efe5..d82d42da44 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesView.cpp @@ -1,1403 +1,1403 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. 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 "QmitkControlVisualizationPropertiesView.h" #include "mitkNodePredicateDataType.h" #include "mitkDataNodeObject.h" #include "mitkOdfNormalizationMethodProperty.h" #include "mitkOdfScaleByProperty.h" #include "mitkResliceMethodProperty.h" #include "mitkRenderingManager.h" #include "mitkTbssImage.h" #include "mitkPlanarFigure.h" #include "mitkFiberBundle.h" #include "QmitkDataStorageComboBox.h" #include "mitkPlanarFigureInteractor.h" #include #include #include #include #include #include "usModuleRegistry.h" #include #include #include "mitkPlaneGeometry.h" #include #include #include #include "berryIWorkbenchWindow.h" #include "berryIWorkbenchPage.h" #include "berryISelectionService.h" #include "berryConstants.h" #include "berryPlatformUI.h" #include "itkRGBAPixel.h" #include #include "qwidgetaction.h" #include "qcolordialog.h" #include #include #include #define ROUND(a) ((a)>0 ? (int)((a)+0.5) : -(int)(0.5-(a))) const std::string QmitkControlVisualizationPropertiesView::VIEW_ID = "org.mitk.views.controlvisualizationpropertiesview"; using namespace berry; QmitkControlVisualizationPropertiesView::QmitkControlVisualizationPropertiesView() : QmitkAbstractView(), m_Controls(nullptr), m_CurrentSelection(0), m_IconTexOFF(new QIcon(":/QmitkDiffusionImaging/texIntOFFIcon.png")), m_IconTexON(new QIcon(":/QmitkDiffusionImaging/texIntONIcon.png")), m_IconGlyOFF_T(new QIcon(":/QmitkDiffusionImaging/glyphsoff_T.png")), m_IconGlyON_T(new QIcon(":/QmitkDiffusionImaging/glyphson_T.png")), m_IconGlyOFF_C(new QIcon(":/QmitkDiffusionImaging/glyphsoff_C.png")), m_IconGlyON_C(new QIcon(":/QmitkDiffusionImaging/glyphson_C.png")), m_IconGlyOFF_S(new QIcon(":/QmitkDiffusionImaging/glyphsoff_S.png")), m_IconGlyON_S(new QIcon(":/QmitkDiffusionImaging/glyphson_S.png")), m_GlyIsOn_T(false), m_GlyIsOn_C(false), m_GlyIsOn_S(false), m_CurrentPickingNode(0), - m_FiberBundleObserverTag(0), - m_FiberBundleObserveOpacityTag(0) + m_ColorPropertyObserverTag(0), + m_OpacityPropertyObserverTag(0) { currentThickSlicesMode = 1; m_MyMenu = nullptr; int numThread = itk::MultiThreader::GetGlobalMaximumNumberOfThreads(); if (numThread > 12) numThread = 12; itk::MultiThreader::SetGlobalDefaultNumberOfThreads(numThread); } QmitkControlVisualizationPropertiesView::~QmitkControlVisualizationPropertiesView() { mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart(); if (renderWindow) { mitk::SliceNavigationController* slicer = renderWindow->GetQmitkRenderWindow(QString("axial"))->GetSliceNavigationController(); slicer->RemoveObserver(m_SliceObserverTag1); slicer = renderWindow->GetQmitkRenderWindow(QString("sagittal"))->GetSliceNavigationController(); slicer->RemoveObserver(m_SliceObserverTag2); slicer = renderWindow->GetQmitkRenderWindow(QString("coronal"))->GetSliceNavigationController(); slicer->RemoveObserver(m_SliceObserverTag3); } this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->RemovePostSelectionListener(/*"org.mitk.views.datamanager",*/ m_SelListener.data()); } void QmitkControlVisualizationPropertiesView::OnThickSlicesModeSelected( QAction* action ) { currentThickSlicesMode = action->data().toInt(); switch( currentThickSlicesMode ) { case 0: // toInt() returns 0 'otherwise'. return; // dummy code/todo: implement stuff. case 1: this->m_Controls->m_TSMenu->setText("MIP"); break; case 2: this->m_Controls->m_TSMenu->setText("SUM"); break; case 3: this->m_Controls->m_TSMenu->setText("WEIGH"); break; default: return; // dummy code/todo: implement stuff. } if (auto renderWindowPart = this->GetRenderWindowPart(OPEN)) { /// TODO There is no way to access the individual crosshair planes through the render window part API. /// There could be a new 'mitk::DataNode* mitk::ILinkedRenderWindowPart::GetSlicingPlane(const std::string& name) const' /// function for this purpose. For the time being, I comment out the lines below, but they are valid /// and they have to be re-enabled after the crosshair planes can be accessed again. // mitk::DataNode* n; // n = renderWindowPart->GetSlicingPlane("axial"); // if (n) { n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( currentThickSlicesMode ) ); } // n = renderWindowPart->GetSlicingPlane("sagittal"); // if (n) { n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( currentThickSlicesMode ) ); } // n = renderWindowPart->GetSlicingPlane("coronal"); // if (n) { n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( currentThickSlicesMode ) ); } mitk::BaseRenderer::Pointer renderer; renderer = renderWindowPart->GetQmitkRenderWindow("axial")->GetRenderer(); if (renderer.IsNotNull()) { renderer->SendUpdateSlice(); } renderer = renderWindowPart->GetQmitkRenderWindow("sagittal")->GetRenderer(); if (renderer.IsNotNull()) { renderer->SendUpdateSlice(); } renderer = renderWindowPart->GetQmitkRenderWindow("coronal")->GetRenderer(); if (renderer.IsNotNull()) { renderer->SendUpdateSlice(); } renderer->GetRenderingManager()->RequestUpdateAll(); } } void QmitkControlVisualizationPropertiesView::OnTSNumChanged( int num ) { if (auto renderWindowPart = this->GetRenderWindowPart(OPEN)) { /// TODO There is no way to access the individual crosshair planes through the render window part API. /// There could be a new 'mitk::DataNode* mitk::ILinkedRenderWindowPart::GetSlicingPlane(const std::string& name) const' /// function for this purpose. For the time being, I comment out the lines below, but they are valid /// and they have to be re-enabled after the crosshair planes can be accessed again. // if(num==0) // { // mitk::DataNode* n; // n = renderWindowPart->GetSlicingPlane("axial"); // if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( 0 ) ); // if(n) n->SetProperty( "reslice.thickslices.num", mitk::IntProperty::New( num ) ); // if(n) n->SetProperty( "reslice.thickslices.showarea", mitk::BoolProperty::New( false ) ); // // n = renderWindowPart->GetSlicingPlane("sagittal"); // if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( 0 ) ); // if(n) n->SetProperty( "reslice.thickslices.num", mitk::IntProperty::New( num ) ); // if(n) n->SetProperty( "reslice.thickslices.showarea", mitk::BoolProperty::New( false ) ); // // n = renderWindowPart->GetSlicingPlane("coronal"); // if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( 0 ) ); // if(n) n->SetProperty( "reslice.thickslices.num", mitk::IntProperty::New( num ) ); // if(n) n->SetProperty( "reslice.thickslices.showarea", mitk::BoolProperty::New( false ) ); // } // else // { // mitk::DataNode* n; // n = renderWindowPart->GetSlicingPlane("axial"); // if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( currentThickSlicesMode ) ); // if(n) n->SetProperty( "reslice.thickslices.num", mitk::IntProperty::New( num ) ); // if(n) n->SetProperty( "reslice.thickslices.showarea", mitk::BoolProperty::New( (num>0) ) ); // // n = renderWindowPart->GetSlicingPlane("sagittal"); // if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( currentThickSlicesMode ) ); // if(n) n->SetProperty( "reslice.thickslices.num", mitk::IntProperty::New( num ) ); // if(n) n->SetProperty( "reslice.thickslices.showarea", mitk::BoolProperty::New( (num>0) ) ); // // n = renderWindowPart->GetSlicingPlane("coronal"); // if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( currentThickSlicesMode ) ); // if(n) n->SetProperty( "reslice.thickslices.num", mitk::IntProperty::New( num ) ); // if(n) n->SetProperty( "reslice.thickslices.showarea", mitk::BoolProperty::New( (num>0) ) ); // } m_TSLabel->setText(QString::number( num*2 + 1 )); mitk::BaseRenderer::Pointer renderer; renderer = renderWindowPart->GetQmitkRenderWindow("axial")->GetRenderer(); if(renderer.IsNotNull()) { renderer->SendUpdateSlice(); } renderer = nullptr; renderer = renderWindowPart->GetQmitkRenderWindow("sagittal")->GetRenderer(); if(renderer.IsNotNull()) { renderer->SendUpdateSlice(); } renderer = nullptr; renderer = renderWindowPart->GetQmitkRenderWindow("coronal")->GetRenderer(); if(renderer.IsNotNull()) { renderer->SendUpdateSlice(); } renderer->GetRenderingManager()->RequestUpdateAll(mitk::RenderingManager::REQUEST_UPDATE_2DWINDOWS); } } void QmitkControlVisualizationPropertiesView::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkControlVisualizationPropertiesViewControls; m_Controls->setupUi(parent); this->CreateConnections(); // hide warning (ODFs in rotated planes) m_Controls->m_lblRotatedPlanesWarning->hide(); m_MyMenu = new QMenu(parent); m_Controls->m_TSMenu->setMenu( m_MyMenu ); QIcon iconFiberFade(":/QmitkDiffusionImaging/MapperEfx2D.png"); m_Controls->m_FiberFading2D->setIcon(iconFiberFade); #ifndef DIFFUSION_IMAGING_EXTENDED int size = m_Controls->m_AdditionalScaling->count(); for(int t=0; tm_AdditionalScaling->itemText(t).toStdString() == "Scale by ASR") { m_Controls->m_AdditionalScaling->removeItem(t); } } #endif m_Controls->m_ScalingFrame->setVisible(false); m_Controls->m_NormalizationFrame->setVisible(false); m_Controls->m_Crosshair->setVisible(false); mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart(); if (renderWindow) { { mitk::SliceNavigationController* slicer = renderWindow->GetQmitkRenderWindow(QString("axial"))->GetSliceNavigationController(); itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction( this, &QmitkControlVisualizationPropertiesView::OnAxialChanged ); m_SliceObserverTag1 = slicer->AddObserver( mitk::SliceNavigationController::GeometrySliceEvent(nullptr, 0), command ); } { mitk::SliceNavigationController* slicer = renderWindow->GetQmitkRenderWindow(QString("sagittal"))->GetSliceNavigationController(); itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction( this, &QmitkControlVisualizationPropertiesView::OnSagittalChanged ); m_SliceObserverTag2 = slicer->AddObserver( mitk::SliceNavigationController::GeometrySliceEvent(nullptr, 0), command ); } { mitk::SliceNavigationController* slicer = renderWindow->GetQmitkRenderWindow(QString("coronal"))->GetSliceNavigationController(); itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction( this, &QmitkControlVisualizationPropertiesView::OnCoronalChanged ); m_SliceObserverTag3 = slicer->AddObserver( mitk::SliceNavigationController::GeometrySliceEvent(nullptr, 0), command ); } } } } void QmitkControlVisualizationPropertiesView::SetFocus() { m_Controls->m_TSMenu->setFocus(); } void QmitkControlVisualizationPropertiesView::SliceRotation(const itk::EventObject&) { // test if plane rotated if( m_GlyIsOn_T || m_GlyIsOn_C || m_GlyIsOn_S ) { if( this->IsPlaneRotated() ) { // show label m_Controls->m_lblRotatedPlanesWarning->show(); } else { //hide label m_Controls->m_lblRotatedPlanesWarning->hide(); } } } void QmitkControlVisualizationPropertiesView::NodeRemoved(const mitk::DataNode* /*node*/) { } #include void QmitkControlVisualizationPropertiesView::CreateConnections() { if ( m_Controls ) { connect( (QObject*)(m_Controls->m_VisibleOdfsON_T), SIGNAL(clicked()), this, SLOT(VisibleOdfsON_T()) ); connect( (QObject*)(m_Controls->m_VisibleOdfsON_S), SIGNAL(clicked()), this, SLOT(VisibleOdfsON_S()) ); connect( (QObject*)(m_Controls->m_VisibleOdfsON_C), SIGNAL(clicked()), this, SLOT(VisibleOdfsON_C()) ); connect( (QObject*)(m_Controls->m_ShowMaxNumber), SIGNAL(editingFinished()), this, SLOT(ShowMaxNumberChanged()) ); connect( (QObject*)(m_Controls->m_NormalizationDropdown), SIGNAL(currentIndexChanged(int)), this, SLOT(NormalizationDropdownChanged(int)) ); connect( (QObject*)(m_Controls->m_ScalingFactor), SIGNAL(valueChanged(double)), this, SLOT(ScalingFactorChanged(double)) ); connect( (QObject*)(m_Controls->m_AdditionalScaling), SIGNAL(currentIndexChanged(int)), this, SLOT(AdditionalScaling(int)) ); connect( (QObject*)(m_Controls->m_ScalingCheckbox), SIGNAL(clicked()), this, SLOT(ScalingCheckbox()) ); - connect((QObject*) m_Controls->m_ResetColoring, SIGNAL(clicked()), (QObject*) this, SLOT(BundleRepresentationResetColoring())); + connect((QObject*) m_Controls->m_ResetColoring, SIGNAL(clicked()), (QObject*) this, SLOT(ResetColoring())); + connect((QObject*) m_Controls->m_ResetColoring2, SIGNAL(clicked()), (QObject*) this, SLOT(ResetColoring())); connect((QObject*) m_Controls->m_FiberFading2D, SIGNAL(clicked()), (QObject*) this, SLOT( Fiber2DfadingEFX() ) ); connect((QObject*) m_Controls->m_FiberThicknessSlider, SIGNAL(sliderReleased()), (QObject*) this, SLOT( FiberSlicingThickness2D() ) ); connect((QObject*) m_Controls->m_FiberThicknessSlider, SIGNAL(valueChanged(int)), (QObject*) this, SLOT( FiberSlicingUpdateLabel(int) )); connect((QObject*) m_Controls->m_Crosshair, SIGNAL(clicked()), (QObject*) this, SLOT(SetInteractor())); connect((QObject*) m_Controls->m_LineWidth, SIGNAL(editingFinished()), (QObject*) this, SLOT(LineWidthChanged())); connect((QObject*) m_Controls->m_TubeWidth, SIGNAL(editingFinished()), (QObject*) this, SLOT(TubeRadiusChanged())); connect( (QObject*) m_Controls->m_EllipsoidViewRadioButton, SIGNAL(toggled(bool)), (QObject*) this, SLOT(OnTensorViewChanged() ) ); connect( (QObject*) m_Controls->m_colouriseRainbowRadioButton, SIGNAL(toggled(bool)), (QObject*) this, SLOT(OnColourisationModeChanged() ) ); connect( (QObject*) m_Controls->m_randomModeRadioButton, SIGNAL(toggled(bool)), (QObject*) this, SLOT(OnRandomModeChanged() ) ); connect((QObject*) m_Controls->m_Clip0, SIGNAL(toggled(bool)), (QObject*) this, SLOT(Toggle3DClipping(bool))); connect((QObject*) m_Controls->m_Clip1, SIGNAL(toggled(bool)), (QObject*) this, SLOT(Toggle3DClipping(bool))); connect((QObject*) m_Controls->m_Clip2, SIGNAL(toggled(bool)), (QObject*) this, SLOT(Toggle3DClipping(bool))); connect((QObject*) m_Controls->m_Clip3, SIGNAL(toggled(bool)), (QObject*) this, SLOT(Toggle3DClipping(bool))); connect((QObject*) m_Controls->m_FlipClipBox, SIGNAL(stateChanged(int)), (QObject*) this, SLOT(Toggle3DClipping())); connect((QObject*) m_Controls->m_FlipPeaksButton, SIGNAL(clicked()), (QObject*) this, SLOT(FlipPeaks())); } } // set diffusion image channel to b0 volume void QmitkControlVisualizationPropertiesView::NodeAdded(const mitk::DataNode *node) { mitk::DataNode* notConst = const_cast(node); bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( dynamic_cast(node->GetData())) ); if (isDiffusionImage) { mitk::Image::Pointer dimg = dynamic_cast(notConst->GetData()); // if there is no b0 image in the dataset, the GetB0Indices() returns a vector of size 0 // and hence we cannot set the Property directly to .front() int displayChannelPropertyValue = 0; mitk::BValueMapProperty* bmapproperty = static_cast (dimg->GetProperty(mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str()).GetPointer() ); mitk::DiffusionPropertyHelper::BValueMapType map = bmapproperty->GetBValueMap(); if( map[0].size() > 0) { displayChannelPropertyValue = map[0].front(); } notConst->SetIntProperty("DisplayChannel", displayChannelPropertyValue ); } } /* OnSelectionChanged is registered to SelectionService, therefore no need to implement SelectionService Listener explicitly */ void QmitkControlVisualizationPropertiesView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*part*/, const QList& nodes) { m_Controls->m_BundleControlsFrame->setVisible(false); m_Controls->m_ImageControlsFrame->setVisible(false); m_Controls->m_PeakImageFrame->setVisible(false); if (nodes.size()>1) // only do stuff if one node is selected return; m_Controls->m_NumberGlyphsFrame->setVisible(false); m_Controls->m_GlyphFrame->setVisible(false); m_Controls->m_TSMenu->setVisible(false); m_SelectedNode = nullptr; int numOdfImages = 0; for (mitk::DataNode::Pointer node: nodes) { if(node.IsNull()) continue; mitk::BaseData* nodeData = node->GetData(); if(nodeData == nullptr) continue; m_SelectedNode = node; - if (dynamic_cast(nodeData)) + if (dynamic_cast(nodeData)) + { + m_Controls->m_PeakImageFrame->setVisible(true); + + if (m_Color.IsNotNull()) + m_Color->RemoveObserver(m_ColorPropertyObserverTag); + + itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); + command->SetCallbackFunction( this, &QmitkControlVisualizationPropertiesView::SetCustomColor ); + m_Color = dynamic_cast(node->GetProperty("color", nullptr)); + if (m_Color.IsNotNull()) + m_ColorPropertyObserverTag = m_Color->AddObserver( itk::ModifiedEvent(), command ); + } + else if (dynamic_cast(nodeData)) { int Fiber3DClippingPlaneId = -1; m_SelectedNode->GetPropertyValue("Fiber3DClippingPlaneId",Fiber3DClippingPlaneId); switch(Fiber3DClippingPlaneId) { case 0: m_Controls->m_Clip0->setChecked(1); break; case 1: m_Controls->m_Clip1->setChecked(1); break; case 2: m_Controls->m_Clip2->setChecked(1); break; case 3: m_Controls->m_Clip3->setChecked(1); break; default : m_Controls->m_Clip0->setChecked(1); } - // handle fiber bundle property observers - if (m_Color.IsNotNull()) { m_Color->RemoveObserver(m_FiberBundleObserverTag); } + // handle fiber property observers + if (m_Color.IsNotNull()) + m_Color->RemoveObserver(m_ColorPropertyObserverTag); itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); - command->SetCallbackFunction( this, &QmitkControlVisualizationPropertiesView::SetFiberBundleCustomColor ); + command->SetCallbackFunction( this, &QmitkControlVisualizationPropertiesView::SetCustomColor ); m_Color = dynamic_cast(node->GetProperty("color", nullptr)); if (m_Color.IsNotNull()) - m_FiberBundleObserverTag = m_Color->AddObserver( itk::ModifiedEvent(), command ); - - if (m_Opacity.IsNotNull()) - { - m_Opacity->RemoveObserver(m_FiberBundleObserveOpacityTag); - } - itk::ReceptorMemberCommand::Pointer command2 - = itk::ReceptorMemberCommand::New(); - command2->SetCallbackFunction( this, &QmitkControlVisualizationPropertiesView::SetFiberBundleOpacity ); - m_Opacity = dynamic_cast(node->GetProperty("opacity", nullptr)); + m_ColorPropertyObserverTag = m_Color->AddObserver( itk::ModifiedEvent(), command ); - if (m_Opacity.IsNotNull()) - { - m_FiberBundleObserveOpacityTag = m_Opacity->AddObserver( itk::ModifiedEvent(), command2 ); - } m_Controls->m_BundleControlsFrame->setVisible(true); if(m_CurrentPickingNode != 0 && node.GetPointer() != m_CurrentPickingNode) { m_Controls->m_Crosshair->setEnabled(false); } else { m_Controls->m_Crosshair->setEnabled(true); } int width; node->GetIntProperty("shape.linewidth", width); m_Controls->m_LineWidth->setValue(width); float radius; node->GetFloatProperty("shape.tuberadius", radius); m_Controls->m_TubeWidth->setValue(radius); float range; node->GetFloatProperty("Fiber2DSliceThickness",range); mitk::FiberBundle::Pointer fib = dynamic_cast(node->GetData()); mitk::BaseGeometry::Pointer geo = fib->GetGeometry(); mitk::ScalarType max = geo->GetExtentInMM(0); max = std::max(max, geo->GetExtentInMM(1)); max = std::max(max, geo->GetExtentInMM(2)); m_Controls->m_FiberThicknessSlider->setMaximum(max * 10); m_Controls->m_FiberThicknessSlider->setValue(range * 10); } else if(dynamic_cast(nodeData) || dynamic_cast(nodeData)) { m_Controls->m_ImageControlsFrame->setVisible(true); m_Controls->m_NumberGlyphsFrame->setVisible(true); m_Controls->m_GlyphFrame->setVisible(true); m_Controls->m_NormalizationFrame->setVisible(true); if(m_NodeUsedForOdfVisualization.IsNotNull()) { m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_S", false); m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_C", false); m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_T", false); } m_NodeUsedForOdfVisualization = node; m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_S", m_GlyIsOn_S); m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_C", m_GlyIsOn_C); m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_T", m_GlyIsOn_T); int val; node->GetIntProperty("ShowMaxNumber", val); m_Controls->m_ShowMaxNumber->setValue(val); m_Controls->m_NormalizationDropdown ->setCurrentIndex(dynamic_cast(node->GetProperty("Normalization")) ->GetValueAsId()); float fval; node->GetFloatProperty("Scaling",fval); m_Controls->m_ScalingFactor->setValue(fval); m_Controls->m_AdditionalScaling ->setCurrentIndex(dynamic_cast(node->GetProperty("ScaleBy"))->GetValueAsId()); bool switchTensorViewValue = false; node->GetBoolProperty( "DiffusionCore.Rendering.OdfVtkMapper.SwitchTensorView", switchTensorViewValue ); if( dynamic_cast(nodeData) ) { m_Controls-> m_EllipsoidViewRadioButton-> setEnabled( true ); m_Controls-> m_EllipsoidViewRadioButton-> setChecked( switchTensorViewValue ); } else { m_Controls-> m_EllipsoidViewRadioButton-> setEnabled( false ); m_Controls-> m_EllipsoidViewRadioButton-> setChecked( false ); } bool colourisationModeBit = false; node-> GetBoolProperty( "DiffusionCore.Rendering.OdfVtkMapper.ColourisationModeBit", colourisationModeBit ); m_Controls-> m_colouriseSimpleRadioButton-> setChecked( colourisationModeBit ); bool randomModeBit = false; node-> GetBoolProperty( "DiffusionCore.Rendering.OdfVtkMapper.RandomModeBit", randomModeBit ); m_Controls-> m_randomModeRadioButton-> setChecked( randomModeBit ); numOdfImages++; } else if(dynamic_cast(nodeData)) { PlanarFigureFocus(); } - else if(dynamic_cast(nodeData)) - { - m_Controls->m_PeakImageFrame->setVisible(true); - } else if( dynamic_cast(nodeData) ) { m_Controls->m_ImageControlsFrame->setVisible(true); m_Controls->m_TSMenu->setVisible(true); } } if( nodes.empty() ) { return; } mitk::DataNode::Pointer node = nodes.at(0); if( node.IsNull() ) { return; } QMenu *myMenu = m_MyMenu; myMenu->clear(); QActionGroup* thickSlicesActionGroup = new QActionGroup(myMenu); thickSlicesActionGroup->setExclusive(true); int currentTSMode = 0; { mitk::ResliceMethodProperty::Pointer m = dynamic_cast(node->GetProperty( "reslice.thickslices" )); if( m.IsNotNull() ) currentTSMode = m->GetValueAsId(); } int maxTS = 30; for (auto node: nodes) { mitk::Image* image = dynamic_cast(node->GetData()); if (image) { int size = std::max(image->GetDimension(0), std::max(image->GetDimension(1), image->GetDimension(2))); if (size>maxTS) { maxTS=size; } } } maxTS /= 2; int currentNum = 0; { mitk::IntProperty::Pointer m = dynamic_cast(node->GetProperty( "reslice.thickslices.num" )); if( m.IsNotNull() ) { currentNum = m->GetValue(); if(currentNum < 0) { currentNum = 0; } if(currentNum > maxTS) { currentNum = maxTS; } } } if(currentTSMode==0) { currentNum=0; } QSlider *m_TSSlider = new QSlider(myMenu); m_TSSlider->setMinimum(0); m_TSSlider->setMaximum(maxTS-1); m_TSSlider->setValue(currentNum); m_TSSlider->setOrientation(Qt::Horizontal); connect( m_TSSlider, SIGNAL( valueChanged(int) ), this, SLOT( OnTSNumChanged(int) ) ); QHBoxLayout* _TSLayout = new QHBoxLayout; _TSLayout->setContentsMargins(4,4,4,4); _TSLayout->addWidget(m_TSSlider); _TSLayout->addWidget(m_TSLabel=new QLabel(QString::number(currentNum*2+1),myMenu)); QWidget* _TSWidget = new QWidget; _TSWidget->setLayout(_TSLayout); QActionGroup* thickSliceModeActionGroup = new QActionGroup(myMenu); thickSliceModeActionGroup->setExclusive(true); QWidgetAction *m_TSSliderAction = new QWidgetAction(myMenu); m_TSSliderAction->setDefaultWidget(_TSWidget); myMenu->addAction(m_TSSliderAction); QAction* mipThickSlicesAction = new QAction(myMenu); mipThickSlicesAction->setActionGroup(thickSliceModeActionGroup); mipThickSlicesAction->setText("MIP (max. intensity proj.)"); mipThickSlicesAction->setCheckable(true); mipThickSlicesAction->setChecked(currentThickSlicesMode==1); mipThickSlicesAction->setData(1); myMenu->addAction( mipThickSlicesAction ); QAction* sumThickSlicesAction = new QAction(myMenu); sumThickSlicesAction->setActionGroup(thickSliceModeActionGroup); sumThickSlicesAction->setText("SUM (sum intensity proj.)"); sumThickSlicesAction->setCheckable(true); sumThickSlicesAction->setChecked(currentThickSlicesMode==2); sumThickSlicesAction->setData(2); myMenu->addAction( sumThickSlicesAction ); QAction* weightedThickSlicesAction = new QAction(myMenu); weightedThickSlicesAction->setActionGroup(thickSliceModeActionGroup); weightedThickSlicesAction->setText("WEIGHTED (gaussian proj.)"); weightedThickSlicesAction->setCheckable(true); weightedThickSlicesAction->setChecked(currentThickSlicesMode==3); weightedThickSlicesAction->setData(3); myMenu->addAction( weightedThickSlicesAction ); connect( thickSliceModeActionGroup, SIGNAL(triggered(QAction*)), this, SLOT(OnThickSlicesModeSelected(QAction*)) ); } void QmitkControlVisualizationPropertiesView::VisibleOdfsON_S() { m_GlyIsOn_S = m_Controls->m_VisibleOdfsON_S->isChecked(); if (m_NodeUsedForOdfVisualization.IsNull()) { MITK_WARN << "ODF visualization activated but m_NodeUsedForOdfVisualization is nullptr"; return; } m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_S", m_GlyIsOn_S); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkControlVisualizationPropertiesView::Visible() { } void QmitkControlVisualizationPropertiesView::Hidden() { } void QmitkControlVisualizationPropertiesView::Activated() { } void QmitkControlVisualizationPropertiesView::Deactivated() { } void QmitkControlVisualizationPropertiesView::FlipPeaks() { if (m_SelectedNode.IsNull() || dynamic_cast(m_SelectedNode->GetData())==nullptr) return; mitk::Image::Pointer image = dynamic_cast(m_SelectedNode->GetData()); typedef mitk::ImageToItk< mitk::PeakImage::ItkPeakImageType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(image); caster->Update(); mitk::PeakImage::ItkPeakImageType::Pointer itkImg = caster->GetOutput(); itk::FlipPeaksFilter< float >::Pointer flipper = itk::FlipPeaksFilter< float >::New(); flipper->SetInput(itkImg); flipper->SetFlipX(m_Controls->m_FlipPeaksX->isChecked()); flipper->SetFlipY(m_Controls->m_FlipPeaksY->isChecked()); flipper->SetFlipZ(m_Controls->m_FlipPeaksZ->isChecked()); flipper->Update(); mitk::Image::Pointer resultImage = dynamic_cast(mitk::PeakImage::New().GetPointer()); mitk::CastToMitkImage(flipper->GetOutput(), resultImage); resultImage->SetVolume(flipper->GetOutput()->GetBufferPointer()); m_SelectedNode->SetData(resultImage); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkControlVisualizationPropertiesView::Toggle3DClipping(bool enabled) { if (!enabled || m_SelectedNode.IsNull() || dynamic_cast(m_SelectedNode->GetData())==nullptr) return; m_SelectedNode->SetBoolProperty( "Fiber3DClippingPlaneFlip", m_Controls->m_FlipClipBox->isChecked() ); if (m_Controls->m_Clip0->isChecked()) { m_SelectedNode->SetIntProperty( "Fiber3DClippingPlaneId", 0 ); Set3DClippingPlane(true, m_SelectedNode, ""); } else if (m_Controls->m_Clip1->isChecked()) { m_SelectedNode->SetIntProperty( "Fiber3DClippingPlaneId", 1 ); Set3DClippingPlane(false, m_SelectedNode, "axial"); } else if (m_Controls->m_Clip2->isChecked()) { m_SelectedNode->SetIntProperty( "Fiber3DClippingPlaneId", 2 ); Set3DClippingPlane(false, m_SelectedNode, "sagittal"); } else if (m_Controls->m_Clip3->isChecked()) { m_SelectedNode->SetIntProperty( "Fiber3DClippingPlaneId", 3 ); Set3DClippingPlane(false, m_SelectedNode, "coronal"); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkControlVisualizationPropertiesView::OnAxialChanged(const itk::EventObject& ) { mitk::DataStorage::SetOfObjects::ConstPointer nodes = this->GetDataStorage()->GetAll(); for (unsigned int i=0; iSize(); ++i) { mitk::DataNode::Pointer node = nodes->GetElement(i); int plane_id = -1; node->GetIntProperty("Fiber3DClippingPlaneId", plane_id); if (plane_id==1) Set3DClippingPlane(false, node, "axial"); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkControlVisualizationPropertiesView::OnCoronalChanged(const itk::EventObject& ) { mitk::DataStorage::SetOfObjects::ConstPointer nodes = this->GetDataStorage()->GetAll(); for (unsigned int i=0; iSize(); ++i) { mitk::DataNode::Pointer node = nodes->GetElement(i); int plane_id = -1; node->GetIntProperty("Fiber3DClippingPlaneId", plane_id); if (plane_id==3) Set3DClippingPlane(false, node, "coronal"); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkControlVisualizationPropertiesView::OnSagittalChanged(const itk::EventObject& ) { mitk::DataStorage::SetOfObjects::ConstPointer nodes = this->GetDataStorage()->GetAll(); for (unsigned int i=0; iSize(); ++i) { mitk::DataNode::Pointer node = nodes->GetElement(i); int plane_id = -1; node->GetIntProperty("Fiber3DClippingPlaneId", plane_id); if (plane_id==2) Set3DClippingPlane(false, node, "sagittal"); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkControlVisualizationPropertiesView::Set3DClippingPlane(bool disable, mitk::DataNode* node, std::string plane) { mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart(); if (renderWindow && node && dynamic_cast(node->GetData())) { mitk::Vector3D planeNormal; planeNormal.Fill(0.0); if (!disable) { mitk::SliceNavigationController* slicer = renderWindow->GetQmitkRenderWindow(QString(plane.c_str()))->GetSliceNavigationController(); mitk::PlaneGeometry::ConstPointer planeGeo = slicer->GetCurrentPlaneGeometry(); //generate according cutting planes based on the view position planeNormal = planeGeo->GetNormal(); float tmp1 = planeGeo->GetOrigin()[0] * planeNormal[0]; float tmp2 = planeGeo->GetOrigin()[1] * planeNormal[1]; float tmp3 = planeGeo->GetOrigin()[2] * planeNormal[2]; float distance = tmp1 + tmp2 + tmp3; //attention, correct normalvector planeNormal *= distance; if (distance<0) node->SetBoolProperty( "Fiber3DClippingPlaneSecondFlip", true ); else node->SetBoolProperty( "Fiber3DClippingPlaneSecondFlip", false ); } node->SetProperty( "Fiber3DClippingPlane", mitk::Vector3DProperty::New( planeNormal ) ); dynamic_cast(node->GetData())->RequestUpdate(); } } void QmitkControlVisualizationPropertiesView::VisibleOdfsON_T() { m_GlyIsOn_T = m_Controls->m_VisibleOdfsON_T->isChecked(); if (m_NodeUsedForOdfVisualization.IsNull()) { MITK_WARN << "ODF visualization activated but m_NodeUsedForOdfVisualization is nullptr"; return; } m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_T", m_GlyIsOn_T); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkControlVisualizationPropertiesView::VisibleOdfsON_C() { m_GlyIsOn_C = m_Controls->m_VisibleOdfsON_C->isChecked(); if (m_NodeUsedForOdfVisualization.IsNull()) { MITK_WARN << "ODF visualization activated but m_NodeUsedForOdfVisualization is nullptr"; return; } m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_C", m_GlyIsOn_C); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } bool QmitkControlVisualizationPropertiesView::IsPlaneRotated() { mitk::Image* currentImage = dynamic_cast( m_NodeUsedForOdfVisualization->GetData() ); if( currentImage == nullptr ) { MITK_ERROR << " Casting problems. Returning false"; return false; } mitk::Vector3D imageNormal0 = currentImage->GetSlicedGeometry()->GetAxisVector(0); mitk::Vector3D imageNormal1 = currentImage->GetSlicedGeometry()->GetAxisVector(1); mitk::Vector3D imageNormal2 = currentImage->GetSlicedGeometry()->GetAxisVector(2); imageNormal0.Normalize(); imageNormal1.Normalize(); imageNormal2.Normalize(); auto renderWindowPart = this->GetRenderWindowPart(); double eps = 0.000001; // for all 2D renderwindows of the render window part check alignment { mitk::PlaneGeometry::ConstPointer displayPlane = dynamic_cast ( renderWindowPart->GetQmitkRenderWindow("axial")->GetRenderer()->GetCurrentWorldPlaneGeometry() ); if (displayPlane.IsNull()) { return false; } mitk::Vector3D normal = displayPlane->GetNormal(); normal.Normalize(); int test = 0; if( fabs(fabs(dot_product(normal.GetVnlVector(),imageNormal0.GetVnlVector()))-1) > eps ) { test++; } if( fabs(fabs(dot_product(normal.GetVnlVector(),imageNormal1.GetVnlVector()))-1) > eps ) { test++; } if( fabs(fabs(dot_product(normal.GetVnlVector(),imageNormal2.GetVnlVector()))-1) > eps ) { test++; } if (test==3) { return true; } } { mitk::PlaneGeometry::ConstPointer displayPlane = dynamic_cast ( renderWindowPart->GetQmitkRenderWindow("sagittal")->GetRenderer()->GetCurrentWorldPlaneGeometry() ); if (displayPlane.IsNull()) { return false; } mitk::Vector3D normal = displayPlane->GetNormal(); normal.Normalize(); int test = 0; if( fabs(fabs(dot_product(normal.GetVnlVector(),imageNormal0.GetVnlVector()))-1) > eps ) { test++; } if( fabs(fabs(dot_product(normal.GetVnlVector(),imageNormal1.GetVnlVector()))-1) > eps ) { test++; } if( fabs(fabs(dot_product(normal.GetVnlVector(),imageNormal2.GetVnlVector()))-1) > eps ) { test++; } if (test==3) { return true; } } { mitk::PlaneGeometry::ConstPointer displayPlane = dynamic_cast ( renderWindowPart->GetQmitkRenderWindow("coronal")->GetRenderer()->GetCurrentWorldPlaneGeometry() ); if (displayPlane.IsNull()) { return false; } mitk::Vector3D normal = displayPlane->GetNormal(); normal.Normalize(); int test = 0; if( fabs(fabs(dot_product(normal.GetVnlVector(),imageNormal0.GetVnlVector()))-1) > eps ) { test++; } if( fabs(fabs(dot_product(normal.GetVnlVector(),imageNormal1.GetVnlVector()))-1) > eps ) { test++; } if( fabs(fabs(dot_product(normal.GetVnlVector(),imageNormal2.GetVnlVector()))-1) > eps ) { test++; } if (test==3) { return true; } } return false; } void QmitkControlVisualizationPropertiesView::ShowMaxNumberChanged() { int maxNr = m_Controls->m_ShowMaxNumber->value(); if ( maxNr < 1 ) { m_Controls->m_ShowMaxNumber->setValue( 1 ); maxNr = 1; } if ( dynamic_cast(m_SelectedNode->GetData()) || dynamic_cast(m_SelectedNode->GetData()) ) { m_SelectedNode->SetIntProperty("ShowMaxNumber", maxNr); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkControlVisualizationPropertiesView::NormalizationDropdownChanged(int normDropdown) { typedef mitk::OdfNormalizationMethodProperty PropType; PropType::Pointer normMeth = PropType::New(); switch(normDropdown) { case 0: normMeth->SetNormalizationToMinMax(); break; case 1: normMeth->SetNormalizationToMax(); break; case 2: normMeth->SetNormalizationToNone(); break; case 3: normMeth->SetNormalizationToGlobalMax(); break; default: normMeth->SetNormalizationToMinMax(); } if ( dynamic_cast(m_SelectedNode->GetData()) || dynamic_cast(m_SelectedNode->GetData()) ) { m_SelectedNode->SetProperty("Normalization", normMeth.GetPointer()); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkControlVisualizationPropertiesView::ScalingFactorChanged(double scalingFactor) { if ( dynamic_cast(m_SelectedNode->GetData()) || dynamic_cast(m_SelectedNode->GetData()) ) { m_SelectedNode->SetFloatProperty("Scaling", scalingFactor); } if (auto renderWindowPart = this->GetRenderWindowPart()) { renderWindowPart->RequestUpdate(); } } void QmitkControlVisualizationPropertiesView::AdditionalScaling(int additionalScaling) { typedef mitk::OdfScaleByProperty PropType; PropType::Pointer scaleBy = PropType::New(); switch(additionalScaling) { case 0: scaleBy->SetScaleByNothing(); break; case 1: scaleBy->SetScaleByGFA(); //m_Controls->params_frame->setVisible(true); break; #ifdef DIFFUSION_IMAGING_EXTENDED case 2: scaleBy->SetScaleByPrincipalCurvature(); // commented in for SPIE paper, Principle curvature scaling //m_Controls->params_frame->setVisible(true); break; #endif default: scaleBy->SetScaleByNothing(); } if ( dynamic_cast(m_SelectedNode->GetData()) || dynamic_cast(m_SelectedNode->GetData()) ) { m_SelectedNode->SetProperty("Normalization", scaleBy.GetPointer()); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkControlVisualizationPropertiesView::ScalingCheckbox() { m_Controls->m_ScalingFrame->setVisible( m_Controls->m_ScalingCheckbox->isChecked() ); if( ! m_Controls->m_ScalingCheckbox->isChecked() ) { m_Controls->m_AdditionalScaling->setCurrentIndex(0); m_Controls->m_ScalingFactor->setValue(1.0); } } void QmitkControlVisualizationPropertiesView::Fiber2DfadingEFX() { if (m_SelectedNode && dynamic_cast(m_SelectedNode->GetData()) ) { bool currentMode; m_SelectedNode->GetBoolProperty("Fiber2DfadeEFX", currentMode); m_SelectedNode->SetProperty("Fiber2DfadeEFX", mitk::BoolProperty::New(!currentMode)); dynamic_cast(m_SelectedNode->GetData())->RequestUpdate2D(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkControlVisualizationPropertiesView::FiberSlicingThickness2D() { if (m_SelectedNode && dynamic_cast(m_SelectedNode->GetData())) { float fibThickness = m_Controls->m_FiberThicknessSlider->value() * 0.1; float currentThickness = 0; m_SelectedNode->GetFloatProperty("Fiber2DSliceThickness", currentThickness); if ( fabs(fibThickness-currentThickness) < 0.001 ) { return; } m_SelectedNode->SetProperty("Fiber2DSliceThickness", mitk::FloatProperty::New(fibThickness)); dynamic_cast(m_SelectedNode->GetData())->RequestUpdate2D(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkControlVisualizationPropertiesView::FiberSlicingUpdateLabel(int value) { QString label = "Range %1 mm"; label = label.arg(value * 0.1); m_Controls->label_range->setText(label); FiberSlicingThickness2D(); } - -void QmitkControlVisualizationPropertiesView::SetFiberBundleOpacity(const itk::EventObject& /*e*/) +void QmitkControlVisualizationPropertiesView::SetCustomColor(const itk::EventObject& /*e*/) { - if(m_SelectedNode) + if(m_SelectedNode && dynamic_cast(m_SelectedNode->GetData())) { + float color[3]; + m_SelectedNode->GetColor(color); mitk::FiberBundle::Pointer fib = dynamic_cast(m_SelectedNode->GetData()); - fib->RequestUpdate(); + fib->SetFiberColors(color[0]*255, color[1]*255, color[2]*255); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } -} - - -void QmitkControlVisualizationPropertiesView::SetFiberBundleCustomColor(const itk::EventObject& /*e*/) -{ - if(m_SelectedNode && dynamic_cast(m_SelectedNode->GetData())) + else if (m_SelectedNode && dynamic_cast(m_SelectedNode->GetData())) { float color[3]; m_SelectedNode->GetColor(color); - mitk::FiberBundle::Pointer fib = dynamic_cast(m_SelectedNode->GetData()); - fib->SetFiberColors(color[0]*255, color[1]*255, color[2]*255); + mitk::PeakImage::Pointer img = dynamic_cast(m_SelectedNode->GetData()); + img->SetCustomColor(color[0]*255, color[1]*255, color[2]*255); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } -void QmitkControlVisualizationPropertiesView::BundleRepresentationResetColoring() +void QmitkControlVisualizationPropertiesView::ResetColoring() { if(m_SelectedNode && dynamic_cast(m_SelectedNode->GetData())) { mitk::FiberBundle::Pointer fib = dynamic_cast(m_SelectedNode->GetData()); fib->ColorFibersByOrientation(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } + else if(m_SelectedNode && dynamic_cast(m_SelectedNode->GetData())) + { + mitk::PeakImage::Pointer fib = dynamic_cast(m_SelectedNode->GetData()); + fib->ColorByOrientation(); + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + } } void QmitkControlVisualizationPropertiesView::PlanarFigureFocus() { if(m_SelectedNode) { mitk::PlanarFigure* _PlanarFigure = 0; _PlanarFigure = dynamic_cast (m_SelectedNode->GetData()); if (_PlanarFigure && _PlanarFigure->GetPlaneGeometry()) { QmitkRenderWindow* selectedRenderWindow = 0; bool PlanarFigureInitializedWindow = false; auto renderWindowPart = this->GetRenderWindowPart(OPEN); QmitkRenderWindow* axialRenderWindow = renderWindowPart->GetQmitkRenderWindow("axial"); if (m_SelectedNode->GetBoolProperty("PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, axialRenderWindow->GetRenderer())) { selectedRenderWindow = axialRenderWindow; } QmitkRenderWindow* sagittalRenderWindow = renderWindowPart->GetQmitkRenderWindow("sagittal"); if (!selectedRenderWindow && m_SelectedNode->GetBoolProperty( "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, sagittalRenderWindow->GetRenderer())) { selectedRenderWindow = sagittalRenderWindow; } QmitkRenderWindow* coronalRenderWindow = renderWindowPart->GetQmitkRenderWindow("coronal"); if (!selectedRenderWindow && m_SelectedNode->GetBoolProperty( "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, coronalRenderWindow->GetRenderer())) { selectedRenderWindow = coronalRenderWindow; } QmitkRenderWindow* _3DRenderWindow = renderWindowPart->GetQmitkRenderWindow("3d"); if (!selectedRenderWindow && m_SelectedNode->GetBoolProperty( "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, _3DRenderWindow->GetRenderer())) { selectedRenderWindow = _3DRenderWindow; } const mitk::PlaneGeometry* _PlaneGeometry = _PlanarFigure->GetPlaneGeometry(); mitk::VnlVector normal = _PlaneGeometry->GetNormalVnl(); mitk::PlaneGeometry::ConstPointer worldGeometry1 = axialRenderWindow->GetRenderer()->GetCurrentWorldPlaneGeometry(); mitk::PlaneGeometry::ConstPointer _Plane1 = dynamic_cast( worldGeometry1.GetPointer() ); mitk::VnlVector normal1 = _Plane1->GetNormalVnl(); mitk::PlaneGeometry::ConstPointer worldGeometry2 = sagittalRenderWindow->GetRenderer()->GetCurrentWorldPlaneGeometry(); mitk::PlaneGeometry::ConstPointer _Plane2 = dynamic_cast( worldGeometry2.GetPointer() ); mitk::VnlVector normal2 = _Plane2->GetNormalVnl(); mitk::PlaneGeometry::ConstPointer worldGeometry3 = coronalRenderWindow->GetRenderer()->GetCurrentWorldPlaneGeometry(); mitk::PlaneGeometry::ConstPointer _Plane3 = dynamic_cast( worldGeometry3.GetPointer() ); mitk::VnlVector normal3 = _Plane3->GetNormalVnl(); normal[0] = fabs(normal[0]); normal[1] = fabs(normal[1]); normal[2] = fabs(normal[2]); normal1[0] = fabs(normal1[0]); normal1[1] = fabs(normal1[1]); normal1[2] = fabs(normal1[2]); normal2[0] = fabs(normal2[0]); normal2[1] = fabs(normal2[1]); normal2[2] = fabs(normal2[2]); normal3[0] = fabs(normal3[0]); normal3[1] = fabs(normal3[1]); normal3[2] = fabs(normal3[2]); double ang1 = angle(normal, normal1); double ang2 = angle(normal, normal2); double ang3 = angle(normal, normal3); if(ang1 < ang2 && ang1 < ang3) { selectedRenderWindow = axialRenderWindow; } else { if(ang2 < ang3) { selectedRenderWindow = sagittalRenderWindow; } else { selectedRenderWindow = coronalRenderWindow; } } // make node visible if (selectedRenderWindow) { const mitk::Point3D& centerP = _PlaneGeometry->GetOrigin(); selectedRenderWindow->GetSliceNavigationController()->ReorientSlices( centerP, _PlaneGeometry->GetNormal()); } } // set interactor for new node (if not already set) mitk::PlanarFigureInteractor::Pointer figureInteractor = dynamic_cast(m_SelectedNode->GetDataInteractor().GetPointer()); if(figureInteractor.IsNull()) { figureInteractor = mitk::PlanarFigureInteractor::New(); us::Module* planarFigureModule = us::ModuleRegistry::GetModule( "MitkPlanarFigure" ); figureInteractor->LoadStateMachine("PlanarFigureInteraction.xml", planarFigureModule ); figureInteractor->SetEventConfig( "PlanarFigureConfig.xml", planarFigureModule ); figureInteractor->SetDataNode( m_SelectedNode ); } m_SelectedNode->SetProperty("planarfigure.iseditable",mitk::BoolProperty::New(true)); } } void QmitkControlVisualizationPropertiesView::SetInteractor() { // BUG 19179 // typedef std::vector Container; // Container _NodeSet = this->GetDataManagerSelection(); // mitk::DataNode* node = 0; // mitk::FiberBundle* bundle = 0; // mitk::FiberBundleInteractor::Pointer bundleInteractor = 0; // // finally add all nodes to the model // for(Container::const_iterator it=_NodeSet.begin(); it!=_NodeSet.end() // ; it++) // { // node = const_cast(*it); // bundle = dynamic_cast(node->GetData()); // if(bundle) // { // bundleInteractor = dynamic_cast(node->GetInteractor()); // if(bundleInteractor.IsNotNull()) // mitk::GlobalInteraction::GetInstance()->RemoveInteractor(bundleInteractor); // if(!m_Controls->m_Crosshair->isChecked()) // { // m_Controls->m_Crosshair->setChecked(false); // this->GetActiveStdMultiWidget()->GetRenderWindow4()->setCursor(Qt::ArrowCursor); // m_CurrentPickingNode = 0; // } // else // { // m_Controls->m_Crosshair->setChecked(true); // bundleInteractor = mitk::FiberBundleInteractor::New("FiberBundleInteractor", node); // mitk::GlobalInteraction::GetInstance()->AddInteractor(bundleInteractor); // this->GetActiveStdMultiWidget()->GetRenderWindow4()->setCursor(Qt::CrossCursor); // m_CurrentPickingNode = node; // } // } // } } void QmitkControlVisualizationPropertiesView::TubeRadiusChanged() { if(m_SelectedNode && dynamic_cast(m_SelectedNode->GetData())) { float newRadius = m_Controls->m_TubeWidth->value(); if (newRadius>0) m_SelectedNode->SetBoolProperty( "light.enable_light", true); else m_SelectedNode->SetBoolProperty( "light.enable_light", false); m_SelectedNode->SetFloatProperty("shape.tuberadius", newRadius); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkControlVisualizationPropertiesView::LineWidthChanged() { if(m_SelectedNode && dynamic_cast(m_SelectedNode->GetData())) { int newWidth = m_Controls->m_LineWidth->value(); int currentWidth = 0; m_SelectedNode->GetIntProperty("shape.linewidth", currentWidth); if (currentWidth==newWidth) return; m_SelectedNode->SetIntProperty("shape.linewidth", newWidth); dynamic_cast(m_SelectedNode->GetData())->RequestUpdate(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkControlVisualizationPropertiesView::Welcome() { berry::PlatformUI::GetWorkbench()->GetIntroManager() ->ShowIntro(GetSite()->GetWorkbenchWindow(), false); } void QmitkControlVisualizationPropertiesView::OnTensorViewChanged() { if( m_NodeUsedForOdfVisualization.IsNotNull() ) { if( m_Controls-> m_EllipsoidViewRadioButton-> isChecked() ) { if ( m_SelectedNode and dynamic_cast( m_SelectedNode->GetData() ) ) { m_SelectedNode-> SetProperty( "DiffusionCore.Rendering.OdfVtkMapper.SwitchTensorView", mitk::BoolProperty::New( true ) ); mitk::OdfNormalizationMethodProperty::Pointer normalizationProperty = mitk::OdfNormalizationMethodProperty::New( mitk::ODFN_MAX ); m_SelectedNode-> SetProperty( "Normalization", normalizationProperty ); // type OdfNormalizationMethodProperty m_Controls-> m_NormalizationDropdown->setCurrentIndex ( dynamic_cast( m_SelectedNode->GetProperty("Normalization") )->GetValueAsId() ); } else { m_SelectedNode-> SetProperty( "DiffusionCore.Rendering.OdfVtkMapper.SwitchTensorView", mitk::BoolProperty::New( false ) ); m_Controls-> m_OdfViewRadioButton-> setChecked(true); m_Controls-> m_EllipsoidViewRadioButton-> setEnabled(false); } } else if( m_Controls-> m_OdfViewRadioButton-> isChecked() ) { m_SelectedNode-> SetProperty( "DiffusionCore.Rendering.OdfVtkMapper.SwitchTensorView", mitk::BoolProperty::New( false ) ); } mitk::RenderingManager::GetInstance()-> RequestUpdateAll(); } else { MITK_DEBUG << "QmitkControlVisualizationPropertiesView::OnTensorViewChanged()" " was called but m_NodeUsedForOdfVisualization was Null."; } } void QmitkControlVisualizationPropertiesView::OnColourisationModeChanged() { if( m_SelectedNode and m_NodeUsedForOdfVisualization.IsNotNull() ) { if( m_Controls-> m_colouriseRainbowRadioButton-> isChecked() ) { m_SelectedNode-> SetProperty( "DiffusionCore.Rendering.OdfVtkMapper.ColourisationModeBit", mitk::BoolProperty::New( false ) ); } else if ( m_Controls-> m_colouriseSimpleRadioButton-> isChecked() ) { m_SelectedNode-> SetProperty( "DiffusionCore.Rendering.OdfVtkMapper.ColourisationModeBit", mitk::BoolProperty::New( true ) ); } mitk::RenderingManager::GetInstance()-> RequestUpdateAll(); } else { MITK_DEBUG << "QmitkControlVisualizationPropertiesView::OnColourisationModeChanged()" " was called but m_NodeUsedForOdfVisualization was Null."; } } void QmitkControlVisualizationPropertiesView::OnRandomModeChanged() { if( m_SelectedNode and m_NodeUsedForOdfVisualization.IsNotNull() ) { if( m_Controls-> m_randomModeRadioButton-> isChecked() ) { m_SelectedNode-> SetProperty( "DiffusionCore.Rendering.OdfVtkMapper.RandomModeBit", mitk::BoolProperty::New( true ) ); } else if ( m_Controls-> m_orderedModeRadioButton-> isChecked() ) { m_SelectedNode-> SetProperty( "DiffusionCore.Rendering.OdfVtkMapper.RandomModeBit", mitk::BoolProperty::New( false ) ); } mitk::RenderingManager::GetInstance()-> RequestUpdateAll(); } else { MITK_DEBUG << "QmitkControlVisualizationPropertiesView::OnRandomModeChanged()" " was called but m_NodeUsedForOdfVisualization was Null."; } } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesView.h b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesView.h index df172b0406..d03f11eed5 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesView.h +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesView.h @@ -1,169 +1,162 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. 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 _QMITKControlVisualizationPropertiesView_H_INCLUDED #define _QMITKControlVisualizationPropertiesView_H_INCLUDED #include #include #include "berryISelectionListener.h" #include "berryIStructuredSelection.h" #include "berryISizeProvider.h" #include "ui_QmitkControlVisualizationPropertiesViewControls.h" #include "mitkEnumerationProperty.h" #include /*! * \ingroup org_mitk_gui_qt_diffusionquantification_internal * * \brief QmitkControlVisualizationPropertiesView * * Document your class here. */ class QmitkControlVisualizationPropertiesView : public QmitkAbstractView, public mitk::ILifecycleAwarePart { friend struct CvpSelListener; // this is needed for all Qt objects that should have a MOC object (everything that derives from QObject) Q_OBJECT public: static const std::string VIEW_ID; QmitkControlVisualizationPropertiesView(); virtual ~QmitkControlVisualizationPropertiesView(); virtual void CreateQtPartControl(QWidget *parent) override; /// \brief Creation of the connections of main and control widget virtual void CreateConnections(); protected slots: void VisibleOdfsON_S(); void VisibleOdfsON_T(); void VisibleOdfsON_C(); - void ShowMaxNumberChanged(); void NormalizationDropdownChanged(int); void ScalingFactorChanged(double); void AdditionalScaling(int); void ScalingCheckbox(); - void OnThickSlicesModeSelected( QAction* action ); void OnTSNumChanged(int num); - - void BundleRepresentationResetColoring(); + void ResetColoring(); void PlanarFigureFocus(); void Fiber2DfadingEFX(); void FiberSlicingThickness2D(); void FiberSlicingUpdateLabel(int); void LineWidthChanged(); void TubeRadiusChanged(); - void SetInteractor(); void Toggle3DClipping(bool enabled=true); - void FlipPeaks(); - void Welcome(); /// \brief Slot function for switching tensor view between ODF and ellipsoids from tensors. void OnTensorViewChanged(); /// \brief Slot function for switching colourisation mode of glyphs. void OnColourisationModeChanged(); /// \brief Slot function for switching glyph placement mode. void OnRandomModeChanged(); protected: virtual void SetFocus() override; virtual void Activated() override; virtual void Deactivated() override; virtual void Visible() override; virtual void Hidden() override; virtual void NodeRemoved(const mitk::DataNode* node) override; /// \brief called by QmitkAbstractView when DataManager's selection has changed virtual void OnSelectionChanged(berry::IWorkbenchPart::Pointer part, const QList& nodes) override; virtual void NodeAdded(const mitk::DataNode *node) override; - void SetFiberBundleCustomColor(const itk::EventObject& /*e*/); - void SetFiberBundleOpacity(const itk::EventObject& /*e*/); + void SetCustomColor(const itk::EventObject& /*e*/); bool IsPlaneRotated(); void SliceRotation(const itk::EventObject&); void OnAxialChanged(const itk::EventObject& e); void OnCoronalChanged(const itk::EventObject& e); void OnSagittalChanged(const itk::EventObject& e); void Set3DClippingPlane(bool disable, mitk::DataNode *node, std::string plane); Ui::QmitkControlVisualizationPropertiesViewControls* m_Controls; QScopedPointer m_SelListener; berry::IStructuredSelection::ConstPointer m_CurrentSelection; mitk::DataNode::Pointer m_NodeUsedForOdfVisualization; QIcon* m_IconTexOFF; QIcon* m_IconTexON; QIcon* m_IconGlyOFF_T; QIcon* m_IconGlyON_T; QIcon* m_IconGlyOFF_C; QIcon* m_IconGlyON_C; QIcon* m_IconGlyOFF_S; QIcon* m_IconGlyON_S; bool m_TexIsOn; bool m_GlyIsOn_T; bool m_GlyIsOn_C; bool m_GlyIsOn_S; int currentThickSlicesMode; QLabel* m_TSLabel; QMenu* m_MyMenu; // for planarfigure and bundle handling: mitk::DataNode::Pointer m_SelectedNode; mitk::DataNode* m_CurrentPickingNode; - unsigned long m_FiberBundleObserverTag; - unsigned long m_FiberBundleObserveOpacityTag; + unsigned long m_ColorPropertyObserverTag; + unsigned long m_OpacityPropertyObserverTag; mitk::ColorProperty::Pointer m_Color; mitk::FloatProperty::Pointer m_Opacity; int m_SliceObserverTag1; int m_SliceObserverTag2; int m_SliceObserverTag3; }; #endif // _QMITKControlVisualizationPropertiesView_H_INCLUDED diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesViewControls.ui b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesViewControls.ui index 1e7e8758c0..b06fcea149 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesViewControls.ui +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesViewControls.ui @@ -1,932 +1,946 @@ QmitkControlVisualizationPropertiesViewControls 0 0 567 619 0 100 0 0 QmitkTemplate 0 0 0 0 QFrame::NoFrame QFrame::Raised 0 0 0 0 0 0 QFrame::NoFrame QFrame::Raised 0 0 0 0 Multislice Projection MIP QToolButton::MenuButtonPopup Qt::NoArrow QFrame::NoFrame QFrame::Plain 0 0 0 0 Toggle visibility of ODF glyphs (axial) :/QmitkDiffusionImaging/glyphsoff_T.png :/QmitkDiffusionImaging/glyphson_T.png:/QmitkDiffusionImaging/glyphsoff_T.png true false Toggle visibility of ODF glyphs (sagittal) :/QmitkDiffusionImaging/glyphsoff_S.png :/QmitkDiffusionImaging/glyphson_S.png:/QmitkDiffusionImaging/glyphsoff_S.png true false Toggle visibility of ODF glyphs (coronal) :/QmitkDiffusionImaging/glyphsoff_C.png :/QmitkDiffusionImaging/glyphson_C.png:/QmitkDiffusionImaging/glyphsoff_C.png true false #Glyphs 9999 Qt::Horizontal 20 20 QFrame::NoFrame QFrame::Raised 0 0 0 0 0 QFrame::NoFrame QFrame::Raised 0 0 0 0 Scaling QFrame::NoFrame QFrame::Plain 0 0 0 0 false None By GFA By ASR * Additional scaling factor 3 999999999.000000000000000 0.100000000000000 1.000000000000000 QFrame::NoFrame QFrame::Plain 0 0 0 0 &ODF View true buttonGroup_2 true &Rainbow colorization true buttonGroup true E&llipsoid View buttonGroup_2 false &Simple colorization buttonGroup ODF normalization false Min-Max Max None true Random Placement true buttonGroup_3 true Orderer Placement buttonGroup_3 QFrame::NoFrame QFrame::Raised 0 0 0 0 QFrame::NoFrame QFrame::Raised 0 0 0 0 Reset to Default Coloring :/QmitkDiffusionImaging/reset.png:/QmitkDiffusionImaging/reset.png Position Crosshair by 3D-Click :/QmitkDiffusionImaging/crosshair.png:/QmitkDiffusionImaging/crosshair.png true false 2D Fiberfading on/off Qt::Horizontal 40 20 QFrame::NoFrame QFrame::Raised 0 0 0 0 2D Clipping 100 10 10 10 Qt::Horizontal 90 0 10000 16777215 Range QFrame::NoFrame QFrame::Raised 0 0 0 0 1 10 Tube Radius Line Width 4 0.100000000000000 3D Fiber Clipping 0 0 0 0 0 Sagittal No clipping true Coronal Axial Flipp Clipping Direction 50 false false <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" color:#ff0000;">One or more slices are rotated. ODF Visualisation is not possible in rotated planes. Use 'Reinit' on the image node to reset. </span></p></body></html> Qt::AutoText true QFrame::NoFrame QFrame::Raised 0 0 0 0 - - - - - 0 - 0 - - - - Flip Peaks - - - - + z - + - y + x - + + + + 0 + 0 + + - x + Flip Peaks - + Qt::Horizontal 40 20 + + + + y + + + + + + + Reset to Default Coloring + + + + + + + :/QmitkDiffusionImaging/reset.png:/QmitkDiffusionImaging/reset.png + + + Qt::Vertical 20 40 QmitkDataStorageComboBox.h