diff --git a/Core/Code/IO/mitkImageWriter.cpp b/Core/Code/IO/mitkImageWriter.cpp index a1eb3aca9a..0dfc8c3f67 100644 --- a/Core/Code/IO/mitkImageWriter.cpp +++ b/Core/Code/IO/mitkImageWriter.cpp @@ -1,312 +1,304 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkImageWriter.h" #include "mitkItkPictureWrite.h" #include "mitkImage.h" #include "mitkImageTimeSelector.h" #include "mitkPicFileWriter.h" #include "mitkImageAccessByItk.h" #include #include mitk::ImageWriter::ImageWriter() { this->SetNumberOfRequiredInputs( 1 ); m_MimeType = ""; SetDefaultExtension(); } mitk::ImageWriter::~ImageWriter() { } void mitk::ImageWriter::SetDefaultExtension() { m_Extension = ".mhd"; } #include -#if ((VTK_MAJOR_VERSION > 4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=4) )) #include #include static void writeVti(const char * filename, mitk::Image* image, int t=0) { vtkXMLImageDataWriter * vtkwriter = vtkXMLImageDataWriter::New(); vtkwriter->SetFileName( filename ); vtkwriter->SetInput(image->GetVtkImageData(t)); vtkwriter->Write(); vtkwriter->Delete(); } -#endif void mitk::ImageWriter::WriteByITK(mitk::Image* image, const std::string& fileName) { // Pictures and picture series like .png are written via a different mechanism then volume images. // So, they are still multiplexed and thus not support vector images. if (fileName.find(".png") != std::string::npos || fileName.find(".tif") != std::string::npos || fileName.find(".jpg") != std::string::npos) { AccessByItk_1( image, _mitkItkPictureWrite, fileName ); return; } // Implementation of writer using itkImageIO directly. This skips the use // of templated itkImageFileWriter, which saves the multiplexing on MITK side. unsigned int dimension = image->GetDimension(); unsigned int* dimensions = image->GetDimensions(); mitk::PixelType pixelType = image->GetPixelType(); mitk::Vector3D spacing = image->GetGeometry()->GetSpacing(); mitk::Point3D origin = image->GetGeometry()->GetOrigin(); itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO( fileName.c_str(), itk::ImageIOFactory::WriteMode ); if(imageIO.IsNull()) { itkExceptionMacro(<< "Error: Could not create itkImageIO via factory for file " << fileName); } // Set the necessary information for imageIO imageIO->SetNumberOfDimensions(dimension); imageIO->SetPixelTypeInfo( *(pixelType.GetTypeId()) ); if(pixelType.GetNumberOfComponents() > 1) imageIO->SetNumberOfComponents(pixelType.GetNumberOfComponents()); itk::ImageIORegion ioRegion( dimension ); for(unsigned int i=0; iSetDimensions(i,dimensions[i]); imageIO->SetSpacing(i,spacing[i]); imageIO->SetOrigin(i,origin[i]); mitk::Vector3D direction; direction.Set_vnl_vector(image->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(i)); vnl_vector< double > axisDirection(dimension); for(unsigned int j=0; jSetDirection( i, axisDirection ); ioRegion.SetSize(i, image->GetLargestPossibleRegion().GetSize(i) ); ioRegion.SetIndex(i, image->GetLargestPossibleRegion().GetIndex(i) ); } imageIO->SetIORegion(ioRegion); imageIO->SetFileName(fileName); const void * data = image->GetData(); imageIO->Write(data); } void mitk::ImageWriter::GenerateData() { if ( m_FileName == "" ) { itkWarningMacro( << "Sorry, filename has not been set!" ); return ; } FILE* tempFile = fopen(m_FileName.c_str(),"w"); if (tempFile==NULL) { itkExceptionMacro(<<"File location not writeable"); return; } fclose(tempFile); remove(m_FileName.c_str()); mitk::Image::Pointer input = const_cast(this->GetInput()); -#if ((VTK_MAJOR_VERSION > 4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=4) )) bool vti = (m_Extension.find(".vti") != std::string::npos); -#endif // If the extension is NOT .pic and NOT .nrrd the following block is entered if ( m_Extension.find(".pic") == std::string::npos && m_Extension.find(".nrrd") == std::string::npos) { if(input->GetDimension() > 3) { int t, timesteps; timesteps = input->GetDimension(3); ImageTimeSelector::Pointer timeSelector = ImageTimeSelector::New(); timeSelector->SetInput(input); mitk::Image::Pointer image = timeSelector->GetOutput(); for(t = 0; t < timesteps; ++t) { ::itk::OStringStream filename; timeSelector->SetTimeNr(t); timeSelector->Update(); if(input->GetTimeSlicedGeometry()->IsValidTime(t)) { const mitk::TimeBounds& timebounds = input->GetTimeSlicedGeometry()->GetGeometry3D(t)->GetTimeBounds(); filename << m_FileName.c_str() << "_S" << std::setprecision(0) << timebounds[0] << "_E" << std::setprecision(0) << timebounds[1] << "_T" << t << m_Extension; } else { itkWarningMacro(<<"Error on write: TimeSlicedGeometry invalid of image " << filename << "."); filename << m_FileName.c_str() << "_T" << t << m_Extension; } -#if ((VTK_MAJOR_VERSION > 4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=4) )) if ( vti ) { writeVti(filename.str().c_str(), input, t); } else -#endif { WriteByITK(input, filename.str()); } } } -#if ((VTK_MAJOR_VERSION > 4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=4) )) else if ( vti ) { ::itk::OStringStream filename; filename << m_FileName.c_str() << m_Extension; writeVti(filename.str().c_str(), input); } -#endif else { ::itk::OStringStream filename; filename << m_FileName.c_str() << m_Extension; WriteByITK(input, filename.str()); } } else { // use the PicFileWriter for the .pic data type if( m_Extension.find(".pic") != std::string::npos ) { PicFileWriter::Pointer picWriter = PicFileWriter::New(); size_t found; found = m_FileName.find( m_Extension ); // !!! HAS to be at the very end of the filename (not somewhere in the middle) if( m_FileName.length() > 3 && found != m_FileName.length() - 4 ) { //if Extension not in Filename ::itk::OStringStream filename; filename << m_FileName.c_str() << m_Extension; picWriter->SetFileName( filename.str().c_str() ); } else { picWriter->SetFileName( m_FileName.c_str() ); } picWriter->SetInput( input ); picWriter->Write(); } // use the ITK .nrrd Image writer if( m_Extension.find(".nrrd") != std::string::npos ) { ::itk::OStringStream filename; filename << this->m_FileName.c_str() << this->m_Extension; WriteByITK(input, filename.str()); } } m_MimeType = "application/MITK.Pic"; } bool mitk::ImageWriter::CanWriteDataType( DataNode* input ) { if ( input ) { mitk::BaseData* data = input->GetData(); if ( data ) { mitk::Image::Pointer image = dynamic_cast( data ); if( image.IsNotNull() ) { //"SetDefaultExtension()" set m_Extension to ".mhd" ????? m_Extension = ".pic"; return true; } } } return false; } void mitk::ImageWriter::SetInput( DataNode* input ) { if( input && CanWriteDataType( input ) ) this->ProcessObject::SetNthInput( 0, dynamic_cast( input->GetData() ) ); } std::string mitk::ImageWriter::GetWritenMIMEType() { return m_MimeType; } std::vector mitk::ImageWriter::GetPossibleFileExtensions() { std::vector possibleFileExtensions; possibleFileExtensions.push_back(".pic"); possibleFileExtensions.push_back(".bmp"); possibleFileExtensions.push_back(".dcm"); possibleFileExtensions.push_back(".DCM"); possibleFileExtensions.push_back(".dicom"); possibleFileExtensions.push_back(".DICOM"); possibleFileExtensions.push_back(".gipl"); possibleFileExtensions.push_back(".gipl.gz"); possibleFileExtensions.push_back(".mha"); possibleFileExtensions.push_back(".nii"); possibleFileExtensions.push_back(".nrrd"); possibleFileExtensions.push_back(".nhdr"); possibleFileExtensions.push_back(".png"); possibleFileExtensions.push_back(".PNG"); possibleFileExtensions.push_back(".spr"); possibleFileExtensions.push_back(".mhd"); possibleFileExtensions.push_back(".vtk"); possibleFileExtensions.push_back(".vti"); possibleFileExtensions.push_back(".hdr"); possibleFileExtensions.push_back(".png"); possibleFileExtensions.push_back(".tif"); possibleFileExtensions.push_back(".jpg"); return possibleFileExtensions; } std::string mitk::ImageWriter::GetFileExtension() { return m_Extension; } void mitk::ImageWriter::SetInput( mitk::Image* image ) { this->ProcessObject::SetNthInput( 0, image ); } const mitk::Image* mitk::ImageWriter::GetInput() { if ( this->GetNumberOfInputs() < 1 ) { return NULL; } else { return static_cast< const mitk::Image * >( this->ProcessObject::GetInput( 0 ) ); } } diff --git a/Modules/DiffusionImaging/IODataStructures/TensorImages/mitkTensorImage.cpp b/Modules/DiffusionImaging/IODataStructures/TensorImages/mitkTensorImage.cpp index 0f8d31a61f..41b09cfa1f 100644 --- a/Modules/DiffusionImaging/IODataStructures/TensorImages/mitkTensorImage.cpp +++ b/Modules/DiffusionImaging/IODataStructures/TensorImages/mitkTensorImage.cpp @@ -1,195 +1,191 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2008-02-08 11:19:03 +0100 (Fr, 08 Feb 2008) $ Version: $Revision: 11989 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkTensorImage.h" #include "mitkImageDataItem.h" #include "mitkImageCast.h" #include "itkDiffusionTensor3D.h" #include "itkTensorToRgbImageFilter.h" #include "vtkImageData.h" // #ifdef _OPENMP // #include "omp.h" // #endif mitk::TensorImage::TensorImage() : Image() { m_RgbImage = 0; } mitk::TensorImage::~TensorImage() { } vtkImageData* mitk::TensorImage::GetVtkImageData(int t, int n) { if(m_RgbImage.IsNull()) { ConstructRgbImage(); } return m_RgbImage->GetVtkImageData(t,n); } void mitk::TensorImage::ConstructRgbImage() { typedef itk::Image,3> ImageType; typedef itk::TensorToRgbImageFilter FilterType; FilterType::Pointer filter = FilterType::New(); ImageType::Pointer itkvol = ImageType::New(); mitk::CastToItkImage(this, itkvol); filter->SetInput(itkvol); filter->Update(); m_RgbImage = mitk::Image::New(); m_RgbImage->InitializeByItk( filter->GetOutput() ); m_RgbImage->SetVolume( filter->GetOutput()->GetBufferPointer() ); } vtkImageData* mitk::TensorImage::GetNonRgbVtkImageData(int t, int n) { return Superclass::GetVtkImageData(t,n); } // //vtkImageData* mitk::TensorImage::GetRgbVtkImageData(int t, int n) //{ // if(m_Initialized==false) // { // if(GetSource()==NULL) // return NULL; // if(GetSource()->Updating()==false) // GetSource()->UpdateOutputInformation(); // } // // if(m_VtkImageData==NULL) // ConstructVtkImageData(); // return m_VtkImageData; // // ImageDataItemPointer volume=GetVolumeData(t, n); // if(volume.GetPointer()==NULL || volume->GetVtkImageData() == NULL) // return NULL; // -//#if ((VTK_MAJOR_VERSION > 4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=4) )) // float *fspacing = const_cast(GetSlicedGeometry(t)->GetFloatSpacing()); // double dspacing[3] = {fspacing[0],fspacing[1],fspacing[2]}; // volume->GetVtkImageData()->SetSpacing( dspacing ); -//#else -// volume->GetVtkImageData()->SetSpacing(const_cast(GetSlicedGeometry(t)->GetFloatSpacing())); -//#endif // return volume->GetVtkImageData(); //} // //void mitk::TensorImage::ConstructRgbVtkImageData(int t, int n) const //{ // vtkImageData *inData = vtkImageData::New(); // vtkDataArray *scalars = NULL; // // mitkIpPicDescriptor* picDescriptor = GetVolumeData(t,n)->GetPicDescriptor(); // // unsigned long size = 0; // if ( picDescriptor->dim == 1 ) // { // inData->SetDimensions( picDescriptor->n[0] -1, 1, 1); // size = picDescriptor->n[0]; // inData->SetOrigin( ((float) picDescriptor->n[0]) / 2.0f, 0, 0 ); // } // else if ( picDescriptor->dim == 2 ) // { // inData->SetDimensions( picDescriptor->n[0] , picDescriptor->n[1] , 1 ); // size = picDescriptor->n[0] * picDescriptor->n[1]; // inData->SetOrigin( ((float) picDescriptor->n[0]) / 2.0f, ((float) picDescriptor->n[1]) / 2.0f, 0 ); // } // else if ( picDescriptor->dim >= 3 ) // { // inData->SetDimensions( picDescriptor->n[0], picDescriptor->n[1], picDescriptor->n[2] ); // size = picDescriptor->n[0] * picDescriptor->n[1] * picDescriptor->n[2]; // // Test // //inData->SetOrigin( (float) picDescriptor->n[0] / 2.0f, (float) picDescriptor->n[1] / 2.0f, (float) picDescriptor->n[2] / 2.0f ); // inData->SetOrigin( 0, 0, 0 ); // } // else // { // inData->Delete () ; // return; // } // // // allocate new scalars with three components for RGB // inData->SetNumberOfScalarComponents(3); // inData->SetScalarType( VTK_UNSIGNED_CHAR ); // scalars = vtkUnsignedCharArray::New(); // m_VtkImageDataTensor = inData; // scalars->SetNumberOfComponents(m_VtkImageDataTensor->GetNumberOfScalarComponents()); // // // calculate RGB information from tensors // if(m_PixelType == typeid(itk::DiffusionTensor3D)) // scalars->SetVoidArray(ConvertTensorsToRGB >(), m_Size/2, 1); // if(m_PixelType == typeid(itk::DiffusionTensor3D)) // scalars->SetVoidArray(ConvertTensorsToRGB >(), m_Size/2, 1); // // m_VtkImageDataTensor->GetPointData()->SetScalars(scalars); // scalars->Delete(); // //} // ///** //* This method calculates RGB image from tensor information. //* Templated over pixeltype, output always three uchar components. //*/ //template //unsigned char *mitk::ImageDataItem::ConvertTensorsToRGB() const //{ // const unsigned char *p = m_Data; // unsigned char *out = (unsigned char *) malloc(m_Size/2); // const int pixelsize = sizeof(TPixeltype); // const int numIts = m_Size/pixelsize; // //#ifdef _OPENMP //#pragma omp parallel for //#endif // for(int i=0; i((void*)(p+i*pixelsize)); // typename TPixeltype::EigenValuesArrayType eigenvalues; // typename TPixeltype::EigenVectorsMatrixType eigenvectors; // tensor->ComputeEigenAnalysis(eigenvalues, eigenvectors); // // int index = 2; // if( (eigenvalues[0] >= eigenvalues[1]) // && (eigenvalues[0] >= eigenvalues[2]) ) // index = 0; // else if(eigenvalues[1] >= eigenvalues[2]) // index = 1; // // const float fa = tensor->GetFractionalAnisotropy(); // float r = abs(eigenvectors(index,0)) * fa; // float g = abs(eigenvectors(index,1)) * fa; // float b = abs(eigenvectors(index,2)) * fa; // // __IMG_DAT_ITEM__CEIL_ZERO_ONE__(r); // __IMG_DAT_ITEM__CEIL_ZERO_ONE__(g); // __IMG_DAT_ITEM__CEIL_ZERO_ONE__(b); // // *(out+i*3+0) = (unsigned char)( 255.0f * r ); // *(out+i*3+1) = (unsigned char)( 255.0f * g ); // *(out+i*3+2) = (unsigned char)( 255.0f * b ); // } // return out; //} diff --git a/Modules/DiffusionImaging/Rendering/mitkCompositeMapper.h b/Modules/DiffusionImaging/Rendering/mitkCompositeMapper.h index 1ce4aae15b..13cfae7c11 100644 --- a/Modules/DiffusionImaging/Rendering/mitkCompositeMapper.h +++ b/Modules/DiffusionImaging/Rendering/mitkCompositeMapper.h @@ -1,180 +1,178 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2009-05-12 19:56:03 +0200 (Di, 12 Mai 2009) $ Version: $Revision: 17179 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef COMPOSITEMAPPER_H_HEADER_INCLUDED #define COMPOSITEMAPPER_H_HEADER_INCLUDED #include "mitkGLMapper2D.h" #include "mitkVtkMapper2D.h" #include "mitkQBallImage.h" #include "mitkImageMapperGL2D.h" #include "mitkOdfVtkMapper2D.h" #include "mitkLevelWindowProperty.h" namespace mitk { class CopyImageMapper2D : public ImageMapperGL2D { public: mitkClassMacro(CopyImageMapper2D,ImageMapperGL2D); itkNewMacro(Self); friend class CompositeMapper; }; //##Documentation //## @brief Composite pattern for combination of different mappers //## @ingroup Mapper class CompositeMapper : public VtkMapper2D { public: mitkClassMacro(CompositeMapper,VtkMapper2D); itkNewMacro(Self); virtual void MitkRenderOverlay(BaseRenderer* renderer) { Enable2DOpenGL(); m_ImgMapper->MitkRenderOverlay(renderer); Disable2DOpenGL(); m_OdfMapper->MitkRenderOverlay(renderer); } virtual void MitkRenderOpaqueGeometry(BaseRenderer* renderer) { Enable2DOpenGL(); m_ImgMapper->MitkRenderOpaqueGeometry(renderer); Disable2DOpenGL(); m_OdfMapper->MitkRenderOpaqueGeometry(renderer); if( mitk::RenderingManager::GetInstance()->GetNextLOD( renderer ) == 0 ) { renderer->Modified(); } } virtual void MitkRenderTranslucentGeometry(BaseRenderer* renderer) { Enable2DOpenGL(); m_ImgMapper->MitkRenderTranslucentGeometry(renderer); Disable2DOpenGL(); m_OdfMapper->MitkRenderTranslucentGeometry(renderer); } -#if ( ( VTK_MAJOR_VERSION >= 5 ) && ( VTK_MINOR_VERSION>=2) ) virtual void MitkRenderVolumetricGeometry(BaseRenderer* renderer) { Enable2DOpenGL(); m_ImgMapper->MitkRenderVolumetricGeometry(renderer); Disable2DOpenGL(); m_OdfMapper->MitkRenderVolumetricGeometry(renderer); } -#endif void SetDataNode(DataNode* node) { m_DataNode = node; m_ImgMapper->SetDataNode(node); m_OdfMapper->SetDataNode(node); } mitk::ImageMapperGL2D::Pointer GetImageMapper() { ImageMapperGL2D* retval = m_ImgMapper; return retval; } bool IsVtkBased() const { return m_OdfMapper->IsVtkBased(); } bool HasVtkProp( const vtkProp* prop, BaseRenderer* renderer ) { return m_OdfMapper->HasVtkProp(prop, renderer); } void ReleaseGraphicsResources(vtkWindow* window) { m_ImgMapper->ReleaseGraphicsResources(window); m_OdfMapper->ReleaseGraphicsResources(window); } static void SetDefaultProperties(DataNode* node, BaseRenderer* renderer = NULL, bool overwrite = false ) { mitk::OdfVtkMapper2D::SetDefaultProperties(node, renderer, overwrite); mitk::CopyImageMapper2D::SetDefaultProperties(node, renderer, overwrite); mitk::LevelWindow opaclevwin; opaclevwin.SetRangeMinMax(0,255); opaclevwin.SetWindowBounds(0,0); mitk::LevelWindowProperty::Pointer prop = mitk::LevelWindowProperty::New(opaclevwin); node->AddProperty( "opaclevelwindow", prop ); } bool IsLODEnabled( BaseRenderer * renderer ) const { return m_ImgMapper->IsLODEnabled(renderer) || m_OdfMapper->IsLODEnabled(renderer); } vtkProp* GetProp(mitk::BaseRenderer* renderer) { return m_OdfMapper->GetProp(renderer); } void SetGeometry3D(const mitk::Geometry3D* aGeometry3D) { m_ImgMapper->SetGeometry3D(aGeometry3D); m_OdfMapper->SetGeometry3D(aGeometry3D); } void Enable2DOpenGL(); void Disable2DOpenGL(); protected: virtual void GenerateData() { m_OdfMapper->GenerateData(); } virtual void GenerateData(mitk::BaseRenderer* renderer) { m_ImgMapper->GenerateData(renderer); if( mitk::RenderingManager::GetInstance()->GetNextLOD( renderer ) > 0 ) { m_OdfMapper->GenerateData(renderer); } } CompositeMapper(); virtual ~CompositeMapper(); private: mitk::OdfVtkMapper2D::Pointer m_OdfMapper; mitk::CopyImageMapper2D::Pointer m_ImgMapper; }; } // namespace mitk #endif /* COMPOSITEMAPPER_H_HEADER_INCLUDED */ diff --git a/Modules/DiffusionImaging/Rendering/mitkOdfVtkMapper2D.h b/Modules/DiffusionImaging/Rendering/mitkOdfVtkMapper2D.h index e4ceb2170b..612d75504e 100644 --- a/Modules/DiffusionImaging/Rendering/mitkOdfVtkMapper2D.h +++ b/Modules/DiffusionImaging/Rendering/mitkOdfVtkMapper2D.h @@ -1,156 +1,154 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2008-02-08 13:23:19 +0100 (Fr, 08 Feb 2008) $ Version: $Revision: 13561 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef ODFVTKMAPPER2D_H_HEADER_INCLUDED #define ODFVTKMAPPER2D_H_HEADER_INCLUDED #include "mitkVtkMapper2D.h" #include "vtkPropAssembly.h" #include "vtkAppendPolyData.h" #include "vtkActor.h" #include "vtkPolyDataMapper.h" #include "vtkPlane.h" #include "vtkCutter.h" #include "vtkClipPolyData.h" #include "vtkTransform.h" #include "vtkDataArrayTemplate.h" #include "vtkSmartPointer.h" #include "vtkOdfSource.h" #include "vtkThickPlane.h" //#include "mitkTrackingCameraController.h" namespace mitk { //##Documentation //## @brief Base class of all vtk-based 2D-Mappers //## //## Those must implement the abstract //## method vtkProp* GetProp(). //## @ingroup Mapper template class OdfVtkMapper2D : public VtkMapper2D { struct OdfDisplayGeometry { vtkFloatingPointType vp[ 3 ], vnormal[ 3 ]; Vector3D normal; double d, d1, d2; mitk::Point3D M3D, L3D, O3D; vtkFloatingPointType vp_original[ 3 ], vnormal_original[ 3 ]; mitk::Vector2D size, origin; bool Equals(OdfDisplayGeometry* other) { return other->vp_original[0] == vp[0] && other->vp_original[1] == vp[1] && other->vp_original[2] == vp[2] && other->vnormal_original[0] == vnormal[0] && other->vnormal_original[1] == vnormal[1] && other->vnormal_original[2] == vnormal[2] && other->size[0] == size[0] && other->size[1] == size[1] && other->origin[0] == origin[0] && other->origin[1] == origin[1]; } }; public: mitkClassMacro(OdfVtkMapper2D,VtkMapper2D); itkNewMacro(Self); virtual vtkProp* GetProp(mitk::BaseRenderer* renderer); bool IsVisibleOdfs(mitk::BaseRenderer* renderer); virtual void MitkRenderOverlay(mitk::BaseRenderer* renderer); virtual void MitkRenderOpaqueGeometry(mitk::BaseRenderer* renderer); virtual void MitkRenderTranslucentGeometry(mitk::BaseRenderer* renderer); -#if ( ( VTK_MAJOR_VERSION >= 5 ) && ( VTK_MINOR_VERSION>=2) ) virtual void MitkRenderVolumetricGeometry(mitk::BaseRenderer* /*renderer*/){}; -#endif OdfDisplayGeometry* MeasureDisplayedGeometry(mitk::BaseRenderer* renderer); void AdaptCameraPosition(mitk::BaseRenderer* renderer, OdfDisplayGeometry* dispGeo ); void AdaptOdfScalingToImageSpacing( int index ); void SetRendererLightSources( mitk::BaseRenderer *renderer ); void ApplyPropertySettings(); virtual void Slice(mitk::BaseRenderer* renderer, OdfDisplayGeometry* dispGeo); virtual int GetIndex(mitk::BaseRenderer* renderer); static void SetDefaultProperties(DataNode* node, BaseRenderer* renderer = NULL, bool overwrite = false); virtual void GenerateData(); virtual void GenerateData(mitk::BaseRenderer* renderer); virtual bool IsLODEnabled( BaseRenderer * /*renderer*/ ) const { return true; } protected: OdfVtkMapper2D(); virtual ~OdfVtkMapper2D(); static void GlyphMethod(void *arg); bool IsPlaneRotated(mitk::BaseRenderer* renderer); private: std::vector m_PropAssemblies; std::vector m_OdfsPlanes; std::vector m_OdfsActors; std::vector m_OdfsMappers; vtkPolyData* m_TemplateOdf; static vtkSmartPointer m_OdfTransform; static vtkSmartPointer m_OdfVals; static vtkSmartPointer m_OdfSource; static float m_Scaling; static int m_Normalization; static int m_ScaleBy; static float m_IndexParam1; static float m_IndexParam2; int m_ShowMaxNumber; //std::vector m_TrackingCameraControllers; std::vector m_Planes; std::vector m_Cutters; std::vector m_ThickPlanes1; std::vector m_Clippers1; std::vector m_ThickPlanes2; std::vector m_Clippers2; vtkImageData* m_VtkImage ; mitk::Image* GetInput(); OdfDisplayGeometry* m_LastDisplayGeometry; }; } // namespace mitk #include "mitkOdfVtkMapper2D.txx" #endif /* ODFVTKMAPPER2D_H_HEADER_INCLUDED */ diff --git a/Modules/DiffusionImaging/Rendering/mitkOdfVtkMapper2D.txx b/Modules/DiffusionImaging/Rendering/mitkOdfVtkMapper2D.txx index cb754873ab..74f9933194 100644 --- a/Modules/DiffusionImaging/Rendering/mitkOdfVtkMapper2D.txx +++ b/Modules/DiffusionImaging/Rendering/mitkOdfVtkMapper2D.txx @@ -1,1166 +1,1162 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2008-08-25 18:10:57 +0200 (Mo, 25 Aug 2008) $ Version: $Revision: 15062 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __mitkOdfVtkMapper2D_txx__ #define __mitkOdfVtkMapper2D_txx__ #include "mitkOdfVtkMapper2D.h" #include "mitkDataNode.h" #include "mitkBaseRenderer.h" #include "mitkMatrixConvert.h" #include "mitkGeometry3D.h" #include "mitkOdfNormalizationMethodProperty.h" #include "mitkOdfScaleByProperty.h" #include "mitkProperties.h" #include "mitkTensorImage.h" #include "vtkSphereSource.h" #include "vtkPropCollection.h" #include "vtkMaskedGlyph3D.h" #include "vtkGlyph2D.h" #include "vtkGlyph3D.h" #include "vtkMaskedProgrammableGlyphFilter.h" #include "vtkImageData.h" #include "vtkLinearTransform.h" #include "vtkCamera.h" #include "vtkPointData.h" #include "vtkTransformPolyDataFilter.h" #include "vtkTransform.h" #include "vtkOdfSource.h" #include "vtkDoubleArray.h" #include "vtkLookupTable.h" #include "vtkProperty.h" #include "vtkPolyDataNormals.h" #include "vtkLight.h" #include "vtkLightCollection.h" #include "vtkMath.h" #include "vtkFloatArray.h" #include "vtkDelaunay2D.h" #include "vtkMapper.h" #include "vtkRenderer.h" #include "vtkCamera.h" #include "itkOrientationDistributionFunction.h" #include "itkFixedArray.h" #include #include "vtkOpenGLRenderer.h" template vtkSmartPointer mitk::OdfVtkMapper2D::m_OdfTransform = vtkSmartPointer::New(); template vtkSmartPointer mitk::OdfVtkMapper2D::m_OdfVals = vtkSmartPointer::New(); template vtkSmartPointer mitk::OdfVtkMapper2D::m_OdfSource = vtkSmartPointer::New(); template float mitk::OdfVtkMapper2D::m_Scaling; template int mitk::OdfVtkMapper2D::m_Normalization; template int mitk::OdfVtkMapper2D::m_ScaleBy; template float mitk::OdfVtkMapper2D::m_IndexParam1; template float mitk::OdfVtkMapper2D::m_IndexParam2; #define ODF_MAPPER_PI 3.1415926535897932384626433832795 //#include "vtkSphereSource.h" //#include "vtkPolyDataMapper.h" //#include "vtkActor.h" //#include "vtkRenderWindow.h" //#include "vtkRenderer.h" //#include "vtkRenderWindowInteractor.h" //#include "vtkProperty.h" // //void bla(vtkPolyData* poly) //{ // // // map to graphics library // vtkPolyDataMapper *map = vtkPolyDataMapper::New(); // map->SetInput(poly); // // // actor coordinates geometry, properties, transformation // vtkActor *aSphere = vtkActor::New(); // aSphere->SetMapper(map); // aSphere->GetProperty()->SetColor(0,0,1); // sphere color blue // // // a renderer and render window // vtkRenderer *ren1 = vtkRenderer::New(); // vtkRenderWindow *renWin = vtkRenderWindow::New(); // renWin->AddRenderer(ren1); // // // an interactor // vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New(); // iren->SetRenderWindow(renWin); // // // add the actor to the scene // ren1->AddActor(aSphere); // ren1->SetBackground(1,1,1); // Background color white // // // render an image (lights and cameras are created automatically) // renWin->Render(); // // // begin mouse interaction // iren->Start(); //} template mitk::OdfVtkMapper2D ::OdfVtkMapper2D() { m_VtkBased = true; m_LastDisplayGeometry = 0; m_PropAssemblies.push_back(vtkPropAssembly::New()); m_PropAssemblies.push_back(vtkPropAssembly::New()); m_PropAssemblies.push_back(vtkPropAssembly::New()); m_OdfsPlanes.push_back(vtkAppendPolyData::New()); m_OdfsPlanes.push_back(vtkAppendPolyData::New()); m_OdfsPlanes.push_back(vtkAppendPolyData::New()); m_OdfsPlanes[0]->AddInput(vtkPolyData::New()); m_OdfsPlanes[1]->AddInput(vtkPolyData::New()); m_OdfsPlanes[2]->AddInput(vtkPolyData::New()); m_OdfsActors.push_back(vtkActor::New()); m_OdfsActors.push_back(vtkActor::New()); m_OdfsActors.push_back(vtkActor::New()); m_OdfsActors[0]->GetProperty()->SetInterpolationToGouraud(); m_OdfsActors[1]->GetProperty()->SetInterpolationToGouraud(); m_OdfsActors[2]->GetProperty()->SetInterpolationToGouraud(); m_OdfsMappers.push_back(vtkPolyDataMapper::New()); m_OdfsMappers.push_back(vtkPolyDataMapper::New()); m_OdfsMappers.push_back(vtkPolyDataMapper::New()); vtkLookupTable *lut = vtkLookupTable::New(); //lut->SetMinimumTableValue(0,0,1,1); //lut->SetMaximumTableValue(1,0,0,1); //lut->SetWindow(0.1); //lut->SetLevel(0.05); <== not recognized or reset by mapper ?? //lut->Build(); m_OdfsMappers[0]->SetLookupTable(lut); m_OdfsMappers[1]->SetLookupTable(lut); m_OdfsMappers[2]->SetLookupTable(lut); m_OdfsActors[0]->SetMapper(m_OdfsMappers[0]); m_OdfsActors[1]->SetMapper(m_OdfsMappers[1]); m_OdfsActors[2]->SetMapper(m_OdfsMappers[2]); m_Planes.push_back(vtkPlane::New()); m_Planes.push_back(vtkPlane::New()); m_Planes.push_back(vtkPlane::New()); m_Cutters.push_back(vtkCutter::New()); m_Cutters.push_back(vtkCutter::New()); m_Cutters.push_back(vtkCutter::New()); m_Cutters[0]->SetCutFunction( m_Planes[0] ); m_Cutters[0]->GenerateValues( 1, 0, 1 ); m_Cutters[1]->SetCutFunction( m_Planes[1] ); m_Cutters[1]->GenerateValues( 1, 0, 1 ); m_Cutters[2]->SetCutFunction( m_Planes[2] ); m_Cutters[2]->GenerateValues( 1, 0, 1 ); // Windowing the cutted planes in direction 1 m_ThickPlanes1.push_back(vtkThickPlane::New()); m_ThickPlanes1.push_back(vtkThickPlane::New()); m_ThickPlanes1.push_back(vtkThickPlane::New()); m_Clippers1.push_back(vtkClipPolyData::New()); m_Clippers1.push_back(vtkClipPolyData::New()); m_Clippers1.push_back(vtkClipPolyData::New()); m_Clippers1[0]->SetClipFunction( m_ThickPlanes1[0] ); m_Clippers1[1]->SetClipFunction( m_ThickPlanes1[1] ); m_Clippers1[2]->SetClipFunction( m_ThickPlanes1[2] ); // Windowing the cutted planes in direction 2 m_ThickPlanes2.push_back(vtkThickPlane::New()); m_ThickPlanes2.push_back(vtkThickPlane::New()); m_ThickPlanes2.push_back(vtkThickPlane::New()); m_Clippers2.push_back(vtkClipPolyData::New()); m_Clippers2.push_back(vtkClipPolyData::New()); m_Clippers2.push_back(vtkClipPolyData::New()); m_Clippers2[0]->SetClipFunction( m_ThickPlanes2[0] ); m_Clippers2[1]->SetClipFunction( m_ThickPlanes2[1] ); m_Clippers2[2]->SetClipFunction( m_ThickPlanes2[2] ); m_TemplateOdf = itk::OrientationDistributionFunction::GetBaseMesh(); //vtkPoints* points = m_TemplateOdf->GetPoints(); m_OdfVals->Allocate(N); m_OdfSource->SetTemplateOdf(m_TemplateOdf); m_OdfSource->SetOdfVals(m_OdfVals); m_ShowMaxNumber = 500; //vtkMapper::GlobalImmediateModeRenderingOn(); } template mitk::OdfVtkMapper2D ::~OdfVtkMapper2D() { m_PropAssemblies[0]->Delete(); m_PropAssemblies[1]->Delete(); m_PropAssemblies[2]->Delete(); m_OdfsPlanes[0]->Delete(); m_OdfsPlanes[1]->Delete(); m_OdfsPlanes[2]->Delete(); m_OdfsActors[0]->Delete(); m_OdfsActors[1]->Delete(); m_OdfsActors[2]->Delete(); m_OdfsMappers[0]->Delete(); m_OdfsMappers[1]->Delete(); m_OdfsMappers[2]->Delete(); m_Planes[0]->Delete(); m_Planes[1]->Delete(); m_Planes[2]->Delete(); m_Cutters[0]->Delete(); m_Cutters[1]->Delete(); m_Cutters[2]->Delete(); m_ThickPlanes1[0]->Delete(); m_ThickPlanes1[1]->Delete(); m_ThickPlanes1[2]->Delete(); m_ThickPlanes2[0]->Delete(); m_ThickPlanes2[1]->Delete(); m_ThickPlanes2[2]->Delete(); m_Clippers1[0]->Delete(); m_Clippers1[1]->Delete(); m_Clippers1[2]->Delete(); m_Clippers2[0]->Delete(); m_Clippers2[1]->Delete(); m_Clippers2[2]->Delete(); } template mitk::Image* mitk::OdfVtkMapper2D ::GetInput() { return static_cast ( m_DataNode->GetData() ); } template vtkProp* mitk::OdfVtkMapper2D ::GetProp(mitk::BaseRenderer* renderer) { return m_PropAssemblies[GetIndex(renderer)]; } template int mitk::OdfVtkMapper2D ::GetIndex(mitk::BaseRenderer* renderer) { if(!strcmp(renderer->GetName(),"stdmulti.widget1")) return 0; if(!strcmp(renderer->GetName(),"stdmulti.widget2")) return 1; if(!strcmp(renderer->GetName(),"stdmulti.widget3")) return 2; return 0; } template void mitk::OdfVtkMapper2D ::GlyphMethod(void *arg) { vtkMaskedProgrammableGlyphFilter *pfilter=(vtkMaskedProgrammableGlyphFilter*)arg; double point[3]; double debugpoint[3]; pfilter->GetPoint(point); pfilter->GetPoint(debugpoint); itk::Point p(point); Vector3D spacing = pfilter->GetGeometry()->GetSpacing(); p[0] /= spacing[0]; p[1] /= spacing[1]; p[2] /= spacing[2]; mitk::Point3D p2; pfilter->GetGeometry()->IndexToWorld( p, p2 ); point[0] = p2[0]; point[1] = p2[1]; point[2] = p2[2]; vtkPointData* data = pfilter->GetPointData(); vtkDataArray* odfvals = data->GetArray("vector"); vtkIdType id = pfilter->GetPointId(); m_OdfTransform->Identity(); m_OdfTransform->Translate(point[0],point[1],point[2]); typedef itk::OrientationDistributionFunction OdfType; OdfType odf; if(odfvals->GetNumberOfComponents()==6) { float tensorelems[6] = { (float)odfvals->GetComponent(id,0), (float)odfvals->GetComponent(id,1), (float)odfvals->GetComponent(id,2), (float)odfvals->GetComponent(id,3), (float)odfvals->GetComponent(id,4), (float)odfvals->GetComponent(id,5), }; itk::DiffusionTensor3D tensor(tensorelems); odf.InitFromTensor(tensor); } else { for(int i=0; iGetComponent(id,i); } switch(m_Normalization) { case ODFN_MINMAX: odf = odf.MinMaxNormalize(); break; case ODFN_MAX: odf = odf.MaxNormalize(); break; case ODFN_NONE: // nothing break; case ODFN_GLOBAL_MAX: // global max not implemented yet break; default: odf = odf.MinMaxNormalize(); } switch(m_ScaleBy) { case ODFSB_NONE: break; case ODFSB_GFA: odf = odf * odf.GetGeneralizedGFA(m_IndexParam1, m_IndexParam2); break; case ODFSB_PC: odf = odf * odf.GetPrincipleCurvature(m_IndexParam1, m_IndexParam2, 0); break; } for(int i=0; iSetComponent(0,i,0.5*odf[i]*m_Scaling); //double max = -100000; //double min = 100000; //for( unsigned int i=0; i max ? odf[i] : max; // min = odf[i] < min ? odf[i] : min; //} m_OdfSource->Modified(); } template void mitk::OdfVtkMapper2D ::AdaptCameraPosition(mitk::BaseRenderer* renderer, OdfDisplayGeometry* dispGeo ) { double viewAngle = renderer->GetVtkRenderer()->GetActiveCamera()->GetViewAngle(); viewAngle = viewAngle * (ODF_MAPPER_PI/180.0); viewAngle /= 2; double dist = dispGeo->d/tan(viewAngle); mitk::Point3D mfoc; mfoc[0]=dispGeo->M3D[0]; mfoc[1]=dispGeo->M3D[1]; mfoc[2]=dispGeo->M3D[2]; mitk::Point3D mpos; mpos[0]=mfoc[0]+dist*dispGeo->normal[0]; mpos[1]=mfoc[1]+dist*dispGeo->normal[1]; mpos[2]=mfoc[2]+dist*dispGeo->normal[2]; mitk::Point3D mup; mup[0]=dispGeo->O3D[0]-dispGeo->M3D[0]; mup[1]=dispGeo->O3D[1]-dispGeo->M3D[1]; mup[2]=dispGeo->O3D[2]-dispGeo->M3D[2]; renderer->GetVtkRenderer()->GetActiveCamera()->SetParallelProjection(true); renderer->GetVtkRenderer()->GetActiveCamera()->SetParallelScale(dist/3.74); vtkCamera* camera = renderer->GetVtkRenderer()->GetActiveCamera(); if (camera) { camera->SetPosition(mpos[0],mpos[1],mpos[2]); camera->SetFocalPoint(mfoc[0], mfoc[1],mfoc[2]); camera->SetViewUp(mup[0],mup[1],mup[2]); } renderer->GetVtkRenderer()->ResetCameraClippingRange(); } template typename mitk::OdfVtkMapper2D::OdfDisplayGeometry* mitk::OdfVtkMapper2D ::MeasureDisplayedGeometry(mitk::BaseRenderer* renderer) { //vtkLinearTransform * vtktransform = this->GetDataNode()->GetVtkTransform(this->GetTimestep()); Geometry2D::ConstPointer worldGeometry = renderer->GetCurrentWorldGeometry2D(); PlaneGeometry::ConstPointer worldPlaneGeometry = dynamic_cast( worldGeometry.GetPointer() ); // set up the cutter orientation according to the current geometry of // the renderers plane vtkFloatingPointType vp[ 3 ], vnormal[ 3 ]; Point3D point = worldPlaneGeometry->GetOrigin(); Vector3D normal = worldPlaneGeometry->GetNormal(); normal.Normalize(); vnl2vtk( point.Get_vnl_vector(), vp ); vnl2vtk( normal.Get_vnl_vector(), vnormal ); mitk::DisplayGeometry::Pointer dispGeometry = renderer->GetDisplayGeometry(); mitk::Vector2D size = dispGeometry->GetSizeInMM(); mitk::Vector2D origin = dispGeometry->GetOriginInMM(); // // |------O------| // | d2 | // L d1 M | // | | // |-------------| // mitk::Vector2D M; mitk::Vector2D L; mitk::Vector2D O; M[0] = origin[0] + size[0]/2; M[1] = origin[1] + size[1]/2; L[0] = origin[0]; L[1] = origin[1] + size[1]/2; O[0] = origin[0] + size[0]/2; O[1] = origin[1] + size[1]; mitk::Point2D point1; point1[0] = M[0]; point1[1] = M[1]; point1[2] = M[2]; mitk::Point3D M3D; dispGeometry->Map(point1, M3D); point1[0] = L[0]; point1[1] = L[1]; point1[2] = L[2]; mitk::Point3D L3D; dispGeometry->Map(point1, L3D); point1[0] = O[0]; point1[1] = O[1]; point1[2] = O[2]; mitk::Point3D O3D; dispGeometry->Map(point1, O3D); double d1 = sqrt((M3D[0]-L3D[0])*(M3D[0]-L3D[0]) + (M3D[1]-L3D[1])*(M3D[1]-L3D[1]) + (M3D[2]-L3D[2])*(M3D[2]-L3D[2])); double d2 = sqrt((M3D[0]-O3D[0])*(M3D[0]-O3D[0]) + (M3D[1]-O3D[1])*(M3D[1]-O3D[1]) + (M3D[2]-O3D[2])*(M3D[2]-O3D[2])); double d = d1>d2 ? d1 : d2; d = d2; OdfDisplayGeometry* retval = new OdfDisplayGeometry(); retval->vp[0] = vp[0]; retval->vp[1] = vp[1]; retval->vp[2] = vp[2]; retval->vnormal[0] = vnormal[0]; retval->vnormal[1] = vnormal[1]; retval->vnormal[2] = vnormal[2]; retval->normal[0] = normal[0]; retval->normal[1] = normal[1]; retval->normal[2] = normal[2]; retval->d = d; retval->d1 = d1; retval->d2 = d2; retval->M3D[0] = M3D[0]; retval->M3D[1] = M3D[1]; retval->M3D[2] = M3D[2]; retval->L3D[0] = L3D[0]; retval->L3D[1] = L3D[1]; retval->L3D[2] = L3D[2]; retval->O3D[0] = O3D[0]; retval->O3D[1] = O3D[1]; retval->O3D[2] = O3D[2]; retval->vp_original[0] = vp[0]; retval->vp_original[1] = vp[1]; retval->vp_original[2] = vp[2]; retval->vnormal_original[0] = vnormal[0]; retval->vnormal_original[1] = vnormal[1]; retval->vnormal_original[2] = vnormal[2]; retval->size[0] = size[0]; retval->size[1] = size[1]; retval->origin[0] = origin[0]; retval->origin[1] = origin[1]; return retval; } template void mitk::OdfVtkMapper2D ::Slice(mitk::BaseRenderer* renderer, OdfDisplayGeometry* dispGeo) { vtkLinearTransform * vtktransform = this->GetDataNode()->GetVtkTransform(this->GetTimestep()); int index = GetIndex(renderer); vtkTransform* inversetransform = vtkTransform::New(); inversetransform->Identity(); inversetransform->Concatenate(vtktransform->GetLinearInverse()); double myscale[3]; ((vtkTransform*)vtktransform)->GetScale(myscale); inversetransform->PostMultiply(); inversetransform->Scale(1*myscale[0],1*myscale[1],1*myscale[2]); inversetransform->TransformPoint( dispGeo->vp, dispGeo->vp ); inversetransform->TransformNormalAtPoint( dispGeo->vp, dispGeo->vnormal, dispGeo->vnormal ); // vtk works in axis align coords // thus the normal also must be axis align, since // we do not allow arbitrary cutting through volume // // vnormal should already be axis align, but in order // to get rid of precision effects, we set the two smaller // components to zero here int dims[3]; m_VtkImage->GetDimensions(dims); double spac[3]; m_VtkImage->GetSpacing(spac); if(fabs(dispGeo->vnormal[0]) > fabs(dispGeo->vnormal[1]) && fabs(dispGeo->vnormal[0]) > fabs(dispGeo->vnormal[2]) ) { if(fabs(dispGeo->vp[0]/spac[0]) < 0.4) dispGeo->vp[0] = 0.4*spac[0]; if(fabs(dispGeo->vp[0]/spac[0]) > (dims[0]-1)-0.4) dispGeo->vp[0] = ((dims[0]-1)-0.4)*spac[0]; dispGeo->vnormal[1] = 0; dispGeo->vnormal[2] = 0; } if(fabs(dispGeo->vnormal[1]) > fabs(dispGeo->vnormal[0]) && fabs(dispGeo->vnormal[1]) > fabs(dispGeo->vnormal[2]) ) { if(fabs(dispGeo->vp[1]/spac[1]) < 0.4) dispGeo->vp[1] = 0.4*spac[1]; if(fabs(dispGeo->vp[1]/spac[1]) > (dims[1]-1)-0.4) dispGeo->vp[1] = ((dims[1]-1)-0.4)*spac[1]; dispGeo->vnormal[0] = 0; dispGeo->vnormal[2] = 0; } if(fabs(dispGeo->vnormal[2]) > fabs(dispGeo->vnormal[1]) && fabs(dispGeo->vnormal[2]) > fabs(dispGeo->vnormal[0]) ) { if(fabs(dispGeo->vp[2]/spac[2]) < 0.4) dispGeo->vp[2] = 0.4*spac[2]; if(fabs(dispGeo->vp[2]/spac[2]) > (dims[2]-1)-0.4) dispGeo->vp[2] = ((dims[2]-1)-0.4)*spac[2]; dispGeo->vnormal[0] = 0; dispGeo->vnormal[1] = 0; } m_Planes[index]->SetTransform( (vtkAbstractTransform*)NULL ); m_Planes[index]->SetOrigin( dispGeo->vp ); m_Planes[index]->SetNormal( dispGeo->vnormal ); vtkPoints* points = NULL; vtkPoints* tmppoints = NULL; vtkPolyData* polydata = NULL; vtkFloatArray* pointdata = NULL; vtkDelaunay2D *delaunay = NULL; vtkPolyData* cuttedPlane = NULL; if(!( (dims[0] == 1 && dispGeo->vnormal[0] != 0) || (dims[1] == 1 && dispGeo->vnormal[1] != 0) || (dims[2] == 1 && dispGeo->vnormal[2] != 0) )) { m_Cutters[index]->SetCutFunction( m_Planes[index] ); m_Cutters[index]->SetInput( m_VtkImage ); m_Cutters[index]->Update(); cuttedPlane = m_Cutters[index]->GetOutput(); } else { // cutting of a 2D-Volume does not work, // so we have to build up our own polydata object cuttedPlane = vtkPolyData::New(); points = vtkPoints::New(); points->SetNumberOfPoints(m_VtkImage->GetNumberOfPoints()); for(int i=0; iGetNumberOfPoints(); i++) { points->SetPoint(i, m_VtkImage->GetPoint(i)); } cuttedPlane->SetPoints(points); pointdata = vtkFloatArray::New(); int comps = m_VtkImage->GetPointData()->GetScalars()->GetNumberOfComponents(); pointdata->SetNumberOfComponents(comps); int tuples = m_VtkImage->GetPointData()->GetScalars()->GetNumberOfTuples(); pointdata->SetNumberOfTuples(tuples); for(int i=0; iSetTuple(i,m_VtkImage->GetPointData()->GetScalars()->GetTuple(i)); pointdata->SetName( "vector" ); cuttedPlane->GetPointData()->AddArray(pointdata); int nZero1, nZero2; if(dims[0]==1) { nZero1 = 1; nZero2 = 2; } else if(dims[1]==1) { nZero1 = 0; nZero2 = 2; } else { nZero1 = 0; nZero2 = 1; } tmppoints = vtkPoints::New(); for(int j=0; jGetNumberOfPoints(); j++){ double pt[3]; m_VtkImage->GetPoint(j,pt); tmppoints->InsertNextPoint(pt[nZero1],pt[nZero2],0); } polydata = vtkPolyData::New(); polydata->SetPoints( tmppoints ); delaunay = vtkDelaunay2D::New(); delaunay->SetInput( polydata ); delaunay->Update(); vtkCellArray* polys = delaunay->GetOutput()->GetPolys(); cuttedPlane->SetPolys(polys); } if(cuttedPlane->GetNumberOfPoints()) { // WINDOWING HERE inversetransform = vtkTransform::New(); inversetransform->Identity(); inversetransform->Concatenate(vtktransform->GetLinearInverse()); double myscale[3]; ((vtkTransform*)vtktransform)->GetScale(myscale); inversetransform->PostMultiply(); inversetransform->Scale(1*myscale[0],1*myscale[1],1*myscale[2]); dispGeo->vnormal[0] = dispGeo->M3D[0]-dispGeo->O3D[0]; dispGeo->vnormal[1] = dispGeo->M3D[1]-dispGeo->O3D[1]; dispGeo->vnormal[2] = dispGeo->M3D[2]-dispGeo->O3D[2]; vtkMath::Normalize(dispGeo->vnormal); dispGeo->vp[0] = dispGeo->M3D[0]; dispGeo->vp[1] = dispGeo->M3D[1]; dispGeo->vp[2] = dispGeo->M3D[2]; inversetransform->TransformPoint( dispGeo->vp, dispGeo->vp ); inversetransform->TransformNormalAtPoint( dispGeo->vp, dispGeo->vnormal, dispGeo->vnormal ); m_ThickPlanes1[index]->count = 0; m_ThickPlanes1[index]->SetTransform((vtkAbstractTransform*)NULL ); m_ThickPlanes1[index]->SetPose( dispGeo->vnormal, dispGeo->vp ); m_ThickPlanes1[index]->SetThickness(dispGeo->d2); m_Clippers1[index]->SetClipFunction( m_ThickPlanes1[index] ); m_Clippers1[index]->SetInput( cuttedPlane ); m_Clippers1[index]->SetInsideOut(1); m_Clippers1[index]->Update(); dispGeo->vnormal[0] = dispGeo->M3D[0]-dispGeo->L3D[0]; dispGeo->vnormal[1] = dispGeo->M3D[1]-dispGeo->L3D[1]; dispGeo->vnormal[2] = dispGeo->M3D[2]-dispGeo->L3D[2]; vtkMath::Normalize(dispGeo->vnormal); dispGeo->vp[0] = dispGeo->M3D[0]; dispGeo->vp[1] = dispGeo->M3D[1]; dispGeo->vp[2] = dispGeo->M3D[2]; inversetransform->TransformPoint( dispGeo->vp, dispGeo->vp ); inversetransform->TransformNormalAtPoint( dispGeo->vp, dispGeo->vnormal, dispGeo->vnormal ); m_ThickPlanes2[index]->count = 0; m_ThickPlanes2[index]->SetTransform((vtkAbstractTransform*)NULL ); m_ThickPlanes2[index]->SetPose( dispGeo->vnormal, dispGeo->vp ); m_ThickPlanes2[index]->SetThickness(dispGeo->d1); m_Clippers2[index]->SetClipFunction( m_ThickPlanes2[index] ); m_Clippers2[index]->SetInput( m_Clippers1[index]->GetOutput() ); m_Clippers2[index]->SetInsideOut(1); m_Clippers2[index]->Update(); cuttedPlane = m_Clippers2[index]->GetOutput (); if(cuttedPlane->GetNumberOfPoints()) { m_OdfsPlanes[index]->RemoveAllInputs(); vtkPolyDataNormals* normals = vtkPolyDataNormals::New(); normals->SetInputConnection( m_OdfSource->GetOutputPort() ); normals->SplittingOff(); normals->ConsistencyOff(); normals->AutoOrientNormalsOff(); normals->ComputePointNormalsOn(); normals->ComputeCellNormalsOff(); normals->FlipNormalsOff(); normals->NonManifoldTraversalOff(); vtkTransformPolyDataFilter* trans = vtkTransformPolyDataFilter::New(); trans->SetInputConnection( normals->GetOutputPort() ); trans->SetTransform(m_OdfTransform); vtkMaskedProgrammableGlyphFilter* glyphGenerator = vtkMaskedProgrammableGlyphFilter::New(); glyphGenerator->SetMaximumNumberOfPoints(m_ShowMaxNumber); glyphGenerator->SetRandomMode(1); glyphGenerator->SetUseMaskPoints(1); glyphGenerator->SetSource( trans->GetOutput() ); glyphGenerator->SetInput(cuttedPlane); glyphGenerator->SetColorModeToColorBySource(); glyphGenerator->SetInputArrayToProcess(0,0,0, vtkDataObject::FIELD_ASSOCIATION_POINTS , "vector"); glyphGenerator->SetGeometry(this->GetDataNode()->GetData()->GetGeometry()); glyphGenerator->SetGlyphMethod(&(GlyphMethod),(void *)glyphGenerator); try { glyphGenerator->Update(); } catch( itk::ExceptionObject& err ) { std::cout << err << std::endl; } m_OdfsPlanes[index]->AddInput(glyphGenerator->GetOutput()); trans->Delete(); glyphGenerator->Delete(); normals->Delete(); m_OdfsPlanes[index]->Update(); } } m_PropAssemblies[index]->VisibilityOn(); if(m_PropAssemblies[index]->GetParts()->IsItemPresent(m_OdfsActors[index])) m_PropAssemblies[index]->RemovePart(m_OdfsActors[index]); m_OdfsMappers[index]->SetInput(m_OdfsPlanes[index]->GetOutput()); m_PropAssemblies[index]->AddPart(m_OdfsActors[index]); if(inversetransform) inversetransform->Delete(); if(points) points->Delete(); if(pointdata) pointdata->Delete(); if(tmppoints) tmppoints->Delete(); if(polydata) polydata->Delete(); if(delaunay) delaunay->Delete(); } template bool mitk::OdfVtkMapper2D ::IsVisibleOdfs(mitk::BaseRenderer* renderer) { if(this->IsPlaneRotated(renderer)) return false; bool retval = false; switch(GetIndex(renderer)) { case 0: retval = this->IsVisible(renderer, "VisibleOdfs_T"); break; case 1: retval = this->IsVisible(renderer, "VisibleOdfs_S"); break; case 2: retval = this->IsVisible(renderer, "VisibleOdfs_C"); break; } return retval; } template void mitk::OdfVtkMapper2D ::MitkRenderOverlay(mitk::BaseRenderer* renderer) { //std::cout << "MitkRenderOverlay(" << renderer->GetName() << ")" << std::endl; if ( this->IsVisibleOdfs(renderer)==false ) return; if ( this->GetProp(renderer)->GetVisibility() ) { this->GetProp(renderer)->RenderOverlay(renderer->GetVtkRenderer()); } } template void mitk::OdfVtkMapper2D ::MitkRenderOpaqueGeometry(mitk::BaseRenderer* renderer) { //std::cout << "MitkRenderOpaqueGeometry(" << renderer->GetName() << ")" << std::endl; if ( this->IsVisibleOdfs( renderer )==false ) return; if ( this->GetProp(renderer)->GetVisibility() ) { // adapt cam pos OdfDisplayGeometry* dispGeo = MeasureDisplayedGeometry( renderer); AdaptCameraPosition(renderer, dispGeo); if(this->GetDataNode()->IsOn("DoRefresh",NULL)) { glMatrixMode( GL_PROJECTION ); glPushMatrix(); glLoadIdentity(); glMatrixMode( GL_MODELVIEW ); glPushMatrix(); glLoadIdentity(); renderer->GetVtkRenderer()->SetErase(false); renderer->GetVtkRenderer()->GetActiveCamera()->Render(renderer->GetVtkRenderer()); renderer->GetVtkRenderer()->SetErase(true); //GLfloat matrix[16]; //glGetFloatv(GL_MODELVIEW_MATRIX, matrix); float LightPos[4] = {0,0,0,0}; int index = GetIndex(renderer); if(index==0) { LightPos[2] = -1000; } if(index==1) { LightPos[0] = 1000; } if(index==2) { LightPos[1] = -1000; } glLightfv(GL_LIGHT0,GL_POSITION,LightPos); glLightfv(GL_LIGHT1,GL_POSITION,LightPos); glLightfv(GL_LIGHT2,GL_POSITION,LightPos); glLightfv(GL_LIGHT3,GL_POSITION,LightPos); glLightfv(GL_LIGHT4,GL_POSITION,LightPos); glLightfv(GL_LIGHT5,GL_POSITION,LightPos); glLightfv(GL_LIGHT6,GL_POSITION,LightPos); glLightfv(GL_LIGHT7,GL_POSITION,LightPos); } this->GetProp(renderer)->RenderOpaqueGeometry( renderer->GetVtkRenderer() ); if(this->GetDataNode()->IsOn("DoRefresh",NULL)) { glMatrixMode( GL_PROJECTION ); glPopMatrix(); glMatrixMode( GL_MODELVIEW ); glPopMatrix(); } } } template void mitk::OdfVtkMapper2D ::MitkRenderTranslucentGeometry(mitk::BaseRenderer* renderer) { //std::cout << "MitkRenderTranslucentGeometry(" << renderer->GetName() << ")" << std::endl; if ( this->IsVisibleOdfs(renderer)==false ) return; if ( this->GetProp(renderer)->GetVisibility() ) - //BUG (#1551) changed VTK_MINOR_VERSION FROM 3 to 2 cause RenderTranslucentGeometry was changed in minor version 2 -#if ( ( VTK_MAJOR_VERSION >= 5 ) && ( VTK_MINOR_VERSION>=2) ) this->GetProp(renderer)->RenderTranslucentPolygonalGeometry(renderer->GetVtkRenderer()); -#else - this->GetProp(renderer)->RenderTranslucentGeometry(renderer->GetVtkRenderer()); -#endif + } template void mitk::OdfVtkMapper2D ::GenerateData() { mitk::Image::Pointer input = const_cast( this->GetInput() ); if ( input.IsNull() ) return ; std::string classname("TensorImage"); if(classname.compare(input->GetNameOfClass())==0) { m_VtkImage = dynamic_cast( this->GetInput() )->GetNonRgbVtkImageData(); } std::string qclassname("QBallImage"); if(qclassname.compare(input->GetNameOfClass())==0) { m_VtkImage = dynamic_cast( this->GetInput() )->GetNonRgbVtkImageData(); } if( m_VtkImage ) { // make sure, that we have point data with more than 1 component (as vectors) vtkPointData* pointData = m_VtkImage->GetPointData(); if ( pointData == NULL ) { itkWarningMacro( << "m_VtkImage->GetPointData() returns NULL!" ); return ; } if ( pointData->GetNumberOfArrays() == 0 ) { itkWarningMacro( << "m_VtkImage->GetPointData()->GetNumberOfArrays() is 0!" ); return ; } else if ( pointData->GetArray(0)->GetNumberOfComponents() != N && pointData->GetArray(0)->GetNumberOfComponents() != 6 /*for tensor visualization*/) { itkWarningMacro( << "number of components != number of directions in ODF!" ); return; } else if ( pointData->GetArrayName( 0 ) == NULL ) { m_VtkImage->GetPointData()->GetArray(0)->SetName("vector"); } } else { itkWarningMacro( << "m_VtkImage is NULL!" ); return ; } } template void mitk::OdfVtkMapper2D ::AdaptOdfScalingToImageSpacing( int index ) { // Spacing adapted scaling double spacing[3]; m_VtkImage->GetSpacing(spacing); double min; if(index==0) { min = spacing[0]; min = min > spacing[1] ? spacing[1] : min; } if(index==1) { min = spacing[1]; min = min > spacing[2] ? spacing[2] : min; } if(index==2) { min = spacing[0]; min = min > spacing[2] ? spacing[2] : min; } m_OdfSource->SetScale(min); } template void mitk::OdfVtkMapper2D ::SetRendererLightSources( mitk::BaseRenderer *renderer ) { // Light Sources vtkCollectionSimpleIterator sit; vtkLight* light; for(renderer->GetVtkRenderer()->GetLights()->InitTraversal(sit); (light = renderer->GetVtkRenderer()->GetLights()->GetNextLight(sit)); ) { renderer->GetVtkRenderer()->RemoveLight(light); } light = vtkLight::New(); light->SetFocalPoint(0,0,0); light->SetLightTypeToSceneLight(); light->SwitchOn(); light->SetIntensity(1.0); light->PositionalOff(); itk::Point p; int index = GetIndex(renderer); if(index==0) { p[0] = 0; p[1] = 0; p[2] = 10000; } if(index==1) { p[0] = 0; p[1] = 10000; p[2] = 0; } if(index==2) { p[0] = 10000; p[1] = 0; p[2] = 0; } mitk::Point3D p2; this->GetInput()->GetGeometry()->IndexToWorld(p,p2); light->SetPosition(p2[0],p2[1],p2[2]); renderer->GetVtkRenderer()->AddLight(light); } template void mitk::OdfVtkMapper2D ::ApplyPropertySettings() { this->GetDataNode()->GetFloatProperty( "Scaling", m_Scaling ); this->GetDataNode()->GetIntProperty( "ShowMaxNumber", m_ShowMaxNumber ); OdfNormalizationMethodProperty* nmp = dynamic_cast ( this->GetDataNode()->GetProperty( "Normalization" )); if(nmp) { m_Normalization = nmp->GetNormalization(); } OdfScaleByProperty* sbp = dynamic_cast ( this->GetDataNode()->GetProperty( "ScaleBy" )); if(sbp) { m_ScaleBy = sbp->GetScaleBy(); } this->GetDataNode()->GetFloatProperty( "IndexParam1", m_IndexParam1); this->GetDataNode()->GetFloatProperty( "IndexParam2", m_IndexParam2); } template bool mitk::OdfVtkMapper2D ::IsPlaneRotated(mitk::BaseRenderer* renderer) { Geometry2D::ConstPointer worldGeometry = renderer->GetCurrentWorldGeometry2D(); PlaneGeometry::ConstPointer worldPlaneGeometry = dynamic_cast( worldGeometry.GetPointer() ); vtkFloatingPointType vnormal[ 3 ]; Vector3D normal = worldPlaneGeometry->GetNormal(); normal.Normalize(); vnl2vtk( normal.Get_vnl_vector(), vnormal ); vtkLinearTransform * vtktransform = this->GetDataNode()->GetVtkTransform(this->GetTimestep()); vtkTransform* inversetransform = vtkTransform::New(); inversetransform->Identity(); inversetransform->Concatenate(vtktransform->GetLinearInverse()); double* n = inversetransform->TransformNormal(vnormal); int nonZeros = 0; for (int j=0; j<3; j++) { if (fabs(n[j])>1e-7){ nonZeros++; } } if(nonZeros>1) return true; return false; } template void mitk::OdfVtkMapper2D ::GenerateData( mitk::BaseRenderer *renderer ) { if(!m_VtkImage) { itkWarningMacro( << "m_VtkImage is NULL!" ); return ; } int index = GetIndex(renderer); if(IsVisibleOdfs(renderer)==false) { m_OdfsActors[0]->VisibilityOff(); m_OdfsActors[1]->VisibilityOff(); m_OdfsActors[2]->VisibilityOff(); return; } else { m_OdfsActors[0]->VisibilityOn(); m_OdfsActors[1]->VisibilityOn(); m_OdfsActors[2]->VisibilityOn(); OdfDisplayGeometry* dispGeo = MeasureDisplayedGeometry( renderer); if(!m_LastDisplayGeometry || !dispGeo->Equals(m_LastDisplayGeometry)) { AdaptOdfScalingToImageSpacing(index); SetRendererLightSources(renderer); ApplyPropertySettings(); AdaptCameraPosition(renderer, dispGeo); Slice(renderer, dispGeo); m_LastDisplayGeometry = dispGeo; } } // Get the TimeSlicedGeometry of the input object mitk::Image::Pointer input = const_cast(this->GetInput()); const TimeSlicedGeometry *inputTimeGeometry = input->GetTimeSlicedGeometry(); if (( inputTimeGeometry == NULL ) || ( inputTimeGeometry->GetTimeSteps() == 0 )) { m_PropAssemblies[0]->VisibilityOff(); m_PropAssemblies[1]->VisibilityOff(); m_PropAssemblies[2]->VisibilityOff(); return; } if( inputTimeGeometry->IsValidTime( this->GetTimestep() ) == false ) { m_PropAssemblies[0]->VisibilityOff(); m_PropAssemblies[1]->VisibilityOff(); m_PropAssemblies[2]->VisibilityOff(); return; } } template void mitk::OdfVtkMapper2D ::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* /*renderer*/, bool /*overwrite*/) { node->SetProperty( "ShowMaxNumber", mitk::IntProperty::New( 150 ) ); node->SetProperty( "Scaling", mitk::FloatProperty::New( 1.0 ) ); node->SetProperty( "Normalization", mitk::OdfNormalizationMethodProperty::New()); node->SetProperty( "ScaleBy", mitk::OdfScaleByProperty::New()); node->SetProperty( "IndexParam1", mitk::FloatProperty::New(2)); node->SetProperty( "IndexParam2", mitk::FloatProperty::New(1)); node->SetProperty( "visible", mitk::BoolProperty::New( true ) ); node->SetProperty( "VisibleOdfs_T", mitk::BoolProperty::New( false ) ); node->SetProperty( "VisibleOdfs_C", mitk::BoolProperty::New( false ) ); node->SetProperty( "VisibleOdfs_S", mitk::BoolProperty::New( false ) ); node->SetProperty ("layer", mitk::IntProperty::New(100)); node->SetProperty( "DoRefresh", mitk::BoolProperty::New( true ) ); //node->SetProperty( "opacity", mitk::FloatProperty::New(1.0f) ); } #endif // __mitkOdfVtkMapper2D_txx__ diff --git a/Modules/MitkExt/Algorithms/mitkImageToSurfaceFilter.cpp b/Modules/MitkExt/Algorithms/mitkImageToSurfaceFilter.cpp index dea4a2849b..3c5c04e543 100644 --- a/Modules/MitkExt/Algorithms/mitkImageToSurfaceFilter.cpp +++ b/Modules/MitkExt/Algorithms/mitkImageToSurfaceFilter.cpp @@ -1,243 +1,216 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include #include #include #include #include -#if (VTK_MAJOR_VERSION < 5) -#include -#endif - #include "mitkProgressBar.h" mitk::ImageToSurfaceFilter::ImageToSurfaceFilter(): m_Smooth(false), m_Decimate( NoDecimation), m_Threshold(1.0), m_TargetReduction(0.95f), m_SmoothIteration(50), m_SmoothRelaxation(0.1) { } mitk::ImageToSurfaceFilter::~ImageToSurfaceFilter() { } void mitk::ImageToSurfaceFilter::CreateSurface(int time, vtkImageData *vtkimage, mitk::Surface * surface, const ScalarType threshold) { vtkImageChangeInformation *indexCoordinatesImageFilter = vtkImageChangeInformation::New(); indexCoordinatesImageFilter->SetInput(vtkimage); indexCoordinatesImageFilter->SetOutputOrigin(0.0,0.0,0.0); //MarchingCube -->create Surface vtkMarchingCubes *skinExtractor = vtkMarchingCubes::New(); skinExtractor->ComputeScalarsOff(); skinExtractor->SetInput(indexCoordinatesImageFilter->GetOutput());//RC++ indexCoordinatesImageFilter->Delete(); skinExtractor->SetValue(0, threshold); vtkPolyData *polydata; polydata = skinExtractor->GetOutput(); polydata->Register(NULL);//RC++ skinExtractor->Delete(); if (m_Smooth) { vtkSmoothPolyDataFilter *smoother = vtkSmoothPolyDataFilter::New(); //read poly1 (poly1 can be the original polygon, or the decimated polygon) smoother->SetInput(polydata);//RC++ smoother->SetNumberOfIterations( m_SmoothIteration ); smoother->SetRelaxationFactor( m_SmoothRelaxation ); smoother->SetFeatureAngle( 60 ); smoother->FeatureEdgeSmoothingOff(); smoother->BoundarySmoothingOff(); smoother->SetConvergence( 0 ); polydata->Delete();//RC-- polydata = smoother->GetOutput(); polydata->Register(NULL);//RC++ smoother->Delete(); } ProgressBar::GetInstance()->Progress(); -//#if (VTK_MAJOR_VERSION >= 5) -// if (m_Decimate == Decimate ) -// { -// MITK_ERROR << "vtkDecimate not available for VTK 5.0 and above."; -// MITK_ERROR << " Using vtkDecimatePro instead." << std::endl; -// m_Decimate = DecimatePro; -// } -//#endif - //decimate = to reduce number of polygons if(m_Decimate==DecimatePro) { vtkDecimatePro *decimate = vtkDecimatePro::New(); decimate->SplittingOff(); decimate->SetErrorIsAbsolute(5); decimate->SetFeatureAngle(30); decimate->PreserveTopologyOn(); decimate->BoundaryVertexDeletionOff(); decimate->SetDegree(10); //std-value is 25! decimate->SetInput(polydata);//RC++ decimate->SetTargetReduction(m_TargetReduction); decimate->SetMaximumError(0.002); polydata->Delete();//RC-- polydata = decimate->GetOutput(); polydata->Register(NULL);//RC++ decimate->Delete(); } else if (m_Decimate==QuadricDecimation) { vtkQuadricDecimation* decimate = vtkQuadricDecimation::New(); decimate->SetTargetReduction(m_TargetReduction); decimate->SetInput(polydata); polydata->Delete(); polydata = decimate->GetOutput(); polydata->Register(NULL); decimate->Delete(); } -#if (VTK_MAJOR_VERSION < 5) - else if (m_Decimate==Decimate) - { - vtkDecimate *decimate = vtkDecimate::New(); - decimate->SetInput( polydata ); - decimate->PreserveTopologyOn(); - decimate->BoundaryVertexDeletionOff(); - decimate->SetTargetReduction( m_TargetReduction ); - polydata->Delete();//RC-- - polydata = decimate->GetOutput(); - polydata->Register(NULL);//RC++ - decimate->Delete(); - } -#endif polydata->Update(); ProgressBar::GetInstance()->Progress(); polydata->SetSource(NULL); if(polydata->GetNumberOfPoints() > 0) { mitk::Vector3D spacing = GetInput()->GetGeometry(time)->GetSpacing(); vtkPoints * points = polydata->GetPoints(); vtkMatrix4x4 *vtkmatrix = vtkMatrix4x4::New(); GetInput()->GetGeometry(time)->GetVtkTransform()->GetMatrix(vtkmatrix); double (*matrix)[4] = vtkmatrix->Element; unsigned int i,j; for(i=0;i<3;++i) for(j=0;j<3;++j) matrix[i][j]/=spacing[j]; unsigned int n = points->GetNumberOfPoints(); vtkFloatingPointType point[3]; for (i = 0; i < n; i++) { points->GetPoint(i, point); mitkVtkLinearTransformPoint(matrix,point,point); points->SetPoint(i, point); } vtkmatrix->Delete(); } ProgressBar::GetInstance()->Progress(); surface->SetVtkPolyData(polydata, time); polydata->UnRegister(NULL); } void mitk::ImageToSurfaceFilter::GenerateData() { mitk::Surface *surface = this->GetOutput(); mitk::Image * image = (mitk::Image*)GetInput(); mitk::Image::RegionType outputRegion = image->GetRequestedRegion(); int tstart=outputRegion.GetIndex(3); int tmax=tstart+outputRegion.GetSize(3); //GetSize()==1 - will aber 0 haben, wenn nicht zeitaufgeloest if ((tmax-tstart) > 0) { ProgressBar::GetInstance()->AddStepsToDo( 4 * (tmax - tstart) ); } int t; for( t=tstart; t < tmax; ++t) { vtkImageData *vtkimagedata = image->GetVtkImageData(t); CreateSurface(t,vtkimagedata,surface,m_Threshold); ProgressBar::GetInstance()->Progress(); } } void mitk::ImageToSurfaceFilter::SetSmoothIteration(int smoothIteration) { m_SmoothIteration = smoothIteration; } void mitk::ImageToSurfaceFilter::SetSmoothRelaxation(float smoothRelaxation) { m_SmoothRelaxation = smoothRelaxation; } void mitk::ImageToSurfaceFilter::SetInput(const mitk::Image *image) { // Process object is not const-correct so the const_cast is required here this->ProcessObject::SetNthInput(0, const_cast< mitk::Image * >( image ) ); } const mitk::Image *mitk::ImageToSurfaceFilter::GetInput(void) { if (this->GetNumberOfInputs() < 1) { return 0; } return static_cast ( this->ProcessObject::GetInput(0) ); } void mitk::ImageToSurfaceFilter::GenerateOutputInformation() { mitk::Image::ConstPointer inputImage =(mitk::Image*) this->GetInput(); //mitk::Image *inputImage = (mitk::Image*)this->GetImage(); mitk::Surface::Pointer output = this->GetOutput(); itkDebugMacro(<<"GenerateOutputInformation()"); if(inputImage.IsNull()) return; //Set Data } diff --git a/Modules/MitkExt/Algorithms/mitkLabeledImageToSurfaceFilter.cpp b/Modules/MitkExt/Algorithms/mitkLabeledImageToSurfaceFilter.cpp index d7d47e5bf0..6705daba3c 100644 --- a/Modules/MitkExt/Algorithms/mitkLabeledImageToSurfaceFilter.cpp +++ b/Modules/MitkExt/Algorithms/mitkLabeledImageToSurfaceFilter.cpp @@ -1,392 +1,365 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include #include #include #include #include -#if (VTK_MAJOR_VERSION < 5) -#include -#endif #include #include #include #include #include #include mitk::LabeledImageToSurfaceFilter::LabeledImageToSurfaceFilter() : m_GaussianStandardDeviation(1.5), m_GenerateAllLabels(true), m_Label(1), m_BackgroundLabel(0) { } mitk::LabeledImageToSurfaceFilter::~LabeledImageToSurfaceFilter() { } void mitk::LabeledImageToSurfaceFilter::GenerateOutputInformation() { Superclass::GenerateOutputInformation(); // // check which labels are available in the image // m_AvailableLabels = this->GetAvailableLabels(); m_IdxToLabels.clear(); // // if we don't want to generate surfaces for all labels // we have to remove all labels except m_Label and m_BackgroundLabel // from the list of available labels // if ( ! m_GenerateAllLabels ) { LabelMapType tmp; LabelMapType::iterator it; it = m_AvailableLabels.find( m_Label ); if ( it != m_AvailableLabels.end() ) tmp[m_Label] = it->second; else tmp[m_Label] = 0; it = m_AvailableLabels.find( m_BackgroundLabel ); if ( it != m_AvailableLabels.end() ) tmp[m_BackgroundLabel] = it->second; else tmp[m_BackgroundLabel] = 0; m_AvailableLabels = tmp; } // // check for the number of labels: if the whole image is filled, no // background is available and thus the numberOfOutpus is equal to the // number of available labels in the image (which is a special case). // If we have background voxels, the number of outputs is one less than // then number of available labels. // unsigned int numberOfOutputs = 0; if ( m_AvailableLabels.find( m_BackgroundLabel ) == m_AvailableLabels.end() ) numberOfOutputs = m_AvailableLabels.size(); else numberOfOutputs = m_AvailableLabels.size() - 1; if ( numberOfOutputs == 0 ) { itkWarningMacro("Number of outputs == 0"); } // // determine the number of time steps of the input image // mitk::Image* image = ( mitk::Image* )GetInput(); unsigned int numberOfTimeSteps = image->GetTimeSlicedGeometry()->GetTimeSteps(); // // set the number of outputs to the number of labels used. // initialize the output surfaces accordingly (incl. time steps) // this->SetNumberOfOutputs( numberOfOutputs ); this->SetNumberOfRequiredOutputs( numberOfOutputs ); for ( unsigned int i = 0 ; i < numberOfOutputs; ++i ) { if ( ! this->GetOutput( i ) ) { mitk::Surface::Pointer output = static_cast( this->MakeOutput(0).GetPointer() ); assert ( output.IsNotNull() ); output->Expand( numberOfTimeSteps ); this->SetNthOutput( i, output.GetPointer() ); } } } void mitk::LabeledImageToSurfaceFilter::GenerateData() { mitk::Image* image = ( mitk::Image* )GetInput(); if ( image == NULL ) { itkWarningMacro("Image is NULL"); return; } mitk::Image::RegionType outputRegion = image->GetRequestedRegion(); m_IdxToLabels.clear(); if ( this->GetNumberOfOutputs() == 0 ) return; // // traverse the known labels and create surfaces for them. // unsigned int currentOutputIndex = 0; for ( LabelMapType::iterator it = m_AvailableLabels.begin() ; it != m_AvailableLabels.end() ; ++it ) { if ( it->first == m_BackgroundLabel ) continue; if ( ( it->second == 0 ) && m_GenerateAllLabels ) continue; assert ( currentOutputIndex < this->GetNumberOfOutputs() ); mitk::Surface::Pointer surface = this->GetOutput( currentOutputIndex ); assert( surface.IsNotNull() ); int tstart=outputRegion.GetIndex(3); int tmax=tstart+outputRegion.GetSize(3); //GetSize()==1 - will aber 0 haben, wenn nicht zeitaufgeloet int t; for( t=tstart; t < tmax; ++t) { vtkImageData *vtkimagedata = image->GetVtkImageData( t ); CreateSurface( t,vtkimagedata,surface.GetPointer(), it->first ); } m_IdxToLabels[ currentOutputIndex ] = it->first; currentOutputIndex++; } } void mitk::LabeledImageToSurfaceFilter::CreateSurface( int time, vtkImageData *vtkimage, mitk::Surface * surface, mitk::LabeledImageToSurfaceFilter::LabelType label ) { vtkImageChangeInformation *indexCoordinatesImageFilter = vtkImageChangeInformation::New(); indexCoordinatesImageFilter->SetInput(vtkimage); indexCoordinatesImageFilter->SetOutputOrigin(0.0,0.0,0.0); vtkImageThreshold* threshold = vtkImageThreshold::New(); threshold->SetInput( indexCoordinatesImageFilter->GetOutput() ); //indexCoordinatesImageFilter->Delete(); threshold->SetInValue( 100 ); threshold->SetOutValue( 0 ); threshold->ThresholdBetween( label, label ); threshold->SetOutputScalarTypeToUnsignedChar(); threshold->ReleaseDataFlagOn(); vtkImageGaussianSmooth *gaussian = vtkImageGaussianSmooth::New(); gaussian->SetInput( threshold->GetOutput() ); //threshold->Delete(); gaussian->SetDimensionality( 3 ); gaussian->SetRadiusFactor( 0.49 ); gaussian->SetStandardDeviation( GetGaussianStandardDeviation() ); gaussian->ReleaseDataFlagOn(); gaussian->UpdateInformation(); gaussian->Update(); //MarchingCube -->create Surface vtkMarchingCubes *skinExtractor = vtkMarchingCubes::New(); skinExtractor->ReleaseDataFlagOn(); skinExtractor->SetInput(gaussian->GetOutput());//RC++ indexCoordinatesImageFilter->Delete(); skinExtractor->SetValue(0, 50); vtkPolyData *polydata; polydata = skinExtractor->GetOutput(); polydata->Register(NULL);//RC++ skinExtractor->Delete(); if (m_Smooth) { vtkSmoothPolyDataFilter *smoother = vtkSmoothPolyDataFilter::New(); //read poly1 (poly1 can be the original polygon, or the decimated polygon) smoother->SetInput(polydata);//RC++ smoother->SetNumberOfIterations( m_SmoothIteration ); smoother->SetRelaxationFactor( m_SmoothRelaxation ); smoother->SetFeatureAngle( 60 ); smoother->FeatureEdgeSmoothingOff(); smoother->BoundarySmoothingOff(); smoother->SetConvergence( 0 ); polydata->Delete();//RC-- polydata = smoother->GetOutput(); polydata->Register(NULL);//RC++ smoother->Delete(); } -// -//#if (VTK_MAJOR_VERSION >= 5) -// if (m_Decimate == Decimate ) -// { -// MITK_ERROR << "vtkDecimate not available for VTK 5.0 and above."; -// MITK_ERROR << " Using vtkDecimatePro instead." << std::endl; -// m_Decimate = DecimatePro; -// } -//#endif - //decimate = to reduce number of polygons if(m_Decimate==DecimatePro) { vtkDecimatePro *decimate = vtkDecimatePro::New(); decimate->SplittingOff(); decimate->SetErrorIsAbsolute(5); decimate->SetFeatureAngle(30); decimate->PreserveTopologyOn(); decimate->BoundaryVertexDeletionOff(); decimate->SetDegree(10); //std-value is 25! decimate->SetInput(polydata);//RC++ decimate->SetTargetReduction(m_TargetReduction); decimate->SetMaximumError(0.002); polydata->Delete();//RC-- polydata = decimate->GetOutput(); polydata->Register(NULL);//RC++ decimate->Delete(); } -#if (VTK_MAJOR_VERSION < 5) - else if (m_Decimate==Decimate) - { - vtkDecimate *decimate = vtkDecimate::New(); - decimate->SetInput( polydata ); - decimate->PreserveTopologyOn(); - decimate->BoundaryVertexDeletionOff(); - decimate->SetTargetReduction( m_TargetReduction ); - polydata->Delete();//RC-- - polydata = decimate->GetOutput(); - polydata->Register(NULL);//RC++ - decimate->Delete(); - } -#endif polydata->Update(); polydata->SetSource(NULL); if(polydata->GetNumberOfPoints() > 0) { mitk::Vector3D spacing = GetInput()->GetGeometry(time)->GetSpacing(); vtkPoints * points = polydata->GetPoints(); vtkMatrix4x4 *vtkmatrix = vtkMatrix4x4::New(); GetInput()->GetGeometry(time)->GetVtkTransform()->GetMatrix(vtkmatrix); double (*matrix)[4] = vtkmatrix->Element; unsigned int i,j; for(i=0;i<3;++i) for(j=0;j<3;++j) matrix[i][j]/=spacing[j]; unsigned int n = points->GetNumberOfPoints(); vtkFloatingPointType point[3]; for (i = 0; i < n; i++) { points->GetPoint(i, point); mitkVtkLinearTransformPoint(matrix,point,point); points->SetPoint(i, point); } vtkmatrix->Delete(); } surface->SetVtkPolyData(polydata, time); polydata->UnRegister(NULL); gaussian->Delete(); threshold->Delete(); } template < typename TPixel, unsigned int VImageDimension > void GetAvailableLabelsInternal( itk::Image* image, mitk::LabeledImageToSurfaceFilter::LabelMapType& availableLabels ) { typedef itk::Image ImageType; typedef itk::ImageRegionIterator< ImageType > ImageRegionIteratorType; availableLabels.clear(); ImageRegionIteratorType it( image, image->GetLargestPossibleRegion() ); it.GoToBegin(); mitk::LabeledImageToSurfaceFilter::LabelMapType::iterator labelIt; while( ! it.IsAtEnd() ) { labelIt = availableLabels.find( ( mitk::LabeledImageToSurfaceFilter::LabelType ) ( it.Get() ) ); if ( labelIt == availableLabels.end() ) { availableLabels[ ( mitk::LabeledImageToSurfaceFilter::LabelType ) ( it.Get() ) ] = 1; } else { labelIt->second += 1; } ++it; } } #define InstantiateAccessFunction_GetAvailableLabelsInternal(pixelType, dim) \ template void GetAvailableLabelsInternal(itk::Image*, mitk::LabeledImageToSurfaceFilter::LabelMapType&); InstantiateAccessFunctionForFixedDimension(GetAvailableLabelsInternal, 3); mitk::LabeledImageToSurfaceFilter::LabelMapType mitk::LabeledImageToSurfaceFilter::GetAvailableLabels() { mitk::Image::Pointer image = ( mitk::Image* )GetInput(); LabelMapType availableLabels; AccessFixedDimensionByItk_1( image, GetAvailableLabelsInternal, 3, availableLabels ); return availableLabels; } void mitk::LabeledImageToSurfaceFilter::CreateSurface(int, vtkImageData*, mitk::Surface*, const ScalarType) { itkWarningMacro( "This function should never be called!" ); assert(false); } mitk::LabeledImageToSurfaceFilter::LabelType mitk::LabeledImageToSurfaceFilter::GetLabelForNthOutput( const unsigned int& idx ) { IdxToLabelMapType::iterator it = m_IdxToLabels.find( idx ); if ( it != m_IdxToLabels.end() ) { return it->second; } else { itkWarningMacro( "Unknown index encountered: " << idx << ". There are " << this->GetNumberOfOutputs() << " outputs available." ); return itk::NumericTraits::max(); } } mitk::ScalarType mitk::LabeledImageToSurfaceFilter::GetVolumeForNthOutput( const unsigned int& i ) { return GetVolumeForLabel( GetLabelForNthOutput( i ) ); } mitk::ScalarType mitk::LabeledImageToSurfaceFilter::GetVolumeForLabel( const mitk::LabeledImageToSurfaceFilter::LabelType& label ) { // get the image spacing mitk::Image* image = ( mitk::Image* )GetInput(); const float* spacing = image->GetSlicedGeometry()->GetFloatSpacing(); // get the number of voxels encountered for the given label, // calculate the volume and return it. LabelMapType::iterator it = m_AvailableLabels.find( label ); if ( it != m_AvailableLabels.end() ) { return static_cast(it->second) * ( spacing[0] * spacing[1] * spacing[2] / 1000.0f ); } else { itkWarningMacro( "Unknown label encountered: " << label ); return 0.0; } } diff --git a/Modules/MitkExt/Algorithms/mitkMeshUtil.h b/Modules/MitkExt/Algorithms/mitkMeshUtil.h index 4fa212f484..4194c2caf6 100644 --- a/Modules/MitkExt/Algorithms/mitkMeshUtil.h +++ b/Modules/MitkExt/Algorithms/mitkMeshUtil.h @@ -1,1577 +1,1571 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef MITKMESHUTIL_H_INCLUDED #define MITKMESHUTIL_H_INCLUDED #if(_MSC_VER==1200) #error MeshUtils currently not supported for MS Visual C++ 6.0. Sorry. #endif //#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 template class NullScalarAccessor { public: static inline vtkFloatingPointType GetPointScalar(typename MeshType::PointDataContainer* /*pointData*/, typename MeshType::PointIdentifier /*idx*/, MeshType* /*mesh*/ = NULL, unsigned int /*type*/ = 0) { return (vtkFloatingPointType) 0.0; }; static inline vtkFloatingPointType GetCellScalar(typename MeshType::CellDataContainer* /*cellData*/, typename MeshType::CellIdentifier /*idx*/, MeshType* /*mesh*/ = NULL, unsigned int /*type*/ = 0) { return (vtkFloatingPointType) 0.0; }; }; template class MeshScalarAccessor { public: static inline vtkFloatingPointType GetPointScalar(typename MeshType::PointDataContainer* pointData, typename MeshType::PointIdentifier idx, MeshType* /*mesh*/ = NULL, unsigned int /*type*/ = 0) { return (vtkFloatingPointType)pointData->GetElement(idx); }; static inline vtkFloatingPointType GetCellScalar(typename MeshType::CellDataContainer* cellData, typename MeshType::CellIdentifier idx, MeshType* /*mesh*/ = NULL, unsigned int /*type*/ = 0) { return (vtkFloatingPointType)cellData->GetElement(idx); }; }; template class MeanCurvatureAccessor : public NullScalarAccessor { public: static inline vtkFloatingPointType GetPointScalar(typename MeshType::PointDataContainer* /*point*/, typename MeshType::PointIdentifier idx, MeshType* mesh, unsigned int /*type*/ = 0) { typename MeshType::PixelType dis = 0; mesh->GetPointData(idx, &dis); return (vtkFloatingPointType) dis; }; }; template class SimplexMeshAccessor : public NullScalarAccessor { public: static inline vtkFloatingPointType GetPointScalar(typename MeshType::PointDataContainer* point, typename MeshType::PointIdentifier idx, MeshType* mesh, unsigned int type = 0 ) { typename MeshType::GeometryMapPointer geometryData = mesh->GetGeometryData(); if (type == 0) { double val = mesh->GetMeanCurvature( idx ); mesh->SetPointData(idx, val); return val; } else if (type == 1) { double val = geometryData->GetElement(idx)->meanTension; mesh->SetPointData(idx, val); return val; } else if (type == 2) { double val = geometryData->GetElement(idx)->externalForce.GetNorm(); mesh->SetPointData(idx, val); return val; } else if (type == 3) return geometryData->GetElement(idx)->internalForce.GetNorm(); else if (type == 4) return geometryData->GetElement(idx)->externalForce.GetNorm() * mesh->GetDistance(idx); else if (type == 5) { typename MeshType::PixelType dis = 0; mesh->GetPointData(idx, &dis); return (vtkFloatingPointType) dis; } else if (type == 6) { return (vtkFloatingPointType) ((geometryData->GetElement(idx))->allowSplitting); } else return (vtkFloatingPointType) 0; }; }; /*! \brief The class provides mehtods for ITK - VTK mesh conversion * * \todo document the inner class * \todo maybe inner class should be moved out */ template > class MeshUtil { /*! \brief A visitor to create VTK cells by means of a class defining the InsertImplementation interface The InsertImplementation interface defines the methods \code void InsertLine(vtkIdType *pts); void InsertTriangle(vtkIdType *pts); void InsertPolygon(vtkIdType npts, vtkIdType *pts); void InsertQuad(vtkIdType *pts); void InsertTetra(vtkIdType *pts); void InsertHexahedron(vtkIdType *pts); \endcode This class calls the appropriate insert-method of the InsertImplementation according to the cell type of the visited cell \em and its actual contents: e.g., for a polygon cell with just two points, a line will be created by calling InsertLine. \sa ExactSwitchByCellType \sa SingleCellArrayInsertImplementation \sa DistributeInsertImplementation */ template class SwitchByCellType : public InsertImplementation { // typedef the itk cells we are interested in typedef typename itk::CellInterface< typename MeshType::CellPixelType, typename MeshType::CellTraits > CellInterfaceType; typedef itk::LineCell floatLineCell; typedef itk::TriangleCell floatTriangleCell; typedef itk::PolygonCell floatPolygonCell; typedef itk::QuadrilateralCell floatQuadrilateralCell; typedef itk::TetrahedronCell floatTetrahedronCell; typedef itk::HexahedronCell floatHexahedronCell; typedef typename CellInterfaceType::PointIdConstIterator PointIdIterator; public: /*! Visit a line and create the VTK_LINE cell */ void Visit(unsigned long cellId, floatLineCell* t) { vtkIdType pts[2]; int i=0; unsigned long num = t->GetNumberOfVertices(); vtkIdType vtkCellId = -1; if (num==2) { // useless because itk::LineCell always returns 2 for (PointIdIterator it=t->PointIdsBegin(); it!=t->PointIdsEnd(); it++) pts[i++] = *it; vtkCellId = this->InsertLine( (vtkIdType*)pts ); } if (this->m_UseCellScalarAccessor && vtkCellId >= 0) { this->m_CellScalars->InsertTuple1(vtkCellId, ScalarAccessor::GetCellScalar(this->m_CellData, cellId)); } } /*! Visit a polygon and create the VTK_POLYGON cell */ void Visit(unsigned long cellId, floatPolygonCell* t) { vtkIdType pts[4096]; int i=0; unsigned long num = t->GetNumberOfVertices(); vtkIdType vtkCellId = -1; if (num > 4096) { MITK_ERROR << "Problem in mitkMeshUtil: Polygon with more than maximum number of vertices encountered." << std::endl; } else if (num > 3) { for (PointIdIterator it=t->PointIdsBegin(); it!=t->PointIdsEnd(); it++) pts[i++] = *it; vtkCellId = this->InsertPolygon( num, (vtkIdType*)pts ); } else if (num == 3) { for (PointIdIterator it=t->PointIdsBegin(); it!=t->PointIdsEnd(); it++) pts[i++] = *it; vtkCellId = this->InsertTriangle( (vtkIdType*)pts ); } else if (num==2) { for (PointIdIterator it=t->PointIdsBegin(); it!=t->PointIdsEnd(); it++) pts[i++] = *it; vtkCellId = this->InsertLine( (vtkIdType*)pts ); } if (this->m_UseCellScalarAccessor && vtkCellId >= 0) { this->m_CellScalars->InsertTuple1(vtkCellId, ScalarAccessor::GetCellScalar(this->m_CellData, cellId)); } } /*! Visit a triangle and create the VTK_TRIANGLE cell */ void Visit(unsigned long cellId, floatTriangleCell* t) { vtkIdType pts[3]; int i=0; unsigned long num = t->GetNumberOfVertices(); vtkIdType vtkCellId = -1; if (num == 3) { for (PointIdIterator it=t->PointIdsBegin(); it!=t->PointIdsEnd(); it++) pts[i++] = *it; vtkCellId = this->InsertTriangle( (vtkIdType*)pts ); } else if (num==2) { for (PointIdIterator it=t->PointIdsBegin(); it!=t->PointIdsEnd(); it++) pts[i++] = *it; vtkCellId = this->InsertLine( (vtkIdType*)pts ); } if (this->m_UseCellScalarAccessor && vtkCellId >= 0) { this->m_CellScalars->InsertTuple1(vtkCellId, ScalarAccessor::GetCellScalar(this->m_CellData, cellId)); } } /*! Visit a quad and create the VTK_QUAD cell */ void Visit(unsigned long cellId, floatQuadrilateralCell* t) { vtkIdType pts[4]; int i=0; unsigned long num = t->GetNumberOfVertices(); vtkIdType vtkCellId = -1; if (num == 4) { for (PointIdIterator it=t->PointIdsBegin(); it!=t->PointIdsEnd(); it++) { if (i == 2) pts[3] = *it; else if (i == 3) pts[2] = *it; else pts[i] = *it; i++; //pts[i++] = *it; } vtkCellId = this->InsertQuad( (vtkIdType*)pts ); } else if (num == 3) { for (PointIdIterator it=t->PointIdsBegin(); it!=t->PointIdsEnd(); it++) pts[i++] = *it; vtkCellId = this->InsertTriangle( (vtkIdType*)pts ); } else if (num==2) { for (PointIdIterator it=t->PointIdsBegin(); it!=t->PointIdsEnd(); it++) pts[i++] = *it; vtkCellId = this->InsertLine( (vtkIdType*)pts ); } if (this->m_UseCellScalarAccessor && vtkCellId >= 0) { this->m_CellScalars->InsertTuple1(vtkCellId, ScalarAccessor::GetCellScalar(this->m_CellData, cellId)); } } /*! Visit a tetrahedra and create the VTK_TETRA cell */ void Visit(unsigned long cellId, floatTetrahedronCell* t) { vtkIdType pts[4]; int i=0; unsigned long num = t->GetNumberOfVertices(); vtkIdType vtkCellId = -1; if (num == 4) { for (PointIdIterator it=t->PointIdsBegin(); it!=t->PointIdsEnd(); it++) pts[i++] = *it; vtkCellId = this->InsertTetra( (vtkIdType*)pts ); } else if (num == 3) { for (PointIdIterator it=t->PointIdsBegin(); it!=t->PointIdsEnd(); it++) pts[i++] = *it; vtkCellId = this->InsertTriangle( (vtkIdType*)pts ); } else if (num==2) { for (PointIdIterator it=t->PointIdsBegin(); it!=t->PointIdsEnd(); it++) pts[i++] = *it; vtkCellId = this->InsertLine( (vtkIdType*)pts ); } if (this->m_UseCellScalarAccessor && vtkCellId >= 0) { this->m_CellScalars->InsertTuple1(vtkCellId, ScalarAccessor::GetCellScalar(this->m_CellData, cellId)); } } /*! Visit a hexahedron and create the VTK_HEXAHEDRON cell */ void Visit(unsigned long cellId, floatHexahedronCell* t) { vtkIdType pts[8]; int i=0; unsigned long num = t->GetNumberOfVertices(); vtkIdType vtkCellId = -1; if (num == 8) { for (PointIdIterator it=t->PointIdsBegin(); it!=t->PointIdsEnd(); it++) { if (i == 2) pts[i++] = *(it+1); else if (i == 3) pts[i++] = *(it-1); else if (i == 6) pts[i++] = *(it+1); else if (i == 7) pts[i++] = *(it-1); else pts[i++] = *it; } vtkCellId = this->InsertHexahedron( (vtkIdType*)pts ); } else if (num == 4) { for (PointIdIterator it=t->PointIdsBegin(); it!=t->PointIdsEnd(); it++) pts[i++] = *it; vtkCellId = this->InsertQuad( (vtkIdType*)pts ); } else if (num == 3) { for (PointIdIterator it=t->PointIdsBegin(); it!=t->PointIdsEnd(); it++) pts[i++] = *it; vtkCellId = this->InsertTriangle( (vtkIdType*)pts ); } else if (num==2) { for (PointIdIterator it=t->PointIdsBegin(); it!=t->PointIdsEnd(); it++) pts[i++] = *it; vtkCellId = this->InsertLine( (vtkIdType*)pts ); } if (this->m_UseCellScalarAccessor && vtkCellId >= 0) { this->m_CellScalars->InsertTuple1(vtkCellId, ScalarAccessor::GetCellScalar(this->m_CellData, cellId)); } } }; /*! \brief A visitor similar to SwitchByCellType, but with exact matching of cell types Works as described in SwitchByCellType, but does exact matching of cell types, e.g., for a polygon cell with just two points, \em no insert-method will be called, because a polygon must have at least three points. \sa SwitchByCellType \sa SingleCellArrayInsertImplementation \sa DistributeInsertImplementation */ template class ExactSwitchByCellType : public InsertImplementation { // typedef the itk cells we are interested in typedef typename itk::CellInterface< typename MeshType::CellPixelType, typename MeshType::CellTraits > CellInterfaceType; typedef itk::LineCell floatLineCell; typedef itk::TriangleCell floatTriangleCell; typedef itk::PolygonCell floatPolygonCell; typedef itk::QuadrilateralCell floatQuadrilateralCell; typedef itk::TetrahedronCell floatTetrahedronCell; typedef itk::HexahedronCell floatHexahedronCell; public: /*! Visit a line and create the VTK_LINE cell */ void Visit(unsigned long , floatLineCell* t) { unsigned long num = t->GetNumberOfVertices(); vtkIdType *pts = (vtkIdType*)t->PointIdsBegin(); if (num==2) this->InsertLine(pts); } /*! Visit a polygon and create the VTK_POLYGON cell */ void Visit(unsigned long , floatPolygonCell* t) { unsigned long num = t->GetNumberOfVertices(); vtkIdType *pts = (vtkIdType*)t->PointIdsBegin(); if (num > 3) this->InsertPolygon(num, pts); } /*! Visit a triangle and create the VTK_TRIANGLE cell */ void Visit(unsigned long , floatTriangleCell* t) { unsigned long num = t->GetNumberOfVertices(); vtkIdType *pts = (vtkIdType*)t->PointIdsBegin(); if (num == 3) this->InsertTriangle(pts); } /*! Visit a quadrilateral and create the VTK_QUAD cell */ void Visit(unsigned long , floatQuadrilateralCell* t) { unsigned long num = t->GetNumberOfVertices(); vtkIdType *pts = (vtkIdType*)t->PointIdsBegin(); if (num == 4) { vtkIdType tmpId = pts[3]; pts[3] = pts[4]; pts[4] = tmpId; this->InsertQuad(pts); } } /*! Visit a tetrahedron and create the VTK_TETRA cell */ void Visit(unsigned long , floatTetrahedronCell* t) { unsigned long num = t->GetNumberOfVertices(); vtkIdType *pts = (vtkIdType*)t->PointIdsBegin(); if (num == 4) this->InsertTetra(pts); } /*! Visit a hexahedron and create the VTK_HEXAHEDRON cell */ void Visit(unsigned long , floatHexahedronCell* t) { unsigned long num = t->GetNumberOfVertices(); vtkIdType *pts = (vtkIdType*)t->PointIdsBegin(); if (num == 8) { vtkIdType tmp[8]; for (unsigned int i = 0; i < 8; i++) tmp[i] = pts[i]; pts[2] = tmp[3]; pts[3] = tmp[2]; pts[6] = tmp[7]; pts[7] = tmp[6]; this->InsertHexahedron(pts); } } }; /*! \brief Implementation of the InsertImplementation interface of SwitchByCellType to define a visitor that create cells according to their types and put them in a single vtkCellArray (for vtkUnstructuredGrid construction) */ class SingleCellArrayInsertImplementation { vtkCellArray* m_Cells; int* m_TypeArray; //vtkIdType cellId; protected: bool m_UseCellScalarAccessor; vtkFloatArray* m_CellScalars; typename MeshType::CellDataContainer::Pointer m_CellData; public: SingleCellArrayInsertImplementation() : m_UseCellScalarAccessor(false) {} /*! Set the vtkCellArray that will be constructed */ void SetCellArray(vtkCellArray* cells) { m_Cells = cells; } /*! Set the type array for storing the vtk cell types */ void SetTypeArray(int* i) { m_TypeArray = i; } void SetUseCellScalarAccessor(bool flag) { m_UseCellScalarAccessor = flag; } void SetCellScalars(vtkFloatArray* scalars) { m_CellScalars = scalars; } vtkFloatArray* GetCellScalars() { return m_CellScalars; } void SetMeshCellData(typename MeshType::CellDataContainer* data) { m_CellData = data; } vtkIdType InsertLine(vtkIdType *pts) { vtkIdType cellId = m_Cells->InsertNextCell(2, pts); m_TypeArray[cellId] = VTK_LINE; return cellId; } vtkIdType InsertTriangle(vtkIdType *pts) { vtkIdType cellId = m_Cells->InsertNextCell(3, pts); m_TypeArray[cellId] = VTK_TRIANGLE; return cellId; } vtkIdType InsertPolygon(vtkIdType npts, vtkIdType *pts) { vtkIdType cellId = m_Cells->InsertNextCell(npts, pts); m_TypeArray[cellId] = VTK_POLYGON; return cellId; } vtkIdType InsertQuad(vtkIdType *pts) { vtkIdType cellId = m_Cells->InsertNextCell(4, pts); m_TypeArray[cellId] = VTK_QUAD; return cellId; } vtkIdType InsertTetra(vtkIdType *pts) { vtkIdType cellId = m_Cells->InsertNextCell(4, pts); m_TypeArray[cellId] = VTK_TETRA; return cellId; } vtkIdType InsertHexahedron(vtkIdType *pts) { vtkIdType cellId = m_Cells->InsertNextCell(8, pts); m_TypeArray[cellId] = VTK_HEXAHEDRON; return cellId; } }; /*! \brief Implementation of the InsertImplementation interface of SwitchByCellType to define a visitor that distributes cells according to their types (for vtkPolyData construction) */ class DistributeInsertImplementation { vtkCellArray* m_LineCells; vtkCellArray* m_TriangleCells; vtkCellArray* m_PolygonCells; vtkCellArray* m_QuadCells; protected: bool m_UseCellScalarAccessor; vtkFloatArray* m_CellScalars; typename MeshType::CellDataContainer::Pointer m_CellData; public: DistributeInsertImplementation() : m_UseCellScalarAccessor(false) {} /*! Set the vtkCellArray that will be constructed */ void SetCellArrays(vtkCellArray* lines, vtkCellArray* triangles, vtkCellArray* polygons, vtkCellArray* quads) { m_LineCells = lines; m_TriangleCells = triangles; m_PolygonCells = polygons; m_QuadCells = quads; } vtkIdType InsertLine(vtkIdType *pts) { return m_LineCells->InsertNextCell(2, pts); } vtkIdType InsertTriangle(vtkIdType *pts) { return m_TriangleCells->InsertNextCell(3, pts); } vtkIdType InsertPolygon(vtkIdType npts, vtkIdType *pts) { return m_PolygonCells->InsertNextCell(npts, pts); } vtkIdType InsertQuad(vtkIdType *pts) { return m_QuadCells->InsertNextCell(4, pts); } vtkIdType InsertTetra(vtkIdType *pts) { return -1; } // ignored vtkIdType InsertHexahedron(vtkIdType *pts) { return -1; } // ignored }; //typedef typename MeshType::CellType CellType; //typedef typename itk::LineCell< CellType > LineType; //typedef typename itk::PolygonCell< CellType > PolygonType; //typedef typename itk::TriangleCell< CellType > TriangleType; typedef SwitchByCellType SingleCellArrayUserVisitorType; typedef SwitchByCellType DistributeUserVisitorType; typedef ExactSwitchByCellType ExactUserVisitorType; public: typedef itk::MatrixOffsetTransformBase ITKTransformType; typedef itk::MatrixOffsetTransformBase MITKTransformType; /*! Convert a MITK transformation to an ITK transformation Necessary because ITK uses double and MITK uses float values */ static void ConvertTransformToItk(const MITKTransformType* mitkTransform, ITKTransformType* itkTransform) { typename MITKTransformType::MatrixType mitkM = mitkTransform->GetMatrix(); typename ITKTransformType::MatrixType itkM; typename MITKTransformType::OffsetType mitkO = mitkTransform->GetOffset(); typename ITKTransformType::OffsetType itkO; for(short i = 0; i < 3; ++i) { for(short j = 0; j<3; ++j) { itkM[i][j] = (double)mitkM[i][j]; } itkO[i] = (double)mitkO[i]; } itkTransform->SetMatrix(itkM); itkTransform->SetOffset(itkO); } /*! create an itkMesh object from a vtkPolyData */ static typename MeshType::Pointer MeshFromPolyData(vtkPolyData* poly, mitk::Geometry3D* geometryFrame=NULL, mitk::Geometry3D* polyDataGeometryFrame=NULL) { // Create a new mesh typename MeshType::Pointer output = MeshType::New(); output->SetCellsAllocationMethod( MeshType::CellsAllocatedDynamicallyCellByCell ); typedef typename MeshType::CellDataContainer MeshCellDataContainerType; output->SetCellData(MeshCellDataContainerType::New()); // Get the points from vtk vtkPoints* vtkpoints = poly->GetPoints(); const unsigned int numPoints = poly->GetNumberOfPoints(); // Create a compatible point container for the mesh // the mesh is created with a null points container // MeshType::PointsContainer::Pointer points = // MeshType::PointsContainer::New(); // // Resize the point container to be able to fit the vtk points // points->Reserve(numPoints); // // Set the point container on the mesh //output->SetPoints(points); vtkFloatingPointType vtkpoint[3]; typename MeshType::PointType itkPhysicalPoint; if(geometryFrame==NULL) { if(polyDataGeometryFrame==NULL) { for(unsigned int i=0; i < numPoints; ++i) { vtkpoints->GetPoint(i, vtkpoint); //MITK_INFO << "next point: " << test[0]<< "," << test[1] << "," << test[2] << std::endl; //typename MeshType::PixelType* apoint = (typename MeshType::PixelType*) vtkpoints->GetPoint(i); mitk::vtk2itk(vtkpoint, itkPhysicalPoint); output->SetPoint( i, itkPhysicalPoint ); } } else { for(unsigned int i=0; i < numPoints; ++i) { vtkpoints->GetPoint(i, vtkpoint); //MITK_INFO << "next point: " << test[0]<< "," << test[1] << "," << test[2] << std::endl; //typename MeshType::PixelType* apoint = (typename MeshType::PixelType*) vtkpoints->GetPoint(i); mitk::Point3D mitkWorldPoint; mitk::vtk2itk(vtkpoint, mitkWorldPoint); polyDataGeometryFrame->IndexToWorld(mitkWorldPoint, mitkWorldPoint); mitk::vtk2itk(mitkWorldPoint, itkPhysicalPoint); output->SetPoint( i, itkPhysicalPoint ); } } } else { mitk::Point3D mitkWorldPoint; if(polyDataGeometryFrame==NULL) { for(unsigned int i=0; i < numPoints; ++i) { vtkpoints->GetPoint(i, vtkpoint); //MITK_INFO << "next point: " << test[0]<< "," << test[1] << "," << test[2] << std::endl; //typename MeshType::PixelType* apoint = (typename MeshType::PixelType*) vtkpoints->GetPoint(i); mitk::vtk2itk(vtkpoint, mitkWorldPoint); geometryFrame->WorldToItkPhysicalPoint(mitkWorldPoint, itkPhysicalPoint); output->SetPoint( i, itkPhysicalPoint ); } } else { for(unsigned int i=0; i < numPoints; ++i) { vtkpoints->GetPoint(i, vtkpoint); //MITK_INFO << "next point: " << test[0]<< "," << test[1] << "," << test[2] << std::endl; //typename MeshType::PixelType* apoint = (typename MeshType::PixelType*) vtkpoints->GetPoint(i); mitk::vtk2itk(vtkpoint, mitkWorldPoint); polyDataGeometryFrame->IndexToWorld(mitkWorldPoint, mitkWorldPoint); geometryFrame->WorldToItkPhysicalPoint(mitkWorldPoint, itkPhysicalPoint); output->SetPoint( i, itkPhysicalPoint ); } } } vtkCellArray* vtkcells = poly->GetPolys(); // vtkCellArray* vtkcells = poly->GetStrips(); //MeshType::CellsContainerPointer cells = MeshType::CellsContainer::New(); //output->SetCells(cells); // extract the cell id's from the vtkUnstructuredGrid int numcells = vtkcells->GetNumberOfCells(); int* vtkCellTypes = new int[numcells]; int cellId = 0; // poly ids start after verts and lines! int cellIdOfs = poly->GetNumberOfVerts() + poly->GetNumberOfLines(); for(; cellId < numcells; cellId++) { vtkCellTypes[cellId] = poly->GetCellType( cellId+cellIdOfs ); } // cells->Reserve(numcells); vtkIdType npts; vtkIdType* pts; cellId = 0; typedef typename MeshType::MeshTraits OMeshTraits; typedef typename OMeshTraits::PixelType OPixelType; typedef typename MeshType::CellTraits CellTraits; typedef typename itk::CellInterface CellInterfaceType; typedef typename itk::TriangleCell TriCellType; typedef typename TriCellType::CellAutoPointer TriCellPointer; TriCellPointer newCell; output->GetCells()->Reserve( poly->GetNumberOfPolys() + poly->GetNumberOfStrips() ); output->GetCellData()->Reserve( poly->GetNumberOfPolys() + poly->GetNumberOfStrips() ); for(vtkcells->InitTraversal(); vtkcells->GetNextCell(npts, pts); cellId++) { switch(vtkCellTypes[cellId]) { case VTK_TRIANGLE: { if (npts != 3) continue; // skip non-triangles; unsigned long pointIds[3]; pointIds[0] = (unsigned long) pts[0]; pointIds[1] = (unsigned long) pts[1]; pointIds[2] = (unsigned long) pts[2]; newCell.TakeOwnership( new TriCellType ); newCell->SetPointIds(pointIds);//(unsigned long*)pts); output->SetCell(cellId, newCell ); output->SetCellData(cellId, (typename MeshType::PixelType)3); break; } case VTK_QUAD: { if (npts != 4 ) continue; // skip non-quadrilateral unsigned long pointIds[3]; pointIds[0] = (unsigned long) pts[0]; pointIds[1] = (unsigned long) pts[1]; pointIds[2] = (unsigned long) pts[2]; newCell.TakeOwnership( new TriCellType ); newCell->SetPointIds(pointIds); output->SetCell(cellId, newCell ); output->SetCellData(cellId, (typename MeshType::PixelType)3); cellId++; pointIds[0] = (unsigned long) pts[2]; pointIds[1] = (unsigned long) pts[3]; pointIds[2] = (unsigned long) pts[0]; newCell.TakeOwnership( new TriCellType ); newCell->SetPointIds(pointIds); output->SetCell(cellId, newCell ); output->SetCellData(cellId, (typename MeshType::PixelType)3); break; } case VTK_EMPTY_CELL: { if (npts != 3) { MITK_ERROR << "Only empty triangle cell supported by now..." << std::endl; // skip non-triangle empty cells; continue; } unsigned long pointIds[3]; pointIds[0] = (unsigned long) pts[0]; pointIds[1] = (unsigned long) pts[1]; pointIds[2] = (unsigned long) pts[2]; newCell.TakeOwnership( new TriCellType ); newCell->SetPointIds(pointIds); output->SetCell(cellId, newCell ); output->SetCellData(cellId, (typename MeshType::PixelType)3); break; } //case VTK_VERTEX: // If need to implement use //case VTK_POLY_VERTEX: // the poly->GetVerts() and //case VTK_LINE: // poly->GetLines() routines //case VTK_POLY_LINE: // outside of the switch..case. case VTK_POLYGON: case VTK_PIXEL: { if (npts != 4 ) continue;// skip non-quadrilateral unsigned long pointIds[3]; for ( unsigned int idx = 0; idx <= 1; idx++ ) { pointIds[0] = (unsigned long) pts[idx]; pointIds[1] = (unsigned long) pts[idx+1]; pointIds[2] = (unsigned long) pts[idx+2]; newCell.TakeOwnership( new TriCellType ); newCell->SetPointIds(pointIds); output->SetCell(cellId+idx, newCell ); output->SetCellData(cellId+idx, (typename MeshType::PixelType)3); } cellId++; break; } case VTK_TETRA: case VTK_VOXEL: case VTK_HEXAHEDRON: case VTK_WEDGE: case VTK_PYRAMID: case VTK_PARAMETRIC_CURVE: case VTK_PARAMETRIC_SURFACE: default: MITK_WARN << "Warning, unhandled cell type " << vtkCellTypes[cellId] << std::endl; } } if (poly->GetNumberOfStrips() != 0) { vtkcells = poly->GetStrips(); numcells = vtkcells->GetNumberOfCells(); vtkCellTypes = new int[numcells]; int stripId = 0; // strip ids start after verts, lines and polys! int stripIdOfs = poly->GetNumberOfVerts() + poly->GetNumberOfLines() + poly->GetNumberOfPolys(); for(; stripId < numcells; stripId++) { vtkCellTypes[stripId] = poly->GetCellType( stripId+stripIdOfs ); } stripId = 0; vtkcells->InitTraversal(); while( vtkcells->GetNextCell(npts, pts) ) { if (vtkCellTypes[stripId] != VTK_TRIANGLE_STRIP) { MITK_ERROR << "Only triangle strips supported!" << std::endl; continue; } stripId++; unsigned int numberOfTrianglesInStrip = npts - 2; unsigned long pointIds[3]; pointIds[0] = (unsigned long) pts[0]; pointIds[1] = (unsigned long) pts[1]; pointIds[2] = (unsigned long) pts[2]; for( unsigned int t=0; t < numberOfTrianglesInStrip; t++ ) { newCell.TakeOwnership( new TriCellType ); newCell->SetPointIds(pointIds); output->SetCell(cellId, newCell ); output->SetCellData(cellId, (typename MeshType::PixelType)3); cellId++; pointIds[0] = pointIds[1]; pointIds[1] = pointIds[2]; pointIds[2] = pts[t+3]; } } } //output->Print(std::cout); output->BuildCellLinks(); delete[] vtkCellTypes; return output; } /*! create an itkMesh object from an mitk::Surface */ static typename MeshType::Pointer MeshFromSurface(mitk::Surface* surface, mitk::Geometry3D* geometryFrame=NULL) { if(surface == NULL) return NULL; return MeshFromPolyData(surface->GetVtkPolyData(), geometryFrame, surface->GetGeometry()); } /*! create an vtkUnstructuredGrid object from an itkMesh */ static vtkUnstructuredGrid* MeshToUnstructuredGrid( MeshType* mesh, bool usePointScalarAccessor = false, bool useCellScalarAccessor = false, unsigned int pointDataType = 0, mitk::Geometry3D* geometryFrame=NULL) { /*! default SingleCellArray line cell visitior definition */ typedef typename itk::CellInterfaceVisitorImplementation, SingleCellArrayUserVisitorType> SingleCellArrayLineVisitor; /*! default SingleCellArray polygon cell visitior definition */ typedef typename itk::CellInterfaceVisitorImplementation, SingleCellArrayUserVisitorType> SingleCellArrayPolygonVisitor; /*! default SingleCellArray triangle cell visitior definition */ typedef typename itk::CellInterfaceVisitorImplementation >, SingleCellArrayUserVisitorType> SingleCellArrayTriangleVisitor; /*! default SingleCellArray quad cell visitior definition */ typedef typename itk::CellInterfaceVisitorImplementation >, SingleCellArrayUserVisitorType> SingleCellArrayQuadrilateralVisitor; /*! default SingleCellArray tetra cell visitior definition */ typedef typename itk::CellInterfaceVisitorImplementation >, SingleCellArrayUserVisitorType> SingleCellArrayTetrahedronVisitor; /*! default SingleCellArray hex cell visitior definition */ typedef typename itk::CellInterfaceVisitorImplementation >, SingleCellArrayUserVisitorType> SingleCellArrayHexahedronVisitor; // Get the number of points in the mesh int numPoints = mesh->GetNumberOfPoints(); if(numPoints == 0) { //mesh->Print(std::cerr); MITK_FATAL << "no points in Grid " << std::endl; exit(-1); } // Create a vtkUnstructuredGrid vtkUnstructuredGrid* vgrid = vtkUnstructuredGrid::New(); // Create the vtkPoints object and set the number of points -#if ((VTK_MAJOR_VERSION > 4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=4) )) vtkPoints* vpoints = vtkPoints::New( VTK_DOUBLE ); -#else - vtkPoints* vpoints = vtkPoints::New(); -#endif + vtkFloatArray* pointScalars = vtkFloatArray::New(); vtkFloatArray* cellScalars = vtkFloatArray::New(); pointScalars->SetNumberOfComponents(1); cellScalars->SetNumberOfComponents(1); typename MeshType::PointsContainer::Pointer points = mesh->GetPoints(); typename MeshType::PointsContainer::Iterator i; // iterate over all the points in the itk mesh to find // the maximal index unsigned int maxIndex = 0; for(i = points->Begin(); i != points->End(); ++i) { if(maxIndex < i->Index()) maxIndex = i->Index(); } // initialize vtk-classes for points and scalars vpoints->SetNumberOfPoints(maxIndex+1); pointScalars->SetNumberOfTuples(maxIndex+1); cellScalars->SetNumberOfTuples(mesh->GetNumberOfCells()); vtkFloatingPointType vtkpoint[3]; typename MeshType::PointType itkPhysicalPoint; if (geometryFrame == 0) { for(i = points->Begin(); i != points->End(); ++i) { // Get the point index from the point container iterator int idx = i->Index(); itkPhysicalPoint = i->Value(); mitk::itk2vtk(itkPhysicalPoint, vtkpoint); // Set the vtk point at the index with the the coord array from itk vpoints->SetPoint(idx, vtkpoint); if(usePointScalarAccessor) { pointScalars->InsertTuple1( idx, ScalarAccessor::GetPointScalar( mesh->GetPointData(), i->Index(), mesh, pointDataType ) ); } } } else { mitk::Point3D mitkWorldPoint; for(i = points->Begin(); i != points->End(); ++i) { // Get the point index from the point container iterator int idx = i->Index(); itkPhysicalPoint = i->Value(); geometryFrame->ItkPhysicalPointToWorld(itkPhysicalPoint, mitkWorldPoint); mitk::itk2vtk(mitkWorldPoint, vtkpoint); // Set the vtk point at the index with the the coord array from itk vpoints->SetPoint(idx, vtkpoint); if(usePointScalarAccessor) { pointScalars->InsertTuple1( idx, ScalarAccessor::GetPointScalar( mesh->GetPointData(), i->Index(), mesh, pointDataType ) ); } } } // Set the points on the vtk grid vgrid->SetPoints(vpoints); if (usePointScalarAccessor) vgrid->GetPointData()->SetScalars(pointScalars); // Now create the cells using the MultiVisitor // 1. Create a MultiVisitor typename MeshType::CellType::MultiVisitor::Pointer mv = MeshType::CellType::MultiVisitor::New(); // 2. Create visitors typename SingleCellArrayLineVisitor::Pointer lv = SingleCellArrayLineVisitor::New(); typename SingleCellArrayPolygonVisitor::Pointer pv = SingleCellArrayPolygonVisitor::New(); typename SingleCellArrayTriangleVisitor::Pointer tv = SingleCellArrayTriangleVisitor::New(); typename SingleCellArrayQuadrilateralVisitor::Pointer qv = SingleCellArrayQuadrilateralVisitor::New(); typename SingleCellArrayTetrahedronVisitor::Pointer tetv = SingleCellArrayTetrahedronVisitor::New(); typename SingleCellArrayHexahedronVisitor::Pointer hv = SingleCellArrayHexahedronVisitor::New(); // 3. Set up the visitors //int vtkCellCount = 0; // running counter for current cell being inserted into vtk int numCells = mesh->GetNumberOfCells(); int *types = new int[numCells]; // type array for vtk // create vtk cells and estimate the size vtkCellArray* cells = vtkCellArray::New(); cells->Allocate(numCells); // Set the TypeArray CellCount and CellArray for the visitors lv->SetTypeArray(types); lv->SetCellArray(cells); pv->SetTypeArray(types); pv->SetCellArray(cells); tv->SetTypeArray(types); //tv->SetCellCounter(&vtkCellCount); tv->SetCellArray(cells); qv->SetTypeArray(types); //qv->SetCellCounter(&vtkCellCount); qv->SetCellArray(cells); tetv->SetTypeArray(types); tetv->SetCellArray(cells); hv->SetTypeArray(types); hv->SetCellArray(cells); if (useCellScalarAccessor) { lv->SetUseCellScalarAccessor(true); lv->SetCellScalars(cellScalars); lv->SetMeshCellData(mesh->GetCellData()); pv->SetUseCellScalarAccessor(true); pv->SetCellScalars(cellScalars); pv->SetMeshCellData(mesh->GetCellData()); tv->SetUseCellScalarAccessor(true); tv->SetCellScalars(cellScalars); tv->SetMeshCellData(mesh->GetCellData()); qv->SetUseCellScalarAccessor(true); qv->SetCellScalars(cellScalars); qv->SetMeshCellData(mesh->GetCellData()); tetv->SetUseCellScalarAccessor(true); tetv->SetCellScalars(cellScalars); tetv->SetMeshCellData(mesh->GetCellData()); hv->SetUseCellScalarAccessor(true); hv->SetCellScalars(cellScalars); hv->SetMeshCellData(mesh->GetCellData()); } // add the visitors to the multivisitor mv->AddVisitor(lv); mv->AddVisitor(pv); mv->AddVisitor(tv); mv->AddVisitor(qv); mv->AddVisitor(tetv); mv->AddVisitor(hv); // Now ask the mesh to accept the multivisitor which // will Call Visit for each cell in the mesh that matches the // cell types of the visitors added to the MultiVisitor mesh->Accept(mv); // Now set the cells on the vtk grid with the type array and cell array vgrid->SetCells(types, cells); vgrid->GetCellData()->SetScalars(cellScalars); // Clean up vtk objects (no vtkSmartPointer ... ) cells->Delete(); vpoints->Delete(); delete[] types; pointScalars->Delete(); cellScalars->Delete(); //MITK_INFO << "meshToUnstructuredGrid end" << std::endl; return vgrid; } /*! create a vtkPolyData object from an itkMesh */ static vtkPolyData* MeshToPolyData(MeshType* mesh, bool onlyTriangles = false, bool useScalarAccessor = false, unsigned int pointDataType = 0, mitk::Geometry3D* geometryFrame=NULL, vtkPolyData* polydata = NULL) { /*! default Distribute line cell visitior definition */ typedef typename itk::CellInterfaceVisitorImplementation, DistributeUserVisitorType> DistributeLineVisitor; /*! default Distribute polygon cell visitior definition */ typedef typename itk::CellInterfaceVisitorImplementation, DistributeUserVisitorType> DistributePolygonVisitor; /*! default Distribute triangle cell visitior definition */ typedef typename itk::CellInterfaceVisitorImplementation >, DistributeUserVisitorType> DistributeTriangleVisitor; /*! default Distribute quad cell visitior definition */ typedef typename itk::CellInterfaceVisitorImplementation >, DistributeUserVisitorType> DistributeQuadrilateralVisitor; /*! default Distribute triangle cell visitior definition */ typedef typename itk::CellInterfaceVisitorImplementation >, ExactUserVisitorType> ExactTriangleVisitor; // Get the number of points in the mesh int numPoints = mesh->GetNumberOfPoints(); if(numPoints == 0) { //mesh->Print(std::cerr); MITK_ERROR << "no points in Grid " << std::endl; } // Create a vtkPolyData if(polydata == NULL) polydata = vtkPolyData::New(); else polydata->Initialize(); // Create the vtkPoints object and set the number of points -#if ((VTK_MAJOR_VERSION > 4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=4) )) vtkPoints* vpoints = vtkPoints::New( VTK_DOUBLE ); -#else - vtkPoints* vpoints = vtkPoints::New(); -#endif + vtkFloatArray * scalars = vtkFloatArray::New(); scalars->SetNumberOfComponents(1); typename MeshType::PointsContainer::Pointer points = mesh->GetPoints(); typename MeshType::PointsContainer::Iterator i; // iterate over all the points in the itk mesh to find // the maximal index unsigned int maxIndex = 0; for(i = points->Begin(); i != points->End(); ++i) { if(maxIndex < i->Index()) maxIndex = i->Index(); } // initialize vtk-classes for points and scalars vpoints->SetNumberOfPoints(maxIndex+1); scalars->SetNumberOfTuples(maxIndex+1); // iterate over all the points in the itk mesh filling in // the vtkPoints object as we go vtkFloatingPointType vtkpoint[3]; typename MeshType::PointType itkPhysicalPoint; if(geometryFrame==NULL) { for(i = points->Begin(); i != points->End(); ++i) { // Get the point index from the point container iterator int idx = i->Index(); itkPhysicalPoint = i->Value(); mitk::itk2vtk(itkPhysicalPoint, vtkpoint); // Set the vtk point at the index with the the coord array from itk // itk returns a const pointer, but vtk is not const correct, so // we have to use a const cast to get rid of the const // vpoints->SetPoint(idx, const_cast(i->Value().GetDataPointer())); vpoints->SetPoint(idx, vtkpoint); if(useScalarAccessor) { scalars->InsertTuple1( idx, ScalarAccessor::GetPointScalar( mesh->GetPointData(), i->Index(), mesh, pointDataType ) ); } } } else { mitk::Point3D mitkWorldPoint; for(i = points->Begin(); i != points->End(); ++i) { // Get the point index from the point container iterator int idx = i->Index(); itkPhysicalPoint = i->Value(); geometryFrame->ItkPhysicalPointToWorld(itkPhysicalPoint, mitkWorldPoint); mitk::itk2vtk(mitkWorldPoint, vtkpoint); // Set the vtk point at the index with the the coord array from itk // itk returns a const pointer, but vtk is not const correct, so // we have to use a const cast to get rid of the const // vpoints->SetPoint(idx, const_cast(i->Value().GetDataPointer())); vpoints->SetPoint(idx, vtkpoint); if(useScalarAccessor) { scalars->InsertTuple1( idx, ScalarAccessor::GetPointScalar( mesh->GetPointData(), i->Index(), mesh, pointDataType ) ); } } } // Set the points on the vtk grid polydata->SetPoints(vpoints); if (useScalarAccessor) polydata->GetPointData()->SetScalars(scalars); polydata->GetPointData()->CopyAllOn(); // Now create the cells using the MulitVisitor // 1. Create a MultiVisitor typedef typename MeshType::CellType::MultiVisitor MeshMV; typename MeshMV::Pointer mv = MeshMV::New(); int numCells = mesh->GetNumberOfCells(); if (onlyTriangles) { // create vtk cells and allocate vtkCellArray* trianglecells = vtkCellArray::New(); trianglecells->Allocate(numCells); // 2. Create a triangle visitor and add it to the multivisitor typename ExactTriangleVisitor::Pointer tv = ExactTriangleVisitor::New(); tv->SetCellArrays(NULL, trianglecells, NULL, NULL); mv->AddVisitor(tv); // 3. Now ask the mesh to accept the multivisitor which // will Call Visit for each cell in the mesh that matches the // cell types of the visitors added to the MultiVisitor mesh->Accept(mv); // 4. Set the result into our vtkPolyData if(trianglecells->GetNumberOfCells()>0) polydata->SetStrips(trianglecells); // 5. Clean up vtk objects (no vtkSmartPointer ... ) trianglecells->Delete(); } else { // create vtk cells and allocate vtkCellArray* linecells = vtkCellArray::New(); vtkCellArray* trianglecells = vtkCellArray::New(); vtkCellArray* polygoncells = vtkCellArray::New(); linecells->Allocate(numCells); trianglecells->Allocate(numCells); polygoncells->Allocate(numCells); // 2. Create visitors typename DistributeLineVisitor::Pointer lv = DistributeLineVisitor::New(); typename DistributePolygonVisitor::Pointer pv = DistributePolygonVisitor::New(); typename DistributeTriangleVisitor::Pointer tv = DistributeTriangleVisitor::New(); typename DistributeQuadrilateralVisitor::Pointer qv = DistributeQuadrilateralVisitor::New(); lv->SetCellArrays(linecells, trianglecells, polygoncells, polygoncells); pv->SetCellArrays(linecells, trianglecells, polygoncells, polygoncells); tv->SetCellArrays(linecells, trianglecells, polygoncells, polygoncells); qv->SetCellArrays(linecells, trianglecells, polygoncells, polygoncells); // add the visitors to the multivisitor mv->AddVisitor(tv); mv->AddVisitor(lv); mv->AddVisitor(pv); mv->AddVisitor(qv); // 3. Now ask the mesh to accept the multivisitor which // will Call Visit for each cell in the mesh that matches the // cell types of the visitors added to the MultiVisitor mesh->Accept(mv); // 4. Set the result into our vtkPolyData if(linecells->GetNumberOfCells()>0) polydata->SetLines(linecells); if(trianglecells->GetNumberOfCells()>0) polydata->SetStrips(trianglecells); if(polygoncells->GetNumberOfCells()>0) polydata->SetPolys(polygoncells); // 5. Clean up vtk objects (no vtkSmartPointer ... ) linecells->Delete(); trianglecells->Delete(); polygoncells->Delete(); } vpoints->Delete(); scalars->Delete(); //MITK_INFO << "meshToPolyData end" << std::endl; return polydata; } static typename MeshType::Pointer CreateRegularSphereMesh(typename MeshType::PointType center, typename MeshType::PointType::VectorType scale, int resolution) { typedef itk::RegularSphereMeshSource SphereSourceType; typename SphereSourceType::Pointer mySphereSource = SphereSourceType::New(); mySphereSource->SetCenter(center); mySphereSource->SetScale(scale); mySphereSource->SetResolution( resolution ); mySphereSource->Update(); typename MeshType::Pointer resultMesh = mySphereSource->GetOutput(); resultMesh->Register(); // necessary ???? return resultMesh; } static typename MeshType::Pointer CreateSphereMesh(typename MeshType::PointType center, typename MeshType::PointType scale, int* resolution) { typedef typename itk::SphereMeshSource SphereSource; typename SphereSource::Pointer mySphereSource = SphereSource::New(); mySphereSource->SetCenter(center); mySphereSource->SetScale(scale); mySphereSource->SetResolutionX(resolution[0]); mySphereSource->SetResolutionY(resolution[1]); mySphereSource->SetSquareness1(1); mySphereSource->SetSquareness2(1); mySphereSource->Update(); mySphereSource->GetOutput(); typename MeshType::Pointer resultMesh = mySphereSource->GetOutput(); resultMesh->Register(); return resultMesh; } // static typename MeshType::Pointer TranslateMesh(typename MeshType::PointType vec, MeshType* input) // { // // typename MeshType::Pointer output = MeshType::New(); // { // output->SetPoints(input->GetPoints()); // output->SetPointData(input->GetPointData()); // output->SetCells(input->GetCells()); // output->SetLastCellId( input->GetLastCellId() ); // typename MeshType::GeometryMapIterator pointDataIterator = input->GetGeometryData()->Begin(); // typename MeshType::GeometryMapIterator pointDataEnd = input->GetGeometryData()->End(); // // typename MeshType::PointType inputPoint,outputPoint; // // while (pointDataIterator != pointDataEnd) // { // unsigned long pointId = pointDataIterator->Index(); // itk::SimplexMeshGeometry* newGeometry = new itk::SimplexMeshGeometry(); // itk::SimplexMeshGeometry* refGeometry = pointDataIterator->Value(); // // input->GetPoint(pointId, &inputPoint ); // outputPoint[0] = inputPoint[0] + vec[0]; // outputPoint[1] = inputPoint[1] + vec[1]; // outputPoint[2] = inputPoint[2] + vec[2]; // output->SetPoint( pointId, outputPoint ); // // // newGeometry->pos = outputPoint; // newGeometry->neighborIndices = refGeometry->neighborIndices; // newGeometry->meanCurvature = refGeometry->meanCurvature; // newGeometry->neighbors = refGeometry->neighbors; // newGeometry->oldPos = refGeometry->oldPos; // newGeometry->eps = refGeometry->eps; // newGeometry->referenceMetrics = refGeometry->referenceMetrics; // newGeometry->neighborSet = refGeometry->neighborSet; // newGeometry->distance = refGeometry->distance; // newGeometry->externalForce = refGeometry->externalForce; // newGeometry->internalForce = refGeometry->internalForce; // output->SetGeometryData(pointId, newGeometry); // pointDataIterator++; // } // } //// output->SetGeometryData( inputMesh->GetGeometryData() ); // return output; // } static typename MeshType::Pointer CreateRegularSphereMesh2(typename MeshType::PointType center, typename MeshType::PointType scale, int resolution) { typedef typename itk::AutomaticTopologyMeshSource MeshSourceType; typename MeshSourceType::Pointer mySphereSource = MeshSourceType::New(); typename MeshType::PointType pnt0, pnt1, pnt2, pnt3, pnt4, pnt5, pnt6, pnt7, pnt8, pnt9, pnt10, pnt11; double c1= 0.5 * (1.0 + sqrt(5.0)); double c2= 1.0; double len = sqrt( c1*c1 + c2*c2 ); c1 /= len; c2 /= len; pnt0[0] = center[0] - c1*scale[0]; pnt0[1] = center[1]; pnt0[2] = center[2] + c2*scale[2]; pnt1[0] = center[0]; pnt1[1] = center[1] + c2*scale[1]; pnt1[2] = center[2] - c1*scale[2]; pnt2[0] = center[0]; pnt2[1] = center[1] + c2*scale[1]; pnt2[2] = center[2] + c1*scale[2]; pnt3[0] = center[0] + c1*scale[0]; pnt3[1] = center[1]; pnt3[2] = center[2] - c2*scale[2]; pnt4[0] = center[0] - c2*scale[0]; pnt4[1] = center[1] - c1*scale[1]; pnt4[2] = center[2]; pnt5[0] = center[0] - c2*scale[0]; pnt5[1] = center[1] + c1*scale[1]; pnt5[2] = center[2]; pnt6[0] = center[0]; pnt6[1] = center[1] - c2*scale[1]; pnt6[2] = center[2] + c1*scale[2]; pnt7[0] = center[0] + c2*scale[0]; pnt7[1] = center[1] + c1*scale[1]; pnt7[2] = center[2]; pnt8[0] = center[0]; pnt8[1] = center[1] - c2*scale[1]; pnt8[2] = center[2] - c1*scale[2]; pnt9[0] = center[0] + c1*scale[0]; pnt9[1] = center[1]; pnt9[2] = center[2] + c2*scale[2]; pnt10[0]= center[0] + c2*scale[0]; pnt10[1]= center[1] - c1*scale[1]; pnt10[2]= center[2]; pnt11[0]= center[0] - c1*scale[0]; pnt11[1]= center[1]; pnt11[2]= center[2] - c2*scale[2]; addTriangle( mySphereSource, scale, pnt9, pnt2, pnt6, resolution ); addTriangle( mySphereSource, scale, pnt1, pnt11, pnt5, resolution ); addTriangle( mySphereSource, scale, pnt11, pnt1, pnt8, resolution ); addTriangle( mySphereSource, scale, pnt0, pnt11, pnt4, resolution ); addTriangle( mySphereSource, scale, pnt3, pnt1, pnt7, resolution ); addTriangle( mySphereSource, scale, pnt3, pnt8, pnt1, resolution ); addTriangle( mySphereSource, scale, pnt9, pnt3, pnt7, resolution ); addTriangle( mySphereSource, scale, pnt0, pnt6, pnt2, resolution ); addTriangle( mySphereSource, scale, pnt4, pnt10, pnt6, resolution ); addTriangle( mySphereSource, scale, pnt1, pnt5, pnt7, resolution ); addTriangle( mySphereSource, scale, pnt7, pnt5, pnt2, resolution ); addTriangle( mySphereSource, scale, pnt8, pnt3, pnt10, resolution ); addTriangle( mySphereSource, scale, pnt4, pnt11, pnt8, resolution ); addTriangle( mySphereSource, scale, pnt9, pnt7, pnt2, resolution ); addTriangle( mySphereSource, scale, pnt10, pnt9, pnt6, resolution ); addTriangle( mySphereSource, scale, pnt0, pnt5, pnt11, resolution ); addTriangle( mySphereSource, scale, pnt0, pnt2, pnt5, resolution ); addTriangle( mySphereSource, scale, pnt8, pnt10, pnt4, resolution ); addTriangle( mySphereSource, scale, pnt3, pnt9, pnt10, resolution ); addTriangle( mySphereSource, scale, pnt6, pnt0, pnt4, resolution ); return mySphereSource->GetOutput(); } private: static void addTriangle( typename itk::AutomaticTopologyMeshSource::Pointer meshSource, typename MeshType::PointType scale, typename MeshType::PointType pnt0, typename MeshType::PointType pnt1, typename MeshType::PointType pnt2, int resolution ) { if (resolution==0) { // add triangle meshSource->AddTriangle( meshSource->AddPoint( pnt0 ), meshSource->AddPoint( pnt1 ), meshSource->AddPoint( pnt2 ) ); } else { vnl_vector_fixed v1, v2, res, pv; v1 = (pnt1-pnt0).Get_vnl_vector(); v2 = (pnt2-pnt0).Get_vnl_vector(); res = vnl_cross_3d( v1, v2 ); pv = pnt0.GetVectorFromOrigin().Get_vnl_vector(); //double d = res[0]*pv[0] + res[1]*pv[1] + res[2]*pv[2]; // subdivision typename MeshType::PointType pnt01, pnt12, pnt20; for (int d=0; d<3; d++) { pnt01[d] = (pnt0[d] + pnt1[d]) / 2.0; pnt12[d] = (pnt1[d] + pnt2[d]) / 2.0; pnt20[d] = (pnt2[d] + pnt0[d]) / 2.0; } // map new points to sphere double lenPnt01=0; for (int d=0; d<3; d++) lenPnt01 += pnt01[d]*pnt01[d]; lenPnt01 = sqrt( lenPnt01 ); double lenPnt12=0; for (int d=0; d<3; d++) lenPnt12 += pnt12[d]*pnt12[d]; lenPnt12 = sqrt( lenPnt12 ); double lenPnt20=0; for (int d=0; d<3; d++) lenPnt20 += pnt20[d]*pnt20[d]; lenPnt20 = sqrt( lenPnt20 ); for (int d=0; d<3; d++) { pnt01[d] *= scale[d]/lenPnt01; pnt12[d] *= scale[d]/lenPnt12; pnt20[d] *= scale[d]/lenPnt20; } addTriangle( meshSource, scale, pnt0, pnt01, pnt20, resolution-1 ); addTriangle( meshSource, scale, pnt01, pnt1, pnt12, resolution-1 ); addTriangle( meshSource, scale, pnt20, pnt12, pnt2, resolution-1 ); addTriangle( meshSource, scale, pnt01, pnt12, pnt20, resolution-1 ); } } }; #endif // MITKMESHUTIL_H_INCLUDED diff --git a/Modules/MitkExt/DataManagement/mitkExtrudedContour.cpp b/Modules/MitkExt/DataManagement/mitkExtrudedContour.cpp index 92630ea703..c2379ca4ba 100644 --- a/Modules/MitkExt/DataManagement/mitkExtrudedContour.cpp +++ b/Modules/MitkExt/DataManagement/mitkExtrudedContour.cpp @@ -1,402 +1,371 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkExtrudedContour.h" #include "mitkVector.h" #include "mitkBaseProcess.h" #include #include #include #include #include #include #include #include #include #include #include //vtkButterflySubdivisionFilter * subdivs; #include #include #include #include #include mitk::ExtrudedContour::ExtrudedContour() : m_Contour(NULL), m_ClippingGeometry(NULL), m_AutomaticVectorGeneration(false) { GetTimeSlicedGeometry()->Initialize(1); FillVector3D(m_Vector, 0.0, 0.0, 1.0); m_RightVector.Fill(0.0); m_ExtrusionFilter = vtkLinearExtrusionFilter::New(); m_ExtrusionFilter->CappingOff(); m_ExtrusionFilter->SetExtrusionTypeToVectorExtrusion(); -#if ((VTK_MAJOR_VERSION > 4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=4) )) double vtkvector[3]={0,0,1}; -#else - float vtkvector[3]={0,0,1}; -#endif + // set extrusion vector m_ExtrusionFilter->SetVector(vtkvector); m_TriangleFilter = vtkTriangleFilter::New(); m_TriangleFilter->SetInput(m_ExtrusionFilter->GetOutput()); m_SubdivisionFilter = vtkLinearSubdivisionFilter::New(); m_SubdivisionFilter->SetInput(m_TriangleFilter->GetOutput()); m_SubdivisionFilter->SetNumberOfSubdivisions(4); m_ClippingBox = vtkPlanes::New(); m_ClipPolyDataFilter = vtkClipPolyData::New(); m_ClipPolyDataFilter->SetInput(m_SubdivisionFilter->GetOutput()); m_ClipPolyDataFilter->SetClipFunction(m_ClippingBox); m_ClipPolyDataFilter->InsideOutOn(); m_Polygon = vtkPolygon::New(); m_ProjectionPlane = mitk::PlaneGeometry::New(); } mitk::ExtrudedContour::~ExtrudedContour() { m_ClipPolyDataFilter->Delete(); m_ClippingBox->Delete(); m_SubdivisionFilter->Delete(); m_TriangleFilter->Delete(); m_ExtrusionFilter->Delete(); m_Polygon->Delete(); } bool mitk::ExtrudedContour::IsInside(const Point3D& worldPoint) const { -#if ((VTK_MAJOR_VERSION > 4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=4) )) static double polygonNormal[3]={0.0,0.0,1.0}; -#else - static float polygonNormal[3]={0.0,0.0,1.0}; -#endif - // project point onto plane float xt[3]; itk2vtk(worldPoint, xt); xt[0] = worldPoint[0]-m_Origin[0]; xt[1] = worldPoint[1]-m_Origin[1]; xt[2] = worldPoint[2]-m_Origin[2]; float dist=xt[0]*m_Normal[0]+xt[1]*m_Normal[1]+xt[2]*m_Normal[2]; xt[0] -= dist*m_Normal[0]; xt[1] -= dist*m_Normal[1]; xt[2] -= dist*m_Normal[2]; -#if ((VTK_MAJOR_VERSION > 4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=4) )) - double x[3]; -#else - float x[3]; -#endif + double x[3]; x[0] = xt[0]*m_Right[0]+xt[1]*m_Right[1]+xt[2]*m_Right[2]; x[1] = xt[0]*m_Down[0] +xt[1]*m_Down[1] +xt[2]*m_Down[2]; x[2] = 0; -#if ((VTK_MAJOR_VERSION > 4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=4) )) // determine whether it's in the selection loop and then evaluate point // in polygon only if absolutely necessary. if ( x[0] >= this->m_ProjectedContourBounds[0] && x[0] <= this->m_ProjectedContourBounds[1] && x[1] >= this->m_ProjectedContourBounds[2] && x[1] <= this->m_ProjectedContourBounds[3] && this->m_Polygon->PointInPolygon(x, m_Polygon->Points->GetNumberOfPoints(), ((vtkDoubleArray *)this->m_Polygon->Points->GetData())->GetPointer(0), (double*)const_cast(this)->m_ProjectedContourBounds, polygonNormal) == 1 ) return true; else return false; -#else - // determine whether it's in the selection loop and then evaluate point - // in polygon only if absolutely necessary. - if ( x[0] >= this->m_ProjectedContourBounds[0] && x[0] <= this->m_ProjectedContourBounds[1] && - x[1] >= this->m_ProjectedContourBounds[2] && x[1] <= this->m_ProjectedContourBounds[3] && - this->m_Polygon->PointInPolygon(x, m_Polygon->Points->GetNumberOfPoints(), - ((vtkFloatArray *)this->m_Polygon->Points->GetData())->GetPointer(0), - const_cast(this)->m_ProjectedContourBounds, polygonNormal) == 1 ) - return true; - else - return false; -#endif } mitk::ScalarType mitk::ExtrudedContour::GetVolume() { return -1.0; } void mitk::ExtrudedContour::UpdateOutputInformation() { if ( this->GetSource() ) { this->GetSource()->UpdateOutputInformation(); } if(GetMTime() > m_LastCalculateExtrusionTime) { BuildGeometry(); BuildSurface(); } //if ( ( m_CalculateBoundingBox ) && ( m_PolyDataSeries.size() > 0 ) ) // CalculateBoundingBox(); } void mitk::ExtrudedContour::BuildSurface() { if(m_Contour.IsNull()) { SetVtkPolyData(NULL); return; } // set extrusion contour vtkPolyData *polyData = vtkPolyData::New(); vtkCellArray *polys = vtkCellArray::New(); polys->InsertNextCell(m_Polygon->GetPointIds()); polyData->SetPoints(m_Polygon->GetPoints()); //float vtkpoint[3]; //unsigned int i, numPts = m_Polygon->GetNumberOfPoints(); //for(i=0; im_Polygon->Points->GetPoint(i); // pointids[i]=loopPoints->InsertNextPoint(vtkpoint); //} //polys->InsertNextCell( i, pointids ); //delete [] pointids; //polyData->SetPoints( loopPoints ); polyData->SetPolys( polys ); polys->Delete(); m_ExtrusionFilter->SetInput(polyData); polyData->Delete(); // set extrusion scale factor m_ExtrusionFilter->SetScaleFactor(GetGeometry()->GetExtentInMM(2)); SetVtkPolyData(m_SubdivisionFilter->GetOutput()); //if(m_ClippingGeometry.IsNull()) //{ // SetVtkPolyData(m_SubdivisionFilter->GetOutput()); //} //else //{ // m_ClipPolyDataFilter->SetInput(m_SubdivisionFilter->GetOutput()); // mitk::BoundingBox::BoundsArrayType bounds=m_ClippingGeometry->GetBounds(); // m_ClippingBox->SetBounds(bounds[0], bounds[1], bounds[2], bounds[3], bounds[4], bounds[5]); // m_ClippingBox->SetTransform(GetGeometry()->GetVtkTransform()); // m_ClipPolyDataFilter->SetClipFunction(m_ClippingBox); // m_ClipPolyDataFilter->SetValue(0); // SetVtkPolyData(m_ClipPolyDataFilter->GetOutput()); //} m_LastCalculateExtrusionTime.Modified(); } void mitk::ExtrudedContour::BuildGeometry() { if(m_Contour.IsNull()) return; // Initialize(1); Vector3D nullvector; nullvector.Fill(0.0); float xProj[3]; unsigned int i; unsigned int numPts = 20; //m_Contour->GetNumberOfPoints(); mitk::Contour::PathPointer path = m_Contour->GetContourPath(); mitk::Contour::PathType::InputType cstart = path->StartOfInput(); mitk::Contour::PathType::InputType cend = path->EndOfInput(); mitk::Contour::PathType::InputType cstep = (cend-cstart)/numPts; mitk::Contour::PathType::InputType ccur; // Part I: guarantee/calculate legal vectors m_Vector.Normalize(); itk2vtk(m_Vector, m_Normal); // check m_Vector if(mitk::Equal(m_Vector, nullvector) || m_AutomaticVectorGeneration) { if ( m_AutomaticVectorGeneration == false) itkWarningMacro("Extrusion vector is 0 ("<< m_Vector << "); trying to use normal of polygon"); vtkPoints *loopPoints = vtkPoints::New(); //mitk::Contour::PointsContainerIterator pointsIt = m_Contour->GetPoints()->Begin(); -#if ((VTK_MAJOR_VERSION > 4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=4) )) double vtkpoint[3]; -#else - float vtkpoint[3]; -#endif + unsigned int i=0; for(i=0, ccur=cstart; iEvaluate(ccur), vtkpoint); loopPoints->InsertNextPoint(vtkpoint); } // Make sure points define a loop with a m_Normal vtkPolygon::ComputeNormal(loopPoints, m_Normal); loopPoints->Delete(); vtk2itk(m_Normal, m_Vector); if(mitk::Equal(m_Vector, nullvector)) { itkExceptionMacro("Cannot calculate normal of polygon"); } } // check m_RightVector if((mitk::Equal(m_RightVector, nullvector)) || (mitk::Equal(m_RightVector*m_Vector, 0.0)==false)) { if(mitk::Equal(m_RightVector, nullvector)) { itkDebugMacro("Right vector is 0. Calculating."); } else { itkWarningMacro("Right vector ("<InitializeStandardPlane(rightDV, downDV); // create vtkPolygon from contour and simultaneously determine 2D bounds of // contour projected on m_ProjectionPlane //mitk::Contour::PointsContainerIterator pointsIt = m_Contour->GetPoints()->Begin(); m_Polygon->Points->Reset(); m_Polygon->Points->SetNumberOfPoints(numPts); m_Polygon->PointIds->Reset(); m_Polygon->PointIds->SetNumberOfIds(numPts); mitk::Point2D pt2d; mitk::Point3D pt3d; mitk::Point2D min, max; min.Fill(ScalarTypeNumericTraits::max()); max.Fill(ScalarTypeNumericTraits::min()); xProj[2]=0.0; for(i=0, ccur=cstart; iEvaluate(ccur)); m_ProjectionPlane->Map(pt3d, pt2d); xProj[0]=pt2d[0]; if(pt2d[0]max[0]) max[0]=pt2d[0]; xProj[1]=pt2d[1]; if(pt2d[1]max[1]) max[1]=pt2d[1]; m_Polygon->Points->SetPoint(i, xProj); m_Polygon->PointIds->SetId(i, i); } // shift parametric origin to (0,0) for(i=0; i 4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=4) )) double * pt = this->m_Polygon->Points->GetPoint(i); -#else - float * pt = this->m_Polygon->Points->GetPoint(i); -#endif + pt[0]-=min[0]; pt[1]-=min[1]; itkDebugMacro( << i << ": (" << pt[0] << "," << pt[1] << "," << pt[2] << ")" ); } this->m_Polygon->GetBounds(m_ProjectedContourBounds); //m_ProjectedContourBounds[4]=-1.0; m_ProjectedContourBounds[5]=1.0; // calculate origin (except translation along the normal) and bounds // of m_ProjectionPlane: // origin is composed of the minimum x-/y-coordinates of the polygon, // bounds from the extent of the polygon, both after projecting on the plane mitk::Point3D origin; m_ProjectionPlane->Map(min, origin); ScalarType bounds[6]={0, max[0]-min[0], 0, max[1]-min[1], 0, 1}; m_ProjectionPlane->SetBounds(bounds); m_ProjectionPlane->SetOrigin(origin); // Part III: initialize geometry if(m_ClippingGeometry.IsNotNull()) { ScalarType min_dist=ScalarTypeNumericTraits::max(), max_dist=ScalarTypeNumericTraits::min(), dist; unsigned char i; for(i=0; i<8; ++i) { dist = m_ProjectionPlane->SignedDistance( m_ClippingGeometry->GetCornerPoint(i) ); if(distmax_dist) max_dist=dist; } //incorporate translation along the normal into origin origin = origin+m_Vector*min_dist; m_ProjectionPlane->SetOrigin(origin); bounds[5]=max_dist-min_dist; } else bounds[5]=20; itk2vtk(origin, m_Origin); mitk::TimeSlicedGeometry::Pointer timeGeometry = this->GetTimeSlicedGeometry(); mitk::Geometry3D::Pointer g3d = timeGeometry->GetGeometry3D( 0 ); assert( g3d.IsNotNull() ); g3d->SetBounds(bounds); g3d->SetIndexToWorldTransform(m_ProjectionPlane->GetIndexToWorldTransform()); g3d->TransferItkToVtkTransform(); timeGeometry->InitializeEvenlyTimed(g3d, 1); } unsigned long mitk::ExtrudedContour::GetMTime() const { unsigned long latestTime = Superclass::GetMTime(); if(m_Contour.IsNotNull()) { unsigned long localTime; localTime = m_Contour->GetMTime(); if(localTime > latestTime) latestTime = localTime; } return latestTime; } diff --git a/Modules/MitkExt/DataManagement/mitkMesh.h b/Modules/MitkExt/DataManagement/mitkMesh.h index 33b000b5d2..4161876cb7 100644 --- a/Modules/MitkExt/DataManagement/mitkMesh.h +++ b/Modules/MitkExt/DataManagement/mitkMesh.h @@ -1,141 +1,138 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef MITKMESH_H_HEADER_INCLUDED #define MITKMESH_H_HEADER_INCLUDED #include "mitkPointSet.h" #include "MitkExtExports.h" #include #include #include #include #include -#if (VTK_MAJOR_VERSION >= 5) + #include -#else -#include -#endif #include namespace mitk { /** * \brief DataStructure which stores a set of points (incl. pointdata) where * each point can be associated to an element of a cell. * * A mesh contains several cells that can be of different celltypes * (Line, Triangle, Polygone...). A cell is always closed. If a linestrip is * to be created, then declare several cells, each containing one line. * * The operations take care of the coherence. If a line is added to an * existing LineCell, then a TriangleCell is built with the old and the new * parameter (and so on). Deletion is done the opposite way. * * Example for inserting a line into a TriangleCell: * existing PIds ind the cell: 1, 2, 4; * inserting (2, 3) so that new PIds in Cell: 1, 2, 3, 4 * * The cell is now of type QuadrilateralCell * * \ingroup Data */ class MitkExt_EXPORT Mesh : public PointSet { public: mitkClassMacro(Mesh, PointSet); itkNewMacro(Self); typedef Superclass::DataType::CellType CellType; typedef CellType::CellAutoPointer CellAutoPointer; typedef Superclass::MeshTraits::CellTraits CellTraits; typedef CellTraits::PointIdConstIterator PointIdConstIterator; typedef CellTraits::PointIdIterator PointIdIterator; typedef DataType::CellDataContainer CellDataContainer; typedef DataType::CellDataContainerIterator CellDataIterator; typedef Superclass::DataType::CellsContainer::Iterator CellIterator; typedef Superclass::DataType::CellsContainer::ConstIterator ConstCellIterator; typedef itk::PolygonCell< CellType > PolygonType; typedef MeshType::CellType::MultiVisitor MeshMultiVisitor; /** \brief returns the current number of cells in the mesh */ virtual unsigned long GetNumberOfCells( int t = 0 ); /** \brief returns the mesh */ virtual const DataType *GetMesh( int t = 0 ) const; /** \brief returns the mesh */ virtual DataType *GetMesh( int t = 0 ); void SetMesh( DataType *mesh, int t = 0 ); /** \brief checks if the given point is in a cell and returns that cellId. * Basicaly it searches lines and points that are hit. */ virtual bool EvaluatePosition( Point3D point, unsigned long &cellId, float precision, int t = 0 ); /** \brief searches for the next new cellId and returns that id */ unsigned long GetNewCellId( int t = 0 ); /** \brief returns the first cell that includes the given pointId */ virtual int SearchFirstCell( unsigned long pointId, int t = 0 ); /** \brief searches for a line, that is hit by the given point. * Then returns the lineId and the cellId */ virtual bool SearchLine( Point3D point, float distance, unsigned long &lineId, unsigned long &cellId, int t = 0 ); /** \brief searches a line according to the cellId and lineId and returns * the PointIds, that assign the line; if successful, then return * param = true; */ virtual bool GetPointIds( unsigned long cellId, unsigned long lineId, int &idA, int &idB, int t = 0 ); /** \brief searches a selected cell and returns the id of that cell. If no * cell is found, then -1 is returned */ virtual int SearchSelectedCell( int t = 0 ); /** \brief creates a BoundingBox and computes it with the given points of * the cell. * * Returns the BoundingBox != IsNull() if successful. */ virtual DataType::BoundingBoxPointer GetBoundingBoxFromCell( unsigned long cellId, int t = 0 ); /** \brief executes the given Operation */ virtual void ExecuteOperation(Operation* operation); protected: Mesh(); virtual ~Mesh(); }; } // namespace mitk #endif /* MITKMESH_H_HEADER_INCLUDED */ diff --git a/Modules/MitkExt/IO/mitkVtkUnstructuredGridReader.cpp b/Modules/MitkExt/IO/mitkVtkUnstructuredGridReader.cpp index 38a936a1ea..696eb76fd0 100644 --- a/Modules/MitkExt/IO/mitkVtkUnstructuredGridReader.cpp +++ b/Modules/MitkExt/IO/mitkVtkUnstructuredGridReader.cpp @@ -1,130 +1,123 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision: 9496 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkVtkUnstructuredGridReader.h" #include #include #include -#if ((VTK_MAJOR_VERSION > 4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=4) )) #include -#endif + #include mitk::VtkUnstructuredGridReader::VtkUnstructuredGridReader() : m_FileName("") { } mitk::VtkUnstructuredGridReader::~VtkUnstructuredGridReader() { } void mitk::VtkUnstructuredGridReader::GenerateData() { if( m_FileName != "") { bool success = false; MITK_INFO << "Loading " << m_FileName << " as vtk unstructured grid" << std::endl; std::string ext = itksys::SystemTools::GetFilenameLastExtension(m_FileName); ext = itksys::SystemTools::LowerCase(ext); if (ext == ".vtk") { ///We create a Generic Reader to test de .vtk/ vtkDataReader *chooser=vtkDataReader::New(); chooser->SetFileName(m_FileName.c_str() ); if( chooser->IsFileUnstructuredGrid()) { ///UnstructuredGrid/ itkDebugMacro( << "UnstructuredGrid" ); vtkUnstructuredGridReader *reader = vtkUnstructuredGridReader::New(); reader->SetFileName( m_FileName.c_str() ); reader->Update(); if ( reader->GetOutput() != NULL ) { mitk::UnstructuredGrid::Pointer output = this->GetOutput(); output->SetVtkUnstructuredGrid( reader->GetOutput() ); success = true; } reader->Delete(); } } -#if ((VTK_MAJOR_VERSION > 4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=4) )) - else - if (ext == ".vtu") + else if (ext == ".vtu") { vtkXMLUnstructuredGridReader *reader=vtkXMLUnstructuredGridReader::New(); if( reader->CanReadFile(m_FileName.c_str()) ) { ///UnstructuredGrid/ itkDebugMacro( << "XMLUnstructuredGrid" ); reader->SetFileName( m_FileName.c_str() ); reader->Update(); if ( reader->GetOutput() != NULL ) { mitk::UnstructuredGrid::Pointer output = this->GetOutput(); output->SetVtkUnstructuredGrid( reader->GetOutput() ); success = true; } reader->Delete(); } } -#endif if(!success) { itkExceptionMacro( << " ... sorry, this .vtk format is not supported yet." ); } } } bool mitk::VtkUnstructuredGridReader::CanReadFile(const std::string filename, const std::string /*filePrefix*/, const std::string /*filePattern*/) { // First check the extension if( filename == "" ) return false; std::string ext = itksys::SystemTools::GetFilenameLastExtension(filename); ext = itksys::SystemTools::LowerCase(ext); if (ext == ".vtk") { vtkDataReader *chooser=vtkDataReader::New(); chooser->SetFileName(filename.c_str() ); if(!chooser->IsFileUnstructuredGrid()) { chooser->Delete(); return false; } } -#if ((VTK_MAJOR_VERSION > 4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=4) )) - else - if (ext == ".vtu") + else if (ext == ".vtu") { vtkXMLUnstructuredGridReader *chooser=vtkXMLUnstructuredGridReader::New(); if(!chooser->CanReadFile(filename.c_str())) { chooser->Delete(); return false; } } -#endif else return false; return true; } diff --git a/Modules/MitkExt/Interactions/mitkContourInteractor.cpp b/Modules/MitkExt/Interactions/mitkContourInteractor.cpp index 054dbfc191..8eaaf94a7a 100644 --- a/Modules/MitkExt/Interactions/mitkContourInteractor.cpp +++ b/Modules/MitkExt/Interactions/mitkContourInteractor.cpp @@ -1,188 +1,184 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkContourInteractor.h" #include //#include "ipSegmentation.h" //#include "mitkDataNode.h" #include #include #include #include #include #include #include #include #include #include mitk::ContourInteractor::ContourInteractor(const char * type, mitk::DataNode* dataNode) : mitk::Interactor(type, dataNode), m_Started(false) { assert(m_DataNode != NULL); m_DataNode->SetProperty("layer", mitk::IntProperty::New(100) ); m_DataNode->SetProperty("name", mitk::StringProperty::New("InteractiveFeedbackData") ); m_DataNode->SetOpacity(1); m_DataNode->SetColor(0.4,0.9,0.0); m_DataNode->SetProperty( "Width", mitk::FloatProperty::New(2.0) ); m_Started = false; } mitk::ContourInteractor::~ContourInteractor() { } //mitk::Contour::Pointer ContourInteractor::ExtractContour(mitkIpPicDescriptor* pic) //{ // int idx; // int size = _mitkIpPicElements (pic); // for (idx = 0; idx < size; idx++) // if ( ((mitkIpUInt1_t*) pic->data)[idx]> 0) break; // // int sizePoints; // size of the _points buffer (number of coordinate pairs that fit in) // int numPoints; // number of coordinate pairs stored in _points buffer // float *points = 0; // // points = ipSegmentationGetContour8N( pic, idx, numPoints, sizePoints, points ); // // mitk::Contour::Pointer contour = mitk::Contour::New(); // contour->Initialize(); // mitk::Point3D pointInMM, pointInUnits; // mitk::Point3D itkPoint; // for (int pointIdx = 0; pointIdx < numPoints; pointIdx++) // { // pointInUnits[0] = points[2*pointIdx]; // pointInUnits[1] = points[2*pointIdx+1]; // pointInUnits[2] = m_ZCoord; // m_SelectedImageGeometry->IndexToWorld(CorrectPointCoordinates(pointInUnits),pointInMM); // contour->AddVertex(pointInMM); // } // return contour; //} bool mitk::ContourInteractor::ExecuteAction(mitk::Action* action, mitk::StateEvent const* stateEvent) { mitk::Point3D eventPoint; const mitk::PositionEvent* posEvent = dynamic_cast(stateEvent->GetEvent()); if(posEvent==NULL) { const mitk::DisplayPositionEvent* displayPosEvent = dynamic_cast(stateEvent->GetEvent()); mitk::VtkPropRenderer* sender = (mitk::VtkPropRenderer*) stateEvent->GetEvent()->GetSender(); if((displayPosEvent == NULL) || (sender == NULL)) return false; eventPoint[0] = displayPosEvent->GetDisplayPosition()[0]; eventPoint[1] = displayPosEvent->GetDisplayPosition()[1]; eventPoint[2] = 0; -#if ((VTK_MAJOR_VERSION > 4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=4) )) - typedef itk::Point DoublePoint3D; - DoublePoint3D p; - p.CastFrom(eventPoint); - sender->GetVtkRenderer()->SetDisplayPoint(p.GetDataPointer()); -#else - sender->GetVtkRenderer()->SetDisplayPoint(eventPoint.GetDataPointer()); -#endif + typedef itk::Point DoublePoint3D; + DoublePoint3D p; + p.CastFrom(eventPoint); + sender->GetVtkRenderer()->SetDisplayPoint(p.GetDataPointer()); sender->GetVtkRenderer()->DisplayToWorld(); vtkFloatingPointType *vtkwp = sender->GetVtkRenderer()->GetWorldPoint(); vtk2itk(vtkwp, eventPoint); } else { eventPoint = posEvent->GetWorldPosition(); } bool ok = false; switch (action->GetActionId()) { case mitk::AcNEWPOINT: { Press(eventPoint); ok = true; m_Started = true; break; } case mitk::AcINITMOVEMENT: { if (m_Started) { Move(eventPoint); ok = true; break; } } case mitk::AcMOVEPOINT: { if (m_Started) { Move(eventPoint); ok = true; break; } } case mitk::AcFINISHMOVEMENT: { if (m_Started) { Release(eventPoint); ok = true; m_Started = false; } break; } default: ok = false; break; } return ok; } void mitk::ContourInteractor::Press(mitk::Point3D& point) { mitk::Contour* contour = dynamic_cast(m_DataNode->GetData()); assert(contour!=NULL); if (!m_Positive) m_DataNode->SetColor(1.0,0.0,0.0); contour->Initialize(); contour->AddVertex( point ); } void mitk::ContourInteractor::Move(mitk::Point3D& point) { mitk::Contour* contour = dynamic_cast(m_DataNode->GetData()); assert(contour!=NULL); contour->AddVertex( point ); // m_Parent->UpdateWidgets(); } void mitk::ContourInteractor::Release(mitk::Point3D& /*point*/) { //vermutlich m_Parent->UpdateWidgets(); } diff --git a/Modules/MitkExt/Interactions/mitkExtrudedContourInteractor.cpp b/Modules/MitkExt/Interactions/mitkExtrudedContourInteractor.cpp index ec87997cde..aeaf542208 100644 --- a/Modules/MitkExt/Interactions/mitkExtrudedContourInteractor.cpp +++ b/Modules/MitkExt/Interactions/mitkExtrudedContourInteractor.cpp @@ -1,209 +1,202 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkExtrudedContourInteractor.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include mitk::ExtrudedContourInteractor::ExtrudedContourInteractor(const char * type, mitk::DataNode* dataNode) : mitk::Interactor(type, dataNode), m_Started(false) { assert(m_DataNode != NULL); m_DataNode->SetProperty( "material.representation", mitk::VtkRepresentationProperty::New("surface") ); m_Contour = mitk::Contour::New(); m_ContourNode = mitk::DataNode::New(); m_ContourNode->SetData(m_Contour); m_ContourNode->SetProperty("layer", mitk::IntProperty::New(100) ); m_ContourNode->SetProperty("name", mitk::StringProperty::New("InteractiveFeedbackData") ); m_ContourNode->SetOpacity(1); m_ContourNode->SetColor(0.4,0.9,0.0); m_ContourNode->SetProperty( "Width", mitk::FloatProperty::New(2.0) ); m_Started = false; } mitk::ExtrudedContourInteractor::~ExtrudedContourInteractor() { } //mitk::Contour::Pointer ExtrudedContourInteractor::ExtractContour(mitkIpPicDescriptor* pic) //{ // int idx; // int size = _mitkIpPicElements (pic); // for (idx = 0; idx < size; idx++) // if ( ((mitkIpUInt1_t*) pic->data)[idx]> 0) break; // // int sizePoints; // size of the _points buffer (number of coordinate pairs that fit in) // int numPoints; // number of coordinate pairs stored in _points buffer // float *points = 0; // // points = ipSegmentationGetContour8N( pic, idx, numPoints, sizePoints, points ); // // mitk::Contour::Pointer m_Contour = mitk::Contour::New(); // m_Contour->Initialize(); // mitk::Point3D pointInMM, pointInUnits; // mitk::Point3D itkPoint; // for (int pointIdx = 0; pointIdx < numPoints; pointIdx++) // { // pointInUnits[0] = points[2*pointIdx]; // pointInUnits[1] = points[2*pointIdx+1]; // pointInUnits[2] = m_ZCoord; // m_SelectedImageGeometry->IndexToWorld(CorrectPointCoordinates(pointInUnits),pointInMM); // m_Contour->AddVertex(pointInMM); // } // return m_Contour; //} bool mitk::ExtrudedContourInteractor::ExecuteAction(mitk::Action* action, mitk::StateEvent const* stateEvent) { mitk::Point3D eventPoint; mitk::Vector3D eventPlaneNormal; const mitk::PositionEvent* posEvent = dynamic_cast(stateEvent->GetEvent()); if(posEvent==NULL) { const mitk::DisplayPositionEvent* displayPosEvent = dynamic_cast(stateEvent->GetEvent()); mitk::VtkPropRenderer* sender = (mitk::VtkPropRenderer*) stateEvent->GetEvent()->GetSender(); if((displayPosEvent == NULL) || (sender == NULL)) return false; eventPoint[0] = displayPosEvent->GetDisplayPosition()[0]; eventPoint[1] = displayPosEvent->GetDisplayPosition()[1]; eventPoint[2] = 0; -#if ((VTK_MAJOR_VERSION > 4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=4) )) typedef itk::Point DoublePoint3D; DoublePoint3D p; p.CastFrom(eventPoint); sender->GetVtkRenderer()->SetDisplayPoint(p.GetDataPointer()); -#else - sender->GetVtkRenderer()->SetDisplayPoint(eventPoint.GetDataPointer()); -#endif - sender->GetVtkRenderer()->DisplayToWorld(); + sender->GetVtkRenderer()->DisplayToWorld(); -#if ((VTK_MAJOR_VERSION > 4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=4) )) double *vtkwp = sender->GetVtkRenderer()->GetWorldPoint(); -#else - float *vtkwp = sender->GetVtkRenderer()->GetWorldPoint(); -#endif + vtk2itk(vtkwp, eventPoint); double *vtkvpn = sender->GetVtkRenderer()->GetActiveCamera()->GetViewPlaneNormal(); vtk2itk(vtkvpn, eventPlaneNormal); eventPlaneNormal = -eventPlaneNormal; } else { eventPoint = posEvent->GetWorldPosition(); mitk::BaseRenderer* sender = (mitk::BaseRenderer*) stateEvent->GetEvent()->GetSender(); eventPlaneNormal = sender->GetCurrentWorldGeometry2D()->GetAxisVector(2); } bool ok = false; switch (action->GetActionId()) { case mitk::AcNEWPOINT: { Press(eventPoint); ok = true; m_Started = true; break; } case mitk::AcINITMOVEMENT: { if (m_Started) { Move(eventPoint); ok = true; break; } } case mitk::AcMOVEPOINT: { if (m_Started) { Move(eventPoint); ok = true; break; } } case mitk::AcFINISHMOVEMENT: { if (m_Started) { mitk::ExtrudedContour* extrudedcontour = dynamic_cast(m_DataNode->GetData()); extrudedcontour->SetContour(m_Contour); extrudedcontour->SetVector(eventPlaneNormal); Release(eventPoint); ok = true; m_Started = false; InvokeEvent(itk::EndEvent()); } break; } default: ok = false; break; } return ok; } void mitk::ExtrudedContourInteractor::Press(mitk::Point3D& point) { if (!m_Positive) m_ContourNode->SetColor(1.0,0.0,0.0); m_Contour->Initialize(); m_Contour->AddVertex( point ); } void mitk::ExtrudedContourInteractor::Move(mitk::Point3D& point) { assert(m_Contour.IsNotNull()); m_Contour->AddVertex( point ); // m_Parent->UpdateWidgets(); } void mitk::ExtrudedContourInteractor::Release(mitk::Point3D& /*point*/) { //vermutlich m_Parent->UpdateWidgets(); } diff --git a/Modules/MitkExt/Rendering/mitkUnstructuredGridVtkMapper3D.cpp b/Modules/MitkExt/Rendering/mitkUnstructuredGridVtkMapper3D.cpp index ccfdd40d24..ca61550ffc 100644 --- a/Modules/MitkExt/Rendering/mitkUnstructuredGridVtkMapper3D.cpp +++ b/Modules/MitkExt/Rendering/mitkUnstructuredGridVtkMapper3D.cpp @@ -1,419 +1,417 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision: $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkUnstructuredGridVtkMapper3D.h" #include "mitkDataNode.h" #include "mitkProperties.h" #include "mitkTransferFunctionProperty.h" #include "mitkColorProperty.h" //#include "mitkLookupTableProperty.h" #include "mitkGridRepresentationProperty.h" #include "mitkGridVolumeMapperProperty.h" #include "mitkVtkInterpolationProperty.h" #include "mitkVtkScalarModeProperty.h" #include "mitkDataStorage.h" #include "mitkSurfaceVtkMapper3D.h" #include #include #include #include #include const mitk::UnstructuredGrid* mitk::UnstructuredGridVtkMapper3D::GetInput() { return static_cast ( GetData() ); } mitk::UnstructuredGridVtkMapper3D::UnstructuredGridVtkMapper3D() { m_VtkTriangleFilter = vtkDataSetTriangleFilter::New(); m_Assembly = vtkAssembly::New(); m_Volume = vtkVolume::New(); m_Actor = vtkActor::New(); m_ActorWireframe = vtkActor::New(); m_VtkDataSetMapper = vtkUnstructuredGridMapper::New(); m_VtkDataSetMapper->SetResolveCoincidentTopologyToPolygonOffset(); m_VtkDataSetMapper->SetResolveCoincidentTopologyPolygonOffsetParameters(0,1); m_Actor->SetMapper(m_VtkDataSetMapper); m_VtkDataSetMapper2 = vtkUnstructuredGridMapper::New(); m_VtkDataSetMapper2->SetResolveCoincidentTopologyToPolygonOffset(); m_VtkDataSetMapper2->SetResolveCoincidentTopologyPolygonOffsetParameters(1,1); m_ActorWireframe->SetMapper(m_VtkDataSetMapper2); m_ActorWireframe->GetProperty()->SetRepresentationToWireframe(); m_Assembly->AddPart(m_Actor); m_Assembly->AddPart(m_ActorWireframe); m_Assembly->AddPart(m_Volume); m_VtkVolumeRayCastMapper = 0; m_VtkPTMapper = 0; m_VtkVolumeZSweepMapper = 0; //m_GenerateNormals = false; } mitk::UnstructuredGridVtkMapper3D::~UnstructuredGridVtkMapper3D() { if (m_VtkTriangleFilter != 0) m_VtkTriangleFilter->Delete(); if (m_VtkVolumeRayCastMapper != 0) m_VtkVolumeRayCastMapper->Delete(); - #if (VTK_MAJOR_VERSION >= 5) if (m_VtkVolumeZSweepMapper != 0) m_VtkVolumeZSweepMapper->Delete(); if (m_VtkPTMapper != 0) m_VtkPTMapper->Delete(); - #endif if (m_VtkDataSetMapper != 0) m_VtkDataSetMapper->Delete(); if (m_VtkDataSetMapper2 != 0) m_VtkDataSetMapper2->Delete(); if (m_Assembly != 0) m_Assembly->Delete(); if (m_Actor != 0) m_Actor->Delete(); if (m_ActorWireframe != 0) m_ActorWireframe->Delete(); if (m_Volume != 0) m_Volume->Delete(); } vtkProp* mitk::UnstructuredGridVtkMapper3D::GetVtkProp(mitk::BaseRenderer* /*renderer*/) { return m_Assembly; } void mitk::UnstructuredGridVtkMapper3D::GenerateData() { m_Assembly->VisibilityOn(); m_ActorWireframe->GetProperty()->SetAmbient(1.0); m_ActorWireframe->GetProperty()->SetDiffuse(0.0); m_ActorWireframe->GetProperty()->SetSpecular(0.0); mitk::DataNode::ConstPointer node = this->GetDataNode(); mitk::TransferFunctionProperty::Pointer transferFuncProp; if (node->GetProperty(transferFuncProp, "TransferFunction")) { mitk::TransferFunction::Pointer transferFunction = transferFuncProp->GetValue(); if (transferFunction->GetColorTransferFunction()->GetSize() < 2) { mitk::UnstructuredGrid::Pointer input = const_cast< mitk::UnstructuredGrid* >(this->GetInput()); if (input.IsNull()) return; vtkUnstructuredGrid * grid = input->GetVtkUnstructuredGrid(this->GetTimestep()); if (grid == 0) return; double* scalarRange = grid->GetScalarRange(); vtkColorTransferFunction* colorFunc = transferFunction->GetColorTransferFunction(); colorFunc->RemoveAllPoints(); colorFunc->AddRGBPoint(scalarRange[0], 1, 0, 0); colorFunc->AddRGBPoint((scalarRange[0] + scalarRange[1])/2.0, 0, 1, 0); colorFunc->AddRGBPoint(scalarRange[1], 0, 0, 1); } } } void mitk::UnstructuredGridVtkMapper3D::GenerateData(mitk::BaseRenderer* renderer) { if(!IsVisible(renderer)) { m_Assembly->VisibilityOff(); return; } // // get the TimeSlicedGeometry of the input object // mitk::UnstructuredGrid::Pointer input = const_cast< mitk::UnstructuredGrid* >( this->GetInput() ); // // set the input-object at time t for the mapper // vtkUnstructuredGrid * grid = input->GetVtkUnstructuredGrid( this->GetTimestep() ); if(grid == 0) { m_Assembly->VisibilityOff(); return; } m_Assembly->VisibilityOn(); m_VtkTriangleFilter->SetInput(grid); m_VtkDataSetMapper->SetInput(grid); m_VtkDataSetMapper2->SetInput(grid); mitk::DataNode::ConstPointer node = this->GetDataNode(); bool clip = false; node->GetBoolProperty("enable clipping", clip); mitk::DataNode::Pointer bbNode = renderer->GetDataStorage()->GetNamedDerivedNode("Clipping Bounding Object", node); if (clip && bbNode.IsNotNull()) { m_VtkDataSetMapper->SetBoundingObject(dynamic_cast(bbNode->GetData())); m_VtkDataSetMapper2->SetBoundingObject(dynamic_cast(bbNode->GetData())); } else { m_VtkDataSetMapper->SetBoundingObject(0); m_VtkDataSetMapper2->SetBoundingObject(0); } // // apply properties read from the PropertyList // ApplyProperties(0, renderer); } void mitk::UnstructuredGridVtkMapper3D::ResetMapper( BaseRenderer* /*renderer*/ ) { m_Assembly->VisibilityOff(); } void mitk::UnstructuredGridVtkMapper3D::ApplyProperties(vtkActor* /*actor*/, mitk::BaseRenderer* renderer) { mitk::DataNode::Pointer node = this->GetDataNode(); Superclass::ApplyProperties(m_Actor, renderer); Superclass::ApplyProperties(m_ActorWireframe, renderer); vtkVolumeProperty* volProp = m_Volume->GetProperty(); vtkProperty* property = m_Actor->GetProperty(); vtkProperty* wireframeProp = m_ActorWireframe->GetProperty(); mitk::SurfaceVtkMapper3D::ApplyMitkPropertiesToVtkProperty(node,property,renderer); mitk::SurfaceVtkMapper3D::ApplyMitkPropertiesToVtkProperty(node,wireframeProp,renderer); mitk::TransferFunctionProperty::Pointer transferFuncProp; if (node->GetProperty(transferFuncProp, "TransferFunction", renderer)) { mitk::TransferFunction::Pointer transferFunction = transferFuncProp->GetValue(); volProp->SetColor(transferFunction->GetColorTransferFunction()); volProp->SetScalarOpacity(transferFunction->GetScalarOpacityFunction()); volProp->SetGradientOpacity(transferFunction->GetGradientOpacityFunction()); m_VtkDataSetMapper->SetLookupTable(transferFunction->GetColorTransferFunction()); m_VtkDataSetMapper2->SetLookupTable(transferFunction->GetColorTransferFunction()); } bool isVolumeRenderingOn = false; node->GetBoolProperty("volumerendering", isVolumeRenderingOn, renderer); if (isVolumeRenderingOn) { m_Assembly->RemovePart(m_Actor); m_Assembly->RemovePart(m_ActorWireframe); m_Assembly->AddPart(m_Volume); mitk::GridVolumeMapperProperty::Pointer mapperProp; if (node->GetProperty(mapperProp, "volumerendering.mapper", renderer)) { mitk::GridVolumeMapperProperty::IdType type = mapperProp->GetValueAsId(); switch (type) { case mitk::GridVolumeMapperProperty::RAYCAST: if (m_VtkVolumeRayCastMapper == 0) { m_VtkVolumeRayCastMapper = vtkUnstructuredGridVolumeRayCastMapper::New(); m_VtkVolumeRayCastMapper->SetInput(m_VtkTriangleFilter->GetOutput()); } m_Volume->SetMapper(m_VtkVolumeRayCastMapper); break; case mitk::GridVolumeMapperProperty::PT: if (m_VtkPTMapper == 0) { m_VtkPTMapper = vtkProjectedTetrahedraMapper::New(); m_VtkPTMapper->SetInputConnection(m_VtkTriangleFilter->GetOutputPort()); } m_Volume->SetMapper(m_VtkPTMapper); break; case mitk::GridVolumeMapperProperty::ZSWEEP: if (m_VtkVolumeZSweepMapper == 0) { m_VtkVolumeZSweepMapper = vtkUnstructuredGridVolumeZSweepMapper::New(); m_VtkVolumeZSweepMapper->SetInputConnection(m_VtkTriangleFilter->GetOutputPort()); } m_Volume->SetMapper(m_VtkVolumeZSweepMapper); break; } } } else { m_Assembly->RemovePart(m_Volume); m_Assembly->AddPart(m_Actor); m_Assembly->RemovePart(m_ActorWireframe); mitk::GridRepresentationProperty::Pointer gridRepProp; if (node->GetProperty(gridRepProp, "grid representation", renderer)) { mitk::GridRepresentationProperty::IdType type = gridRepProp->GetValueAsId(); switch (type) { case mitk::GridRepresentationProperty::POINTS: property->SetRepresentationToPoints(); break; case mitk::GridRepresentationProperty::WIREFRAME: property->SetRepresentationToWireframe(); break; case mitk::GridRepresentationProperty::SURFACE: property->SetRepresentationToSurface(); break; } // if (type == mitk::GridRepresentationProperty::WIREFRAME_SURFACE) // { // m_Assembly->AddPart(m_ActorWireframe); // } } } // mitk::LevelWindow levelWindow; // if(node->GetLevelWindow(levelWindow, renderer, "levelWindow")) // { // m_VtkVolumeRayCastMapper->SetScalarRange(levelWindow.GetMin(),levelWindow.GetMax()); // } // else // if(node->GetLevelWindow(levelWindow, renderer)) // { // m_VtkVolumeRayCastMapper->SetScalarRange(levelWindow.GetMin(),levelWindow.GetMax()); // } // // mitk::VtkRepresentationProperty* representationProperty; // node->GetProperty(representationProperty, "material.representation", renderer); // if ( representationProperty != NULL ) // m_Volume->GetProperty()->SetRepresentation( representationProperty->GetVtkRepresentation() ); // // mitk::VtkInterpolationProperty* interpolationProperty; // node->GetProperty(interpolationProperty, "material.interpolation", renderer); // if ( interpolationProperty != NULL ) // m_Volume->GetProperty()->SetInterpolation( interpolationProperty->GetVtkInterpolation() ); // mitk::VtkScalarModeProperty* scalarMode = 0; if(node->GetProperty(scalarMode, "scalar mode", renderer)) { if (m_VtkVolumeRayCastMapper) m_VtkVolumeRayCastMapper->SetScalarMode(scalarMode->GetVtkScalarMode()); if (m_VtkPTMapper) m_VtkPTMapper->SetScalarMode(scalarMode->GetVtkScalarMode()); if (m_VtkVolumeZSweepMapper) m_VtkVolumeZSweepMapper->SetScalarMode(scalarMode->GetVtkScalarMode()); m_VtkDataSetMapper->SetScalarMode(scalarMode->GetVtkScalarMode()); m_VtkDataSetMapper2->SetScalarMode(scalarMode->GetVtkScalarMode()); } else { if (m_VtkVolumeRayCastMapper) m_VtkVolumeRayCastMapper->SetScalarModeToDefault(); if (m_VtkPTMapper) m_VtkPTMapper->SetScalarModeToDefault(); if (m_VtkVolumeZSweepMapper) m_VtkVolumeZSweepMapper->SetScalarModeToDefault(); m_VtkDataSetMapper->SetScalarModeToDefault(); m_VtkDataSetMapper2->SetScalarModeToDefault(); } bool scalarVisibility = true; node->GetBoolProperty("scalar visibility", scalarVisibility, renderer); m_VtkDataSetMapper->SetScalarVisibility(scalarVisibility ? 1 : 0); m_VtkDataSetMapper2->SetScalarVisibility(scalarVisibility ? 1 : 0); // double scalarRangeLower = std::numeric_limits::min(); // double scalarRangeUpper = std::numeric_limits::max(); // mitk::DoubleProperty* lowerRange = 0; // if (node->GetProperty(lowerRange, "scalar range min", renderer)) // { // scalarRangeLower = lowerRange->GetValue(); // } // mitk::DoubleProperty* upperRange = 0; // if (node->GetProperty(upperRange, "scalar range max", renderer)) // { // scalarRangeUpper = upperRange->GetValue(); // } // m_VtkDataSetMapper->SetScalarRange(scalarRangeLower, scalarRangeUpper); // m_VtkDataSetMapper2->SetScalarRange(scalarRangeLower, scalarRangeUpper); // bool colorMode = false; // node->GetBoolProperty("color mode", colorMode); // m_VtkVolumeRayCastMapper->SetColorMode( (colorMode ? 1 : 0) ); // float scalarsMin = 0; // if (dynamic_cast(node->GetProperty("ScalarsRangeMinimum").GetPointer()) != NULL) // scalarsMin = dynamic_cast(node->GetProperty("ScalarsRangeMinimum").GetPointer())->GetValue(); // float scalarsMax = 1.0; // if (dynamic_cast(node->GetProperty("ScalarsRangeMaximum").GetPointer()) != NULL) // scalarsMax = dynamic_cast(node->GetProperty("ScalarsRangeMaximum").GetPointer())->GetValue(); // m_VtkVolumeRayCastMapper->SetScalarRange(scalarsMin,scalarsMax); } void mitk::UnstructuredGridVtkMapper3D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { SurfaceVtkMapper3D::SetDefaultPropertiesForVtkProperty(node, renderer, overwrite); node->AddProperty("grid representation", GridRepresentationProperty::New(), renderer, overwrite); node->AddProperty("volumerendering", BoolProperty::New(false), renderer, overwrite); node->AddProperty("volumerendering.mapper", GridVolumeMapperProperty::New(), renderer, overwrite); node->AddProperty("scalar mode", VtkScalarModeProperty::New(0), renderer, overwrite); node->AddProperty("scalar visibility", BoolProperty::New(true), renderer, overwrite); //node->AddProperty("scalar range min", DoubleProperty::New(std::numeric_limits::min()), renderer, overwrite); //node->AddProperty("scalar range max", DoubleProperty::New(std::numeric_limits::max()), renderer, overwrite); node->AddProperty("outline polygons", BoolProperty::New(false), renderer, overwrite); node->AddProperty("color", ColorProperty::New(1.0f, 1.0f, 1.0f), renderer, overwrite); node->AddProperty("line width", IntProperty::New(1), renderer, overwrite); if(overwrite || node->GetProperty("TransferFunction", renderer) == 0) { // add a default transfer function mitk::TransferFunction::Pointer tf = mitk::TransferFunction::New(); //tf->GetColorTransferFunction()->RemoveAllPoints(); node->SetProperty ("TransferFunction", mitk::TransferFunctionProperty::New(tf.GetPointer())); } Superclass::SetDefaultProperties(node, renderer, overwrite); } diff --git a/Modules/MitkExt/Rendering/mitkUnstructuredGridVtkMapper3D.h b/Modules/MitkExt/Rendering/mitkUnstructuredGridVtkMapper3D.h index 2f2472ecd4..465a77758b 100644 --- a/Modules/MitkExt/Rendering/mitkUnstructuredGridVtkMapper3D.h +++ b/Modules/MitkExt/Rendering/mitkUnstructuredGridVtkMapper3D.h @@ -1,93 +1,92 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision: $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _MITK_UNSTRUCTURED_GRID_VTK_MAPPER_3D_H_ #define _MITK_UNSTRUCTURED_GRID_VTK_MAPPER_3D_H_ #include "mitkCommon.h" #include "MitkExtExports.h" #include "mitkVtkMapper3D.h" #include "mitkUnstructuredGrid.h" #include "mitkBaseRenderer.h" #include #include #include #include #include "vtkUnstructuredGridMapper.h" #include -#if (VTK_MAJOR_VERSION >= 5) - #include - #include -#endif +#include +#include + namespace mitk { //##Documentation //## @brief Vtk-based mapper for UnstructuredGrid //## //## @ingroup Mapper class MitkExt_EXPORT UnstructuredGridVtkMapper3D : public VtkMapper3D { public: mitkClassMacro(UnstructuredGridVtkMapper3D, VtkMapper3D); itkNewMacro(Self); virtual const mitk::UnstructuredGrid* GetInput(); virtual vtkProp* GetVtkProp(mitk::BaseRenderer* renderer); static void SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer = NULL, bool overwrite = false); void ApplyProperties(vtkActor* /*actor*/, mitk::BaseRenderer* renderer); protected: UnstructuredGridVtkMapper3D(); virtual ~UnstructuredGridVtkMapper3D(); virtual void GenerateData(); virtual void GenerateData(mitk::BaseRenderer* renderer); virtual void ResetMapper( BaseRenderer* /*renderer*/ ); void SetProperties(mitk::BaseRenderer* renderer); vtkAssembly* m_Assembly; vtkActor* m_Actor; vtkActor* m_ActorWireframe; vtkVolume* m_Volume; vtkDataSetTriangleFilter* m_VtkTriangleFilter; vtkUnstructuredGridMapper* m_VtkDataSetMapper; vtkUnstructuredGridMapper* m_VtkDataSetMapper2; vtkUnstructuredGridVolumeRayCastMapper* m_VtkVolumeRayCastMapper; vtkProjectedTetrahedraMapper* m_VtkPTMapper; vtkUnstructuredGridVolumeZSweepMapper* m_VtkVolumeZSweepMapper; }; } // namespace mitk #endif /* _MITK_UNSTRUCTURED_GRID_VTK_MAPPER_3D_H_ */ diff --git a/Modules/SceneSerializationBase/BasePropertySerializer/mitkLookupTablePropertySerializer.cpp b/Modules/SceneSerializationBase/BasePropertySerializer/mitkLookupTablePropertySerializer.cpp index e51ba4e5d8..a732d7b1e9 100644 --- a/Modules/SceneSerializationBase/BasePropertySerializer/mitkLookupTablePropertySerializer.cpp +++ b/Modules/SceneSerializationBase/BasePropertySerializer/mitkLookupTablePropertySerializer.cpp @@ -1,228 +1,217 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision: 1.12 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef mitkLookupTablePropertySerializer_h_included #define mitkLookupTablePropertySerializer_h_included #include "mitkBasePropertySerializer.h" #include "mitkLookupTableProperty.h" #include "SceneSerializationBaseExports.h" namespace mitk { class SceneSerializationBase_EXPORT LookupTablePropertySerializer : public BasePropertySerializer { public: mitkClassMacro( LookupTablePropertySerializer, BasePropertySerializer ); itkNewMacro(Self); virtual TiXmlElement* Serialize() { if (const LookupTableProperty* prop = dynamic_cast(m_Property.GetPointer())) { LookupTable::Pointer mitkLut = const_cast(prop)->GetLookupTable(); if (mitkLut.IsNull()) return NULL; // really? vtkLookupTable* lut = mitkLut->GetVtkLookupTable(); if (!lut) return NULL; TiXmlElement* element = new TiXmlElement("LookupTable"); -#if ( (VTK_MAJOR_VERSION < 5) && (VTK_MINOR_VERSION < 4) ) - float* range; - float* rgba; -#else double* range; double* rgba; -#endif element->SetAttribute("NumberOfColors", lut->GetNumberOfTableValues()); element->SetAttribute("Scale", lut->GetScale()); element->SetAttribute("Ramp", lut->GetRamp()); range = lut->GetHueRange(); TiXmlElement* child = new TiXmlElement("HueRange"); element->LinkEndChild( child ); child->SetDoubleAttribute("min", range[0]); child->SetDoubleAttribute("max", range[1]); range = lut->GetValueRange(); child = new TiXmlElement("ValueRange"); element->LinkEndChild( child ); child->SetDoubleAttribute("min", range[0]); child->SetDoubleAttribute("max", range[1]); range = lut->GetSaturationRange(); child = new TiXmlElement("SaturationRange"); element->LinkEndChild( child ); child->SetDoubleAttribute("min", range[0]); child->SetDoubleAttribute("max", range[1]); range = lut->GetAlphaRange(); child = new TiXmlElement("AlphaRange"); element->LinkEndChild( child ); child->SetDoubleAttribute("min", range[0]); child->SetDoubleAttribute("max", range[1]); range = lut->GetTableRange(); child = new TiXmlElement("TableRange"); element->LinkEndChild( child ); child->SetDoubleAttribute("min", range[0]); child->SetDoubleAttribute("max", range[1]); child = new TiXmlElement("Table"); element->LinkEndChild( child ); for ( int index = 0; index < lut->GetNumberOfTableValues(); ++index) { TiXmlElement* grandChildNinife = new TiXmlElement("RgbaColor"); rgba = lut->GetTableValue(index); grandChildNinife->SetDoubleAttribute("R", rgba[0]); grandChildNinife->SetDoubleAttribute("G", rgba[1]); grandChildNinife->SetDoubleAttribute("B", rgba[2]); grandChildNinife->SetDoubleAttribute("A", rgba[3]); child->LinkEndChild( grandChildNinife ); } return element; } else return NULL; } virtual BaseProperty::Pointer Deserialize(TiXmlElement* element) { if (!element) return NULL; -#if ( (VTK_MAJOR_VERSION < 5) && (VTK_MINOR_VERSION < 4) ) - typedef float OUR_VTK_FLOAT_TYPE; - float range[2]; - float rgba[4]; -#else typedef double OUR_VTK_FLOAT_TYPE; double range[2]; double rgba[4]; -#endif double d; // bec. of tinyXML's interface that takes a pointer to float or double... vtkLookupTable* lut = vtkLookupTable::New(); int numberOfColors; int scale; int ramp; // hope the int values don't change betw. vtk versions... if ( element->QueryIntAttribute( "NumberOfColors", &numberOfColors ) == TIXML_SUCCESS ) { lut->SetNumberOfTableValues( numberOfColors ); } else return NULL; if ( element->QueryIntAttribute( "Scale", &scale ) == TIXML_SUCCESS ) { lut->SetScale( scale ); } else return NULL; if ( element->QueryIntAttribute( "Ramp", &ramp ) == TIXML_SUCCESS ) { lut->SetRamp( ramp ); } else return NULL; TiXmlElement* child = element->FirstChildElement("HueRange"); if (child) { if ( child->QueryDoubleAttribute( "min", &d ) != TIXML_SUCCESS ) return NULL; range[0] = static_cast(d); if ( child->QueryDoubleAttribute( "max", &d ) != TIXML_SUCCESS ) return NULL; range[1] = static_cast(d); lut->SetHueRange( range ); } child = element->FirstChildElement("ValueRange"); if (child) { if ( child->QueryDoubleAttribute( "min", &d ) != TIXML_SUCCESS ) return NULL; range[0] = static_cast(d); if ( child->QueryDoubleAttribute( "max", &d ) != TIXML_SUCCESS ) return NULL; range[1] = static_cast(d); lut->SetValueRange( range ); } child = element->FirstChildElement("SaturationRange"); if (child) { if ( child->QueryDoubleAttribute( "min", &d ) != TIXML_SUCCESS ) return NULL; range[0] = static_cast(d); if ( child->QueryDoubleAttribute( "max", &d ) != TIXML_SUCCESS ) return NULL; range[1] = static_cast(d); lut->SetSaturationRange( range ); } child = element->FirstChildElement("AlphaRange"); if (child) { if ( child->QueryDoubleAttribute( "min", &d ) != TIXML_SUCCESS ) return NULL; range[0] = static_cast(d); if ( child->QueryDoubleAttribute( "max", &d ) != TIXML_SUCCESS ) return NULL; range[1] = static_cast(d); lut->SetAlphaRange( range ); } child = element->FirstChildElement("TableRange"); if (child) { if ( child->QueryDoubleAttribute( "min", &d ) != TIXML_SUCCESS ) return NULL; range[0] = static_cast(d); if ( child->QueryDoubleAttribute( "max", &d ) != TIXML_SUCCESS ) return NULL; range[1] = static_cast(d); lut->SetTableRange( range ); } child = element->FirstChildElement("Table"); if (child) { unsigned int index(0); for( TiXmlElement* grandChild = child->FirstChildElement("RgbaColor"); grandChild; grandChild = grandChild->NextSiblingElement("RgbaColor")) { if ( grandChild->QueryDoubleAttribute("R", &d) != TIXML_SUCCESS ) return NULL; rgba[0] = static_cast(d); if ( grandChild->QueryDoubleAttribute("G", &d) != TIXML_SUCCESS ) return NULL; rgba[1] = static_cast(d); if ( grandChild->QueryDoubleAttribute("B", &d) != TIXML_SUCCESS ) return NULL; rgba[2] = static_cast(d); if ( grandChild->QueryDoubleAttribute("A", &d) != TIXML_SUCCESS ) return NULL; rgba[3] = static_cast(d); lut->SetTableValue( index, rgba ); ++index; } } LookupTable::Pointer mitkLut = LookupTable::New(); mitkLut->SetVtkLookupTable( lut ); lut->Delete(); return LookupTableProperty::New(mitkLut).GetPointer(); } protected: LookupTablePropertySerializer() {} virtual ~LookupTablePropertySerializer() {} }; } // namespace // important to put this into the GLOBAL namespace (because it starts with 'namespace mitk') MITK_REGISTER_SERIALIZER(LookupTablePropertySerializer); #endif