diff --git a/CMakeExternals/MITKData.cmake b/CMakeExternals/MITKData.cmake index f32215e67d..b304a22a39 100644 --- a/CMakeExternals/MITKData.cmake +++ b/CMakeExternals/MITKData.cmake @@ -1,35 +1,36 @@ #----------------------------------------------------------------------------- # MITK Data #----------------------------------------------------------------------------- # Sanity checks if(DEFINED MITK_DATA_DIR AND NOT EXISTS ${MITK_DATA_DIR}) message(FATAL_ERROR "MITK_DATA_DIR variable is defined but corresponds to non-existing directory") endif() set(proj MITK-Data) set(proj_DEPENDENCIES) set(MITK-Data_DEPENDS ${proj}) if(BUILD_TESTING) - set(revision_tag 8e15bc7f) + set(revision_tag a4bf7438) + ExternalProject_Add(${proj} URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/MITK-Data_${revision_tag}.tar.gz UPDATE_COMMAND "" CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" DEPENDS ${proj_DEPENDENCIES} ) set(MITK_DATA_DIR ${ep_source_dir}/${proj}) else() mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}") endif(BUILD_TESTING) diff --git a/Core/Code/Common/mitkCoreObjectFactory.cpp b/Core/Code/Common/mitkCoreObjectFactory.cpp index 64f7f805dc..3b4cbe8a99 100644 --- a/Core/Code/Common/mitkCoreObjectFactory.cpp +++ b/Core/Code/Common/mitkCoreObjectFactory.cpp @@ -1,403 +1,403 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkConfig.h" #include "mitkCoreObjectFactory.h" #include "mitkAffineInteractor.h" #include "mitkColorProperty.h" #include "mitkDataNode.h" #include "mitkEnumerationProperty.h" #include "mitkGeometry2DData.h" #include "mitkGeometry2DDataMapper2D.h" #include "mitkGeometry2DDataVtkMapper3D.h" #include "mitkGeometry3D.h" #include "mitkGeometryData.h" #include "mitkImage.h" #include #include "mitkLevelWindowProperty.h" #include "mitkLookupTable.h" #include "mitkLookupTableProperty.h" #include "mitkPlaneGeometry.h" #include "mitkPointSet.h" -#include "mitkPointSetGLMapper2D.h" +#include "mitkPointSetVtkMapper2D.h" #include "mitkPointSetVtkMapper3D.h" #include "mitkPolyDataGLMapper2D.h" #include "mitkProperties.h" #include "mitkPropertyList.h" #include "mitkSlicedGeometry3D.h" #include "mitkSmartPointerProperty.h" #include "mitkStringProperty.h" #include "mitkSurface.h" #include "mitkSurface.h" #include "mitkSurfaceGLMapper2D.h" #include "mitkSurfaceVtkMapper3D.h" #include "mitkTimeSlicedGeometry.h" #include "mitkTransferFunctionProperty.h" #include "mitkVolumeDataVtkMapper3D.h" #include "mitkVtkInterpolationProperty.h" #include "mitkVtkRepresentationProperty.h" #include "mitkVtkResliceInterpolationProperty.h" //#include "mitkPicFileIOFactory.h" #include "mitkPointSetIOFactory.h" #include "mitkItkImageFileIOFactory.h" #include "mitkSTLFileIOFactory.h" #include "mitkVtkSurfaceIOFactory.h" #include "mitkVtkImageIOFactory.h" #include "mitkVtiFileIOFactory.h" //#include "mitkPicVolumeTimeSeriesIOFactory.h" #include "mitkImageWriterFactory.h" #include "mitkPointSetWriterFactory.h" #include "mitkSurfaceVtkWriterFactory.h" mitk::CoreObjectFactory::FileWriterList mitk::CoreObjectFactory::m_FileWriters; void mitk::CoreObjectFactory::RegisterExtraFactory(CoreObjectFactoryBase* factory) { MITK_DEBUG << "CoreObjectFactory: registering extra factory of type " << factory->GetNameOfClass(); m_ExtraFactories.insert(CoreObjectFactoryBase::Pointer(factory)); } void mitk::CoreObjectFactory::UnRegisterExtraFactory(CoreObjectFactoryBase *factory) { MITK_DEBUG << "CoreObjectFactory: un-registering extra factory of type " << factory->GetNameOfClass(); try { m_ExtraFactories.erase(factory); } catch( std::exception const& e) { MITK_ERROR << "Caugt exception while unregistering: " << e.what(); } } mitk::CoreObjectFactory::Pointer mitk::CoreObjectFactory::GetInstance() { static mitk::CoreObjectFactory::Pointer instance; if (instance.IsNull()) { instance = mitk::CoreObjectFactory::New(); } return instance; } #include void mitk::CoreObjectFactory::SetDefaultProperties(mitk::DataNode* node) { if(node==NULL) return; mitk::DataNode::Pointer nodePointer = node; mitk::Image::Pointer image = dynamic_cast(node->GetData()); if(image.IsNotNull() && image->IsInitialized()) { mitk::ImageVtkMapper2D::SetDefaultProperties(node); mitk::VolumeDataVtkMapper3D::SetDefaultProperties(node); } mitk::Surface::Pointer surface = dynamic_cast(node->GetData()); if(surface.IsNotNull()) { mitk::SurfaceGLMapper2D::SetDefaultProperties(node); mitk::SurfaceVtkMapper3D::SetDefaultProperties(node); } mitk::PointSet::Pointer pointSet = dynamic_cast(node->GetData()); if(pointSet.IsNotNull()) { - mitk::PointSetGLMapper2D::SetDefaultProperties(node); + mitk::PointSetVtkMapper2D::SetDefaultProperties(node); mitk::PointSetVtkMapper3D::SetDefaultProperties(node); } for (ExtraFactoriesContainer::iterator it = m_ExtraFactories.begin(); it != m_ExtraFactories.end() ; it++ ) { (*it)->SetDefaultProperties(node); } } mitk::CoreObjectFactory::CoreObjectFactory() { static bool alreadyDone = false; if (!alreadyDone) { MITK_DEBUG << "CoreObjectFactory c'tor" << std::endl; // FIXME itk::ObjectFactoryBase::RegisterFactory( PicFileIOFactory::New() ); itk::ObjectFactoryBase::RegisterFactory( PointSetIOFactory::New() ); itk::ObjectFactoryBase::RegisterFactory( STLFileIOFactory::New() ); itk::ObjectFactoryBase::RegisterFactory( VtkSurfaceIOFactory::New() ); itk::ObjectFactoryBase::RegisterFactory( VtkImageIOFactory::New() ); itk::ObjectFactoryBase::RegisterFactory( VtiFileIOFactory::New() ); itk::ObjectFactoryBase::RegisterFactory( ItkImageFileIOFactory::New() ); // FIXME itk::ObjectFactoryBase::RegisterFactory( PicVolumeTimeSeriesIOFactory::New() ); mitk::SurfaceVtkWriterFactory::RegisterOneFactory(); mitk::PointSetWriterFactory::RegisterOneFactory(); mitk::ImageWriterFactory::RegisterOneFactory(); CreateFileExtensionsMap(); alreadyDone = true; } } mitk::Mapper::Pointer mitk::CoreObjectFactory::CreateMapper(mitk::DataNode* node, MapperSlotId id) { mitk::Mapper::Pointer newMapper = NULL; mitk::Mapper::Pointer tmpMapper = NULL; // check whether extra factories provide mapper for (ExtraFactoriesContainer::iterator it = m_ExtraFactories.begin(); it != m_ExtraFactories.end() ; it++ ) { tmpMapper = (*it)->CreateMapper(node,id); if(tmpMapper.IsNotNull()) newMapper = tmpMapper; } if (newMapper.IsNull()) { mitk::BaseData *data = node->GetData(); if ( id == mitk::BaseRenderer::Standard2D ) { if((dynamic_cast(data)!=NULL)) { newMapper = mitk::ImageVtkMapper2D::New(); newMapper->SetDataNode(node); } else if((dynamic_cast(data)!=NULL)) { newMapper = mitk::Geometry2DDataMapper2D::New(); newMapper->SetDataNode(node); } else if((dynamic_cast(data)!=NULL)) { newMapper = mitk::SurfaceGLMapper2D::New(); // cast because SetDataNode is not virtual mitk::SurfaceGLMapper2D *castedMapper = dynamic_cast(newMapper.GetPointer()); castedMapper->SetDataNode(node); } else if((dynamic_cast(data)!=NULL)) { - newMapper = mitk::PointSetGLMapper2D::New(); + newMapper = mitk::PointSetVtkMapper2D::New(); newMapper->SetDataNode(node); } } else if ( id == mitk::BaseRenderer::Standard3D ) { if((dynamic_cast(data) != NULL)) { newMapper = mitk::VolumeDataVtkMapper3D::New(); newMapper->SetDataNode(node); } else if((dynamic_cast(data)!=NULL)) { newMapper = mitk::Geometry2DDataVtkMapper3D::New(); newMapper->SetDataNode(node); } else if((dynamic_cast(data)!=NULL)) { newMapper = mitk::SurfaceVtkMapper3D::New(); newMapper->SetDataNode(node); } else if((dynamic_cast(data)!=NULL)) { newMapper = mitk::PointSetVtkMapper3D::New(); newMapper->SetDataNode(node); } } } return newMapper; } /* // @deprecated // #define EXTERNAL_FILE_EXTENSIONS \ "All known formats(*.dcm *.DCM *.dc3 *.DC3 *.gdcm *.ima *.mhd *.mps *.nii *.pic *.pic.gz *.bmp *.png *.jpg *.tiff *.pvtk *.stl *.vtk *.vtp *.vtu *.obj *.vti *.hdr *.nrrd *.nhdr );;" \ "DICOM files(*.dcm *.DCM *.dc3 *.DC3 *.gdcm);;" \ "DKFZ Pic (*.seq *.pic *.pic.gz *.seq.gz);;" \ "NRRD Vector Images (*.nrrd *.nhdr);;" \ "Point sets (*.mps);;" \ "Sets of 2D slices (*.pic *.pic.gz *.bmp *.png *.dcm *.gdcm *.ima *.tiff);;" \ "Surface files (*.stl *.vtk *.vtp *.obj);;" \ "NIfTI format (*.nii)" #define SAVE_FILE_EXTENSIONS "all (*.pic *.mhd *.vtk *.vti *.hdr *.png *.tiff *.jpg *.hdr *.bmp *.dcm *.gipl *.nii *.nrrd *.nhdr *.spr *.lsm *.dwi *.hdwi *.qbi *.hqbi)" */ /** * @brief This method gets the supported (open) file extensions as string. This string is can then used by the QT QFileDialog widget. * @return The c-string that contains the file extensions * */ const char* mitk::CoreObjectFactory::GetFileExtensions() { MultimapType aMap; for (ExtraFactoriesContainer::iterator it = m_ExtraFactories.begin(); it != m_ExtraFactories.end() ; it++ ) { aMap = (*it)->GetFileExtensionsMap(); this->MergeFileExtensions(m_FileExtensionsMap, aMap); } this->CreateFileExtensions(m_FileExtensionsMap, m_FileExtensions); return m_FileExtensions.c_str(); } /** * @brief Merge the input map into the fileExtensionsMap. Duplicate entries are removed * @param fileExtensionsMap the existing map, it contains value pairs like ("*.dcm", "DICOM files"),("*.dc3", "DICOM files"). * This map is extented/merged with the values from the input map. * @param inputMap the input map, it contains value pairs like ("*.dcm", "DICOM files"),("*.dc3", "DICOM files") returned by * the extra factories. * */ void mitk::CoreObjectFactory::MergeFileExtensions(MultimapType& fileExtensionsMap, MultimapType inputMap) { bool duplicateFound = false; std::pair pairOfIter; for (MultimapType::iterator it = inputMap.begin(); it != inputMap.end(); ++it) { duplicateFound = false; pairOfIter = fileExtensionsMap.equal_range((*it).first); for (MultimapType::iterator it2 = pairOfIter.first; it2 != pairOfIter.second; ++it2) { //cout << " [" << (*it).first << ", " << (*it).second << "]" << endl; std::string aString = (*it2).second; if (aString.compare((*it).second) == 0) { //cout << " DUP!! [" << (*it).first << ", " << (*it).second << "]" << endl; duplicateFound = true; break; } } if (!duplicateFound) { fileExtensionsMap.insert(std::pair((*it).first, (*it).second)); } } } /** * @brief get the defined (open) file extension map * @return the defined (open) file extension map */ mitk::CoreObjectFactoryBase::MultimapType mitk::CoreObjectFactory::GetFileExtensionsMap() { return m_FileExtensionsMap; } /** * @brief initialize the file extension entries for open and save */ void mitk::CoreObjectFactory::CreateFileExtensionsMap() { m_FileExtensionsMap.insert(std::pair("*.dcm", "DICOM files")); m_FileExtensionsMap.insert(std::pair("*.DCM", "DICOM files")); m_FileExtensionsMap.insert(std::pair("*.dc3", "DICOM files")); m_FileExtensionsMap.insert(std::pair("*.DC3", "DICOM files")); m_FileExtensionsMap.insert(std::pair("*.gdcm", "DICOM files")); m_FileExtensionsMap.insert(std::pair("*.seq", "DKFZ Pic")); m_FileExtensionsMap.insert(std::pair("*.pic", "DKFZ Pic")); m_FileExtensionsMap.insert(std::pair("*.pic.gz", "DKFZ Pic")); m_FileExtensionsMap.insert(std::pair("*.mhd", "MetaImage")); m_FileExtensionsMap.insert(std::pair("*.seq.gz", "DKFZ Pic")); m_FileExtensionsMap.insert(std::pair("*.hdr", "Analyze Format")); m_FileExtensionsMap.insert(std::pair("*.img", "Analyze Format")); m_FileExtensionsMap.insert(std::pair("*.img.gz", "Analyze Format")); m_FileExtensionsMap.insert(std::pair("*.nrrd", "Nearly Raw Raster Data")); m_FileExtensionsMap.insert(std::pair("*.nhdr", "NRRD with detached header")); m_FileExtensionsMap.insert(std::pair("*.mps", "Point sets")); m_FileExtensionsMap.insert(std::pair("*.pic", "Sets of 2D slices")); m_FileExtensionsMap.insert(std::pair("*.pic.gz", "Sets of 2D slices")); m_FileExtensionsMap.insert(std::pair("*.bmp", "Sets of 2D slices")); m_FileExtensionsMap.insert(std::pair("*.png", "Sets of 2D slices")); m_FileExtensionsMap.insert(std::pair("*.jpg", "Sets of 2D slices")); m_FileExtensionsMap.insert(std::pair("*.jpeg", "Sets of 2D slices")); m_FileExtensionsMap.insert(std::pair("*.dcm", "Sets of 2D slices")); m_FileExtensionsMap.insert(std::pair("*.gdcm", "Sets of 2D slices")); m_FileExtensionsMap.insert(std::pair("*.ima", "Sets of 2D slices")); m_FileExtensionsMap.insert(std::pair("*.tiff", "Sets of 2D slices")); m_FileExtensionsMap.insert(std::pair("*.tif", "Sets of 2D slices")); m_FileExtensionsMap.insert(std::pair("*.stl", "Surface files")); m_FileExtensionsMap.insert(std::pair("*.vtk", "Surface files")); m_FileExtensionsMap.insert(std::pair("*.vtp", "Surface files")); m_FileExtensionsMap.insert(std::pair("*.obj", "Surface files")); m_FileExtensionsMap.insert(std::pair("*.nii", "NIfTI format")); m_FileExtensionsMap.insert(std::pair("*.nii.gz", "NIfTI format")); //m_SaveFileExtensionsMap.insert(std::pair("*.pic", "DKFZ Pic")); m_SaveFileExtensionsMap.insert(std::pair("*.mhd", "MetaImage")); m_SaveFileExtensionsMap.insert(std::pair("*.vtk", "Surface Files")); m_SaveFileExtensionsMap.insert(std::pair("*.vti", "VTK Image Data Files")); m_SaveFileExtensionsMap.insert(std::pair("*.hdr", "Analyze Format")); m_SaveFileExtensionsMap.insert(std::pair("*.png", "Sets of 2D slices")); m_SaveFileExtensionsMap.insert(std::pair("*.tiff", "Sets of 2D slices")); m_SaveFileExtensionsMap.insert(std::pair("*.tif", "Sets of 2D slices")); m_SaveFileExtensionsMap.insert(std::pair("*.jpg", "Sets of 2D slices")); m_SaveFileExtensionsMap.insert(std::pair("*.jpeg", "Sets of 2D slices")); m_SaveFileExtensionsMap.insert(std::pair("*.bmp", "Sets of 2D slices")); m_SaveFileExtensionsMap.insert(std::pair("*.dcm", "Sets of 2D slices")); m_SaveFileExtensionsMap.insert(std::pair("*.gipl", "UMDS GIPL Format Files")); m_SaveFileExtensionsMap.insert(std::pair("*.nii", "NIfTI format")); m_SaveFileExtensionsMap.insert(std::pair("*.nrrd", "Nearly Raw Raster Data")); m_SaveFileExtensionsMap.insert(std::pair("*.nhdr", "NRRD with detached header")); m_SaveFileExtensionsMap.insert(std::pair("*.lsm", "Microscope Images")); m_SaveFileExtensionsMap.insert(std::pair("*.dwi", "Diffusion Weighted Images")); m_SaveFileExtensionsMap.insert(std::pair("*.hdwi", "Diffusion Weighted Images")); m_SaveFileExtensionsMap.insert(std::pair("*.qbi", "Q-Ball Images")); m_SaveFileExtensionsMap.insert(std::pair("*.hqbi", "Q-Ball Images")); } /** * @brief This method gets the supported (save) file extensions as string. This string is can then used by the QT QFileDialog widget. * @return The c-string that contains the (save) file extensions * */ const char* mitk::CoreObjectFactory::GetSaveFileExtensions() { MultimapType aMap; for (ExtraFactoriesContainer::iterator it = m_ExtraFactories.begin(); it != m_ExtraFactories.end() ; it++ ) { aMap = (*it)->GetSaveFileExtensionsMap(); this->MergeFileExtensions(m_SaveFileExtensionsMap, aMap); } this->CreateFileExtensions(m_SaveFileExtensionsMap, m_SaveFileExtensions); return m_SaveFileExtensions.c_str(); }; /** * @brief get the defined (save) file extension map * @return the defined (save) file extension map */ mitk::CoreObjectFactoryBase::MultimapType mitk::CoreObjectFactory::GetSaveFileExtensionsMap() { return m_SaveFileExtensionsMap; } mitk::CoreObjectFactory::FileWriterList mitk::CoreObjectFactory::GetFileWriters() { FileWriterList allWriters = m_FileWriters; for (ExtraFactoriesContainer::iterator it = m_ExtraFactories.begin(); it != m_ExtraFactories.end() ; it++ ) { FileWriterList list2 = (*it)->GetFileWriters(); allWriters.merge(list2); } return allWriters; } void mitk::CoreObjectFactory::MapEvent(const mitk::Event*, const int) { } diff --git a/Core/Code/Rendering/mitkGLMapper2D.h b/Core/Code/Rendering/mitkGLMapper2D.h index d332e5ee60..cb4cc6fec3 100644 --- a/Core/Code/Rendering/mitkGLMapper2D.h +++ b/Core/Code/Rendering/mitkGLMapper2D.h @@ -1,35 +1,35 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKGLMAPPER2D_H_HEADER_INCLUDED_C197C872 #define MITKGLMAPPER2D_H_HEADER_INCLUDED_C197C872 #include "mitkGLMapper.h" namespace mitk { // typedef allows integration of mappers into the new mapper architecture - // @deprecated Use GLMapper instead + // \deprecatedSince{2013_03} Use GLMapper instead DEPRECATED(typedef GLMapper GLMapper2D); } // namespace mitk #endif /* MITKGLMAPPER2D_H_HEADER_INCLUDED_C197C872 */ diff --git a/Core/Code/Rendering/mitkPointSetGLMapper2D.cpp b/Core/Code/Rendering/mitkPointSetGLMapper2D.cpp index f0f8476e0b..791f062ec2 100644 --- a/Core/Code/Rendering/mitkPointSetGLMapper2D.cpp +++ b/Core/Code/Rendering/mitkPointSetGLMapper2D.cpp @@ -1,523 +1,524 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkPointSetGLMapper2D.h" #include "mitkPointSet.h" #include "mitkPlaneGeometry.h" #include "mitkColorProperty.h" #include "mitkProperties.h" #include "vtkLinearTransform.h" #include "mitkStringProperty.h" #include "mitkPointSet.h" #include "mitkVtkPropRenderer.h" #include "mitkGL.h" //const float selectedColor[]={1.0,0.0,0.6}; //for selected! mitk::PointSetGLMapper2D::PointSetGLMapper2D() : m_Polygon(false), m_ShowPoints(true), m_ShowDistances(false), m_DistancesDecimalDigits(1), m_ShowAngles(false), m_ShowDistantLines(true), m_LineWidth(1) { } mitk::PointSetGLMapper2D::~PointSetGLMapper2D() { } const mitk::PointSet *mitk::PointSetGLMapper2D::GetInput(void) { return static_cast ( GetDataNode()->GetData() ); } + void mitk::PointSetGLMapper2D::ApplyAllProperties(mitk::BaseRenderer* renderer) { GLMapper::ApplyColorAndOpacityProperties( renderer ); const mitk::DataNode* node=GetDataNode(); if( node == NULL ) return; node->GetBoolProperty("show contour", m_Polygon); node->GetBoolProperty("close contour", m_PolygonClosed); node->GetBoolProperty("show points", m_ShowPoints); node->GetBoolProperty("show distances", m_ShowDistances); node->GetIntProperty("distance decimal digits", m_DistancesDecimalDigits); node->GetBoolProperty("show angles", m_ShowAngles); node->GetBoolProperty("show distant lines", m_ShowDistantLines); node->GetIntProperty("line width", m_LineWidth); node->GetIntProperty("point line width", m_PointLineWidth); node->GetIntProperty("point 2D size", m_Point2DSize); } static bool makePerpendicularVector2D(const mitk::Vector2D& in, mitk::Vector2D& out) { if((fabs(in[0])>0) && ( (fabs(in[0])>fabs(in[1])) || (in[1] == 0) ) ) { out[0]=-in[1]/in[0]; out[1]=1; out.Normalize(); return true; } else if(fabs(in[1])>0) { out[0]=1; out[1]=-in[0]/in[1]; out.Normalize(); return true; } else return false; } void mitk::PointSetGLMapper2D::Paint( mitk::BaseRenderer *renderer ) { const mitk::DataNode* node=GetDataNode(); if( node == NULL ) return; const int text2dDistance = 10; bool visible = true; GetDataNode()->GetVisibility(visible, renderer, "visible"); if ( !visible) return; // @FIXME: Logik fuer update bool updateNeccesary=true; if (updateNeccesary) { // ok, das ist aus GenerateData kopiert mitk::PointSet::Pointer input = const_cast(this->GetInput()); // Get the TimeSlicedGeometry of the input object const TimeSlicedGeometry* inputTimeGeometry = input->GetTimeSlicedGeometry(); if (( inputTimeGeometry == NULL ) || ( inputTimeGeometry->GetTimeSteps() == 0 ) ) { return; } // // get the world time // const Geometry2D* worldGeometry = renderer->GetCurrentWorldGeometry2D(); assert( worldGeometry != NULL ); ScalarType time = worldGeometry->GetTimeBounds()[ 0 ]; // // convert the world time in time steps of the input object // int timeStep=0; if ( time > ScalarTypeNumericTraits::NonpositiveMin() ) timeStep = inputTimeGeometry->MSToTimeStep( time ); if ( inputTimeGeometry->IsValidTime( timeStep ) == false ) { return; } mitk::PointSet::DataType::Pointer itkPointSet = input->GetPointSet( timeStep ); if ( itkPointSet.GetPointer() == NULL) { return; } mitk::DisplayGeometry::Pointer displayGeometry = renderer->GetDisplayGeometry(); assert(displayGeometry.IsNotNull()); //apply color and opacity read from the PropertyList this->ApplyAllProperties(renderer); vtkLinearTransform* transform = GetDataNode()->GetVtkTransform(); //List of the Points PointSet::DataType::PointsContainerConstIterator it, end; it = itkPointSet->GetPoints()->Begin(); end = itkPointSet->GetPoints()->End(); //iterator on the additional data of each point PointSet::DataType::PointDataContainerIterator selIt, selEnd; bool pointDataBroken = (itkPointSet->GetPointData()->Size() != itkPointSet->GetPoints()->Size()); selIt = itkPointSet->GetPointData()->Begin(); selEnd = itkPointSet->GetPointData()->End(); int counter = 0; //for writing text int j = 0; //for switching back to old color after using selected color float recallColor[4]; glGetFloatv(GL_CURRENT_COLOR,recallColor); //get the properties for coloring the points float unselectedColor[4] = {1.0, 1.0, 0.0, 1.0};//yellow //check if there is an unselected property if (dynamic_cast(node->GetPropertyList(renderer)->GetProperty("unselectedcolor")) != NULL) { mitk::Color tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("unselectedcolor"))->GetValue(); unselectedColor[0] = tmpColor[0]; unselectedColor[1] = tmpColor[1]; unselectedColor[2] = tmpColor[2]; unselectedColor[3] = 1.0f; //!!define a new ColorProp to be able to pass alpha value } else if (dynamic_cast(node->GetPropertyList(NULL)->GetProperty("unselectedcolor")) != NULL) { mitk::Color tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("unselectedcolor"))->GetValue(); unselectedColor[0] = tmpColor[0]; unselectedColor[1] = tmpColor[1]; unselectedColor[2] = tmpColor[2]; unselectedColor[3] = 1.0f; //!!define a new ColorProp to be able to pass alpha value } else { //get the color from the dataNode node->GetColor(unselectedColor, NULL); } //get selected property float selectedColor[4] = {1.0, 0.0, 0.6, 1.0}; if (dynamic_cast(node->GetPropertyList(renderer)->GetProperty("selectedcolor")) != NULL) { mitk::Color tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("selectedcolor"))->GetValue(); selectedColor[0] = tmpColor[0]; selectedColor[1] = tmpColor[1]; selectedColor[2] = tmpColor[2]; selectedColor[3] = 1.0f; } else if (dynamic_cast(node->GetPropertyList(NULL)->GetProperty("selectedcolor")) != NULL) { mitk::Color tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("selectedcolor"))->GetValue(); selectedColor[0] = tmpColor[0]; selectedColor[1] = tmpColor[1]; selectedColor[2] = tmpColor[2]; selectedColor[3] = 1.0f; } //check if there is an pointLineWidth property if (dynamic_cast(node->GetPropertyList(renderer)->GetProperty("point line width")) != NULL) { m_PointLineWidth = dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("point line width"))->GetValue(); } else if (dynamic_cast(node->GetPropertyList(NULL)->GetProperty("point line width")) != NULL) { m_PointLineWidth = dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("point line width"))->GetValue(); } //check if there is an point 2D size property if (dynamic_cast(node->GetPropertyList(renderer)->GetProperty("point 2D size")) != NULL) { m_Point2DSize = dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("point 2D size"))->GetValue(); } else if (dynamic_cast(node->GetPropertyList(NULL)->GetProperty("point 2D size")) != NULL) { m_Point2DSize = dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("point 2D size"))->GetValue(); } Point3D p; // currently visited point Point3D lastP; // last visited point Vector3D vec; // p - lastP Vector3D lastVec; // lastP - point before lastP vec.Fill(0); mitk::Point3D projected_p; // p projected on viewplane Point2D pt2d; // projected_p in display coordinates Point2D lastPt2d; // last projected_p in display coordinates Point2D preLastPt2d;// projected_p in display coordinates before lastPt2d Point2D lastPt2DInPointSet; // The last point in the pointset in display coordinates mitk::PointSet::DataType::PointType plob; plob.Fill(0); itkPointSet->GetPoint( itkPointSet->GetNumberOfPoints()-1, &plob); //map lastPt2DInPointSet to display coordinates float vtkp[3]; itk2vtk(plob, vtkp); transform->TransformPoint(vtkp, vtkp); vtk2itk(vtkp,p); displayGeometry->Project(p, projected_p); displayGeometry->Map(projected_p, lastPt2DInPointSet); displayGeometry->WorldToDisplay(lastPt2DInPointSet, lastPt2DInPointSet); while(it!=end) // iterate over all points { lastP = p; // valid only for counter > 0 lastVec = vec; // valid only for counter > 1 preLastPt2d = lastPt2d; // valid only for counter > 1 lastPt2d = pt2d; // valid only for counter > 0 itk2vtk(it->Value(), vtkp); transform->TransformPoint(vtkp, vtkp); vtk2itk(vtkp,p); vec = p-lastP; // valid only for counter > 0 displayGeometry->Project(p, projected_p); Vector3D diff=p-projected_p; ScalarType scalardiff = diff.GetSquaredNorm(); //MouseOrientation bool isInputDevice=false; bool isRendererSlice = scalardiff < 0.00001; //cause roundoff error if(this->GetDataNode()->GetBoolProperty("inputdevice",isInputDevice) && isInputDevice && !isRendererSlice ) { displayGeometry->Map(projected_p, pt2d); displayGeometry->WorldToDisplay(pt2d, pt2d); //Point size depending of distance to slice /*float p_size = (1/scalardiff)*10*m_Point2DSize; if(p_size < m_Point2DSize * 0.6 ) p_size = m_Point2DSize * 0.6 ; else if ( p_size > m_Point2DSize ) p_size = m_Point2DSize;*/ float p_size = (1/scalardiff)*100.0; if(p_size < 6.0 ) p_size = 6.0 ; else if ( p_size > 10.0 ) p_size = 10.0; //draw Point float opacity = (p_size<8)?0.3:1.0;//don't get the opacity from the node? Feature not a bug! Otehrwise the 2D cross is hardly seen. glColor4f(unselectedColor[0],unselectedColor[1],unselectedColor[2],opacity); glPointSize(p_size); //glShadeModel(GL_FLAT); glBegin (GL_POINTS); glVertex2fv(&pt2d[0]); glEnd (); } //for point set if(!isInputDevice && ( (scalardiff<4.0) || (m_Polygon))) { Point2D tmp; displayGeometry->Map(projected_p, pt2d); displayGeometry->WorldToDisplay(pt2d, pt2d); Vector2D horz,vert; horz[0]=(float)m_Point2DSize-scalardiff*2; horz[1]=0; vert[0]=0; vert[1]=(float)m_Point2DSize-scalardiff*2; // now paint text if available if (dynamic_cast(this->GetDataNode() ->GetProperty("label")) != NULL) { const char * pointLabel = dynamic_cast( this->GetDataNode()->GetProperty("label"))->GetValue(); std::string l = pointLabel; if (input->GetSize()>1) { // char buffer[20]; // sprintf(buffer,"%d",it->Index()); std::stringstream ss; ss << it->Index(); l.append(ss.str()); } if (unselectedColor != NULL) { mitk::VtkPropRenderer* OpenGLrenderer = dynamic_cast( renderer ); float rgb[3];//yellow rgb[0] = unselectedColor[0]; rgb[1] = unselectedColor[1]; rgb[2] = unselectedColor[2]; OpenGLrenderer->WriteSimpleText(l, pt2d[0] + text2dDistance, pt2d[1] + text2dDistance,rgb[0], rgb[1],rgb[2]); } else { mitk::VtkPropRenderer* OpenGLrenderer = dynamic_cast( renderer ); OpenGLrenderer->WriteSimpleText(l, pt2d[0] + text2dDistance, pt2d[1] + text2dDistance,0.0,1.0,0.0); } } if((m_ShowPoints) && (scalardiff<4.0)) { //check if the point is to be marked as selected if(selIt != selEnd || pointDataBroken) { bool addAsSelected = false; if (pointDataBroken) addAsSelected = false; else if (selIt->Value().selected) addAsSelected = true; else addAsSelected = false; if (addAsSelected) { horz[0]=(float)m_Point2DSize; vert[1]=(float)m_Point2DSize; glColor3f(selectedColor[0],selectedColor[1],selectedColor[2]); glLineWidth(m_PointLineWidth); //a diamond around the point with the selected color glBegin (GL_LINE_LOOP); tmp=pt2d-horz; glVertex2fv(&tmp[0]); tmp=pt2d+vert; glVertex2fv(&tmp[0]); tmp=pt2d+horz; glVertex2fv(&tmp[0]); tmp=pt2d-vert; glVertex2fv(&tmp[0]); glEnd (); glLineWidth(1); //the actual point in the specified color to see the usual color of the point glColor3f(unselectedColor[0],unselectedColor[1],unselectedColor[2]); glPointSize(1); glBegin (GL_POINTS); tmp=pt2d; glVertex2fv(&tmp[0]); glEnd (); } else //if not selected { glColor3f(unselectedColor[0],unselectedColor[1],unselectedColor[2]); glLineWidth(m_PointLineWidth); //drawing crosses glBegin (GL_LINES); tmp=pt2d-horz; glVertex2fv(&tmp[0]); tmp=pt2d+horz; glVertex2fv(&tmp[0]); tmp=pt2d-vert; glVertex2fv(&tmp[0]); tmp=pt2d+vert; glVertex2fv(&tmp[0]); glEnd (); glLineWidth(1); } } } bool drawLinesEtc = true; if (!m_ShowDistantLines && counter > 0) // check, whether this line should be drawn { ScalarType currentDistance = displayGeometry->GetWorldGeometry()->SignedDistance(p); ScalarType lastDistance = displayGeometry->GetWorldGeometry()->SignedDistance(lastP); if ( currentDistance * lastDistance > 0.5 ) // points on same side of plane drawLinesEtc = false; } // draw a line if ((m_Polygon && counter>0 && drawLinesEtc) || (m_Polygon && m_PolygonClosed && drawLinesEtc)) { if ((counter == 0) && ( m_PolygonClosed)) { lastPt2d = lastPt2DInPointSet; } //get contour color property float contourColor[4] = {unselectedColor[0], unselectedColor[1], unselectedColor[2], unselectedColor[3]};//so if no property set, then use unselected color if (dynamic_cast(node->GetPropertyList(renderer)->GetProperty("contourcolor")) != NULL) { mitk::Color tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("contourcolor"))->GetValue(); contourColor[0] = tmpColor[0]; contourColor[1] = tmpColor[1]; contourColor[2] = tmpColor[2]; contourColor[3] = 1.0f; } else if (dynamic_cast(node->GetPropertyList(NULL)->GetProperty("contourcolor")) != NULL) { mitk::Color tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("contourcolor"))->GetValue(); contourColor[0] = tmpColor[0]; contourColor[1] = tmpColor[1]; contourColor[2] = tmpColor[2]; contourColor[3] = 1.0f; } //set this color glColor3f(contourColor[0],contourColor[1],contourColor[2]); glLineWidth( m_LineWidth ); glBegin (GL_LINES); glVertex2fv(&pt2d[0]); glVertex2fv(&lastPt2d[0]); glEnd (); glLineWidth(1.0); if(m_ShowDistances) // calculate and print a distance { std::stringstream buffer; float distance = vec.GetNorm(); buffer<( renderer ); OpenGLrenderer->WriteSimpleText(buffer.str(), pos2d[0], pos2d[1]); //this->WriteTextXY(pos2d[0], pos2d[1], buffer.str(),renderer); } if(m_ShowAngles && counter > 1 ) // calculate and print the angle btw. two lines { std::stringstream buffer; //buffer << angle(vec.Get_vnl_vector(), -lastVec.Get_vnl_vector())*180/vnl_math::pi << "�"; - buffer << angle(vec.GetVnlVector(), -lastVec.GetVnlVector())*180/vnl_math::pi << (char)176; + buffer << angle(vec.Get_vnl_vector(), -lastVec.Get_vnl_vector())*180/vnl_math::pi << (char)176; Vector2D vec2d = pt2d-lastPt2d; vec2d.Normalize(); Vector2D lastVec2d = lastPt2d-preLastPt2d; lastVec2d.Normalize(); vec2d=vec2d-lastVec2d; vec2d.Normalize(); Vector2D pos2d = lastPt2d.GetVectorFromOrigin()+vec2d*text2dDistance*text2dDistance; mitk::VtkPropRenderer* OpenGLrenderer = dynamic_cast( renderer ); OpenGLrenderer->WriteSimpleText(buffer.str(), pos2d[0], pos2d[1]); //this->WriteTextXY(pos2d[0], pos2d[1], buffer.str(),renderer); } } counter++; } ++it; if(selIt != selEnd && !pointDataBroken) ++selIt; j++; } //recall the color to the same color before this drawing glColor3f(recallColor[0],recallColor[1],recallColor[2]); } } void mitk::PointSetGLMapper2D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { node->AddProperty( "line width", mitk::IntProperty::New(2), renderer, overwrite ); // width of the line from one point to another node->AddProperty( "point line width", mitk::IntProperty::New(1), renderer, overwrite ); //width of the cross marking a point node->AddProperty( "point 2D size", mitk::IntProperty::New(8), renderer, overwrite ); // length of the cross marking a point // length of an edge of the box marking a point node->AddProperty( "show contour", mitk::BoolProperty::New(false), renderer, overwrite ); // contour of the line between points node->AddProperty( "close contour", mitk::BoolProperty::New(false), renderer, overwrite ); node->AddProperty( "show points", mitk::BoolProperty::New(true), renderer, overwrite ); //show or hide points node->AddProperty( "show distances", mitk::BoolProperty::New(false), renderer, overwrite ); //show or hide distance measure (not always available) node->AddProperty( "distance decimal digits", mitk::IntProperty::New(2), renderer, overwrite ); //set the number of decimal digits to be shown node->AddProperty( "show angles", mitk::BoolProperty::New(false), renderer, overwrite ); //show or hide angle measurement (not always available) node->AddProperty( "show distant lines", mitk::BoolProperty::New(false), renderer, overwrite ); //show the line between to points from a distant view (equals "always on top" option) node->AddProperty( "layer", mitk::IntProperty::New(1), renderer, overwrite ); // default to draw pointset above images (they have a default layer of 0) Superclass::SetDefaultProperties(node, renderer, overwrite); } diff --git a/Core/Code/Rendering/mitkPointSetGLMapper2D.h b/Core/Code/Rendering/mitkPointSetGLMapper2D.h index bf192147af..f20ff02ddf 100644 --- a/Core/Code/Rendering/mitkPointSetGLMapper2D.h +++ b/Core/Code/Rendering/mitkPointSetGLMapper2D.h @@ -1,94 +1,97 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKPointSetMAPPER2D_H_HEADER_INCLUDED #define MITKPointSetMAPPER2D_H_HEADER_INCLUDED #include #include "mitkGLMapper.h" namespace mitk { class BaseRenderer; class PointSet; /** * @brief OpenGL-based mapper to display a mitk::PointSet in a 2D window. * * This mapper can actually more than just draw a number of points of a * mitk::PointSet. If you set the right properties of the mitk::DataNode, * which contains the point set, then this mapper will also draw lines * connecting the points, and calculate and display distances and angles * between adjacent points. Here is a complete list of boolean properties, * which might be of interest: * * - \b "show contour": Draw not only the points but also the connections between * them (default false) * - \b "line width": IntProperty which gives the width of the contour lines * - \b "show points": Wheter or not to draw the actual points (default true) * - \b "show distances": Wheter or not to calculate and print the distance * between adjacent points (default false) * - \b "show angles": Wheter or not to calculate and print the angle between * adjacent points (default false) * - \b "show distant lines": When true, the mapper will also draw contour * lines that are far away form the current slice (default true) * - \b "label": StringProperty with a label for this point set * * BUG 1321 - possible new features: * point-2d-size (length of lines in cross/diamond) * point-linewidth * * @ingroup Mapper */ -class MITK_CORE_EXPORT PointSetGLMapper2D : public GLMapper + +/** \deprecatedSince{2013_06} This mapper is replaced by PointSetVtkMapper2D. The child classes of this class are deprecated. +/* To further ensure their functionality PointSetGLMapper2D cannot be removed and is set deprecated too. */ +DEPRECATED(class MITK_CORE_EXPORT PointSetGLMapper2D) : public GLMapper { public: mitkClassMacro(PointSetGLMapper2D, GLMapper); itkNewMacro(Self); /** @brief Get the PointDataList to map */ virtual const mitk::PointSet * GetInput(void); virtual void Paint(mitk::BaseRenderer * renderer); virtual void ApplyAllProperties(mitk::BaseRenderer* renderer); static void SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer = NULL, bool overwrite = false); protected: PointSetGLMapper2D(); virtual ~PointSetGLMapper2D(); bool m_Polygon; bool m_PolygonClosed; bool m_ShowPoints; bool m_ShowDistances; int m_DistancesDecimalDigits; bool m_ShowAngles; bool m_ShowDistantLines; int m_LineWidth; int m_PointLineWidth; int m_Point2DSize; }; } // namespace mitk #endif /* MITKPointSetMapper2D_H_HEADER_INCLUDED */ diff --git a/Core/Code/Rendering/mitkPointSetVtkMapper2D.cpp b/Core/Code/Rendering/mitkPointSetVtkMapper2D.cpp new file mode 100644 index 0000000000..31cc35e449 --- /dev/null +++ b/Core/Code/Rendering/mitkPointSetVtkMapper2D.cpp @@ -0,0 +1,768 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#include "mitkPointSetVtkMapper2D.h" +#include "mitkDataNode.h" +#include "mitkProperties.h" +#include "mitkColorProperty.h" +#include "mitkEnumerationProperty.h" +#include "mitkVtkPropRenderer.h" +#include "mitkPointSet.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +mitk::PointSetVtkMapper2D::LocalStorage::LocalStorage() +{ + + // points + m_UnselectedPoints = vtkSmartPointer::New(); + m_SelectedPoints = vtkSmartPointer::New(); + m_ContourPoints = vtkSmartPointer::New(); + + // scales + m_UnselectedScales = vtkSmartPointer::New(); + m_SelectedScales = vtkSmartPointer::New(); + + // distances + m_DistancesBetweenPoints = vtkSmartPointer::New(); + + // lines + m_ContourLines = vtkSmartPointer::New(); + + // glyph source (provides the different shapes) + m_UnselectedGlyphSource2D = vtkSmartPointer::New(); + m_SelectedGlyphSource2D = vtkSmartPointer::New(); + + // glyphs + m_UnselectedGlyph3D = vtkSmartPointer::New(); + m_SelectedGlyph3D = vtkSmartPointer::New(); + + // polydata + m_VtkUnselectedPointListPolyData = vtkSmartPointer::New(); + m_VtkSelectedPointListPolyData = vtkSmartPointer ::New(); + m_VtkContourPolyData = vtkSmartPointer::New(); + + // actors + m_UnselectedActor = vtkSmartPointer ::New(); + m_SelectedActor = vtkSmartPointer ::New(); + m_ContourActor = vtkSmartPointer ::New(); + + // mappers + m_VtkUnselectedPolyDataMapper = vtkSmartPointer::New(); + m_VtkSelectedPolyDataMapper = vtkSmartPointer::New(); + m_VtkContourPolyDataMapper = vtkSmartPointer::New(); + + // propassembly + m_PropAssembly = vtkSmartPointer ::New(); + +} + +mitk::PointSetVtkMapper2D::LocalStorage::~LocalStorage() +{ +} + +// input for this mapper ( = point set) +const mitk::PointSet* mitk::PointSetVtkMapper2D::GetInput() +{ + return static_cast ( GetDataNode()->GetData() ); +} + +// constructor +mitk::PointSetVtkMapper2D::PointSetVtkMapper2D() +: m_Polygon(false), +m_PolygonClosed(false), +m_ShowPoints(true), +m_ShowDistances(false), +m_DistancesDecimalDigits(1), +m_ShowAngles(false), +m_ShowDistantLines(false), +m_LineWidth(1), +m_PointLineWidth(1), +m_Point2DSize(6), +m_IdGlyph(3), // default: cross +m_FillGlyphs(false) +{ +} + +// destructor +mitk::PointSetVtkMapper2D::~PointSetVtkMapper2D() +{ +} + +// toggles visiblity of the prop assembly +void mitk::PointSetVtkMapper2D::ResetMapper( BaseRenderer* renderer ) +{ + LocalStorage *ls = m_LSH.GetLocalStorage(renderer); + ls->m_PropAssembly->VisibilityOff(); +} + +// returns propassembly +vtkProp* mitk::PointSetVtkMapper2D::GetVtkProp(mitk::BaseRenderer * renderer) +{ + LocalStorage *ls = m_LSH.GetLocalStorage(renderer); + return ls->m_PropAssembly; +} + +static bool makePerpendicularVector2D(const mitk::Vector2D& in, mitk::Vector2D& out) +{ + if((fabs(in[0])>0) && ( (fabs(in[0])>fabs(in[1])) || (in[1] == 0) ) ) + { + out[0]=-in[1]/in[0]; + out[1]=1; + out.Normalize(); + return true; + } + else + if(fabs(in[1])>0) + { + out[0]=1; + out[1]=-in[0]/in[1]; + out.Normalize(); + return true; + } + else + return false; +} + + +void mitk::PointSetVtkMapper2D::CreateVTKRenderObjects(mitk::BaseRenderer* renderer) +{ + + LocalStorage *ls = m_LSH.GetLocalStorage(renderer); + + if(ls->m_PropAssembly->GetParts()->IsItemPresent(ls->m_UnselectedActor)) + ls->m_PropAssembly->RemovePart(ls->m_UnselectedActor); + if(ls->m_PropAssembly->GetParts()->IsItemPresent(ls->m_SelectedActor)) + ls->m_PropAssembly->RemovePart(ls->m_SelectedActor); + if(ls->m_PropAssembly->GetParts()->IsItemPresent(ls->m_ContourActor)) + ls->m_PropAssembly->RemovePart(ls->m_ContourActor); + if(ls->m_PropAssembly->GetParts()->IsItemPresent(ls->m_VtkTextActor)) + ls->m_PropAssembly->RemovePart(ls->m_VtkTextActor); + + unsigned i = 0; + for(i=0; i< ls->m_VtkTextLabelActors.size(); i++) + { + if(ls->m_PropAssembly->GetParts()->IsItemPresent(ls->m_VtkTextLabelActors.at(i))) + ls->m_PropAssembly->RemovePart(ls->m_VtkTextLabelActors.at(i)); + } + + for(i=0; i< ls->m_VtkTextDistanceActors.size(); i++) + { + if(ls->m_PropAssembly->GetParts()->IsItemPresent(ls->m_VtkTextDistanceActors.at(i))) + ls->m_PropAssembly->RemovePart(ls->m_VtkTextDistanceActors.at(i)); + } + + for(i=0; i< ls->m_VtkTextAngleActors.size(); i++) + { + if(ls->m_PropAssembly->GetParts()->IsItemPresent(ls->m_VtkTextAngleActors.at(i))) + ls->m_PropAssembly->RemovePart(ls->m_VtkTextAngleActors.at(i)); + } + + // polydata + ls->m_VtkUnselectedPointListPolyData = vtkSmartPointer::New(); + ls->m_VtkSelectedPointListPolyData = vtkSmartPointer ::New(); + ls->m_VtkContourPolyData = vtkSmartPointer::New(); + + + // exceptional displaying for PositionTracker -> MouseOrientationTool + int mapperID; + bool isInputDevice=false; + if( this->GetDataNode()->GetBoolProperty("inputdevice",isInputDevice) && isInputDevice ) + { + if( this->GetDataNode()->GetIntProperty("BaseRendererMapperID",mapperID) && mapperID == 2) + return; //The event for the PositionTracker came from the 3d widget and not needs to be displayed + } + + // get input point set and update the PointSet + mitk::PointSet::Pointer input = const_cast(this->GetInput()); + + /* only update the input data, if the property tells us to */ + bool update = true; + this->GetDataNode()->GetBoolProperty("updateDataOnRender", update); + if (update == true) + input->Update(); + + //TODO: insert last changes on timestamps + int timestep = this->GetTimestep(); + + mitk::PointSet::DataType::Pointer itkPointSet = input->GetPointSet( timestep ); + + if ( itkPointSet.GetPointer() == NULL) + { + ls->m_PropAssembly->VisibilityOff(); + return; + } + + //iterator for point set + mitk::PointSet::PointsContainer::Iterator pointsIter; + mitk::PointSet::PointsContainer::Iterator pointsIterPredecessor; + pointsIterPredecessor = itkPointSet->GetPoints()->Begin(); + + + // PointDataContainer has additional information to each point, e.g. whether + // it is selected or not + mitk::PointSet::PointDataContainer::Iterator pointDataIter; + pointDataIter = itkPointSet->GetPointData()->Begin(); + + + //check if the list for the PointDataContainer is the same size as the PointsContainer. + //If not, then the points were inserted manually and can not be visualized according to the PointData (selected/unselected) + bool pointDataBroken = (itkPointSet->GetPointData()->Size() != itkPointSet->GetPoints()->Size()); + + if(itkPointSet->GetPointData()->size() == 0 || pointDataBroken) + { + return; + } + + // empty point sets, cellarrays, scalars + ls->m_UnselectedPoints->Reset(); + ls->m_SelectedPoints->Reset(); + + ls->m_ContourPoints->Reset(); + ls->m_ContourLines->Reset(); + + ls->m_UnselectedScales->Reset(); + ls->m_SelectedScales->Reset(); + + ls->m_DistancesBetweenPoints->Reset(); + + ls->m_VtkTextLabelActors.clear(); + ls->m_VtkTextDistanceActors.clear(); + ls->m_VtkTextAngleActors.clear(); + + ls->m_UnselectedScales->SetNumberOfComponents(3); + ls->m_SelectedScales->SetNumberOfComponents(3); + + int NumberContourPoints = 0; + bool pointsOnSameSideOfPlane = false; + + const int text2dDistance = 10; + + // current point in point set + itk::Point point; + + Point3D p; // currently visited point + Point3D lastP; // last visited point + Vector3D vec; // p - lastP + Vector3D lastVec; // lastP - point before lastP + vec.Fill(0); + + mitk::Point3D projected_p; // p projected on viewplane + + Point2D pt2d; // projected_p in display coordinates + Point2D lastPt2d; // last projected_p in display coordinates + Point2D preLastPt2d;// projected_p in display coordinates before lastPt2 + + + vtkLinearTransform* linearTransform = GetDataNode()->GetVtkTransform(); + + // get display geometry + mitk::DisplayGeometry::Pointer displayGeometry = renderer->GetDisplayGeometry(); + + // get plane geometry + mitk::PlaneGeometry::ConstPointer planeGeometry = renderer->GetSliceNavigationController()->GetCurrentPlaneGeometry(); + + int count = 0; + + for (pointsIter=itkPointSet->GetPoints()->Begin(); + pointsIter!=itkPointSet->GetPoints()->End(); + pointsIter++) + { + + lastP = p; // valid for number of points count > 0 + preLastPt2d = lastPt2d; // valid only for count > 1 + lastPt2d = pt2d; // valid for number of points count > 0 + + lastVec = vec; // valid only for counter > 1 + + // get current point in point set + point = pointsIter->Value(); + + p[0] = point[0]; + p[1] = point[1]; + p[2] = point[2]; + + displayGeometry->Project(p, projected_p); + displayGeometry->Map(projected_p, pt2d); + displayGeometry->WorldToDisplay(pt2d, pt2d); + + vec = p-lastP; // valid only for counter > 0 + + // compute distance to current plane + float diff = planeGeometry->DistanceFromPlane(point); + diff = diff * diff; + + //MouseOrientation + bool isInputDevice=false; + this->GetDataNode()->GetBoolProperty("inputdevice",isInputDevice); + + // if point is close to current plane ( distance < 4) it will be displayed + if(!isInputDevice && (diff < 4.0)) + { + + // is point selected or not? + if (pointDataIter->Value().selected) + { + ls->m_SelectedPoints->InsertNextPoint(point[0],point[1],point[2]); + // point is scaled according to its distance to the plane + ls->m_SelectedScales->InsertNextTuple3(m_Point2DSize - (2*diff),0,0); + } + else + { + ls->m_UnselectedPoints->InsertNextPoint(point[0],point[1],point[2]); + // point is scaled according to its distance to the plane + ls->m_UnselectedScales->InsertNextTuple3(m_Point2DSize - (2*diff),0,0); + } + + + //---- LABEL -----// + + // paint label for each point if available + if (dynamic_cast(this->GetDataNode()->GetProperty("label")) != NULL) + { + const char * pointLabel = dynamic_cast( + this->GetDataNode()->GetProperty("label"))->GetValue(); + std::string l = pointLabel; + if (input->GetSize()>1) + { + char buffer[20]; + sprintf(buffer,"%d",pointsIter->Index()); + std::stringstream ss; + ss << pointsIter->Index(); + l.append(ss.str()); + } + + ls->m_VtkTextActor = vtkSmartPointer::New(); + + ls->m_VtkTextActor->SetPosition(pt2d[0] + text2dDistance, pt2d[1] + text2dDistance); + ls->m_VtkTextActor->SetInput(l.c_str()); + ls->m_VtkTextActor->GetTextProperty()->SetOpacity( 100 ); + + float unselectedColor[4]; + + //check if there is a color property + GetDataNode()->GetColor(unselectedColor); + + if (unselectedColor != NULL) + ls->m_VtkTextActor->GetTextProperty()->SetColor(unselectedColor[0], unselectedColor[1], unselectedColor[2]); + else + ls->m_VtkTextActor->GetTextProperty()->SetColor(0.0f, 1.0f, 0.0f); + + ls->m_VtkTextLabelActors.push_back(ls->m_VtkTextActor); + + } + } + + // draw contour, distance text and angle text in render window + + // lines between points, which intersect the current plane, are drawn + if( m_Polygon && count > 0 ) + { + ScalarType distance = displayGeometry->GetWorldGeometry()->SignedDistance(point); + ScalarType lastDistance = displayGeometry->GetWorldGeometry()->SignedDistance(lastP); + + pointsOnSameSideOfPlane = (distance * lastDistance) > 0.5; + + // Points must be on different side of plane in order to draw a contour. + // If "show distant lines" is enabled this condition is disregarded. + if ( !pointsOnSameSideOfPlane || m_ShowDistantLines) + { + vtkSmartPointer line = vtkSmartPointer::New(); + + ls->m_ContourPoints->InsertNextPoint(lastP[0],lastP[1],lastP[2]); + line->GetPointIds()->SetId(0, NumberContourPoints); + NumberContourPoints++; + + ls->m_ContourPoints->InsertNextPoint(point[0], point[1], point[2]); + line->GetPointIds()->SetId(1, NumberContourPoints); + NumberContourPoints++; + + ls->m_ContourLines->InsertNextCell(line); + + + if(m_ShowDistances) // calculate and print distance between adjacent points + { + float distancePoints = point.EuclideanDistanceTo(lastP); + + std::stringstream buffer; + buffer<m_VtkTextActor = vtkSmartPointer::New(); + + ls->m_VtkTextActor->SetPosition(pos2d[0],pos2d[1]); + ls->m_VtkTextActor->SetInput(buffer.str().c_str()); + ls->m_VtkTextActor->GetTextProperty()->SetColor(0.0, 1.0, 0.0); + + ls->m_VtkTextDistanceActors.push_back(ls->m_VtkTextActor); + + } + + if(m_ShowAngles && count > 1) // calculate and print angle between connected lines + { + std::stringstream buffer; + //(char) 176 is the degree sign + buffer << angle(vec.GetVnlVector(), -lastVec.GetVnlVector())*180/vnl_math::pi << (char)176; + + //compute desired display position of text + Vector2D vec2d = pt2d-lastPt2d; // first arm enclosing the angle + vec2d.Normalize(); + Vector2D lastVec2d = lastPt2d-preLastPt2d; // second arm enclosing the angle + lastVec2d.Normalize(); + vec2d=vec2d-lastVec2d; // vector connecting both arms + vec2d.Normalize(); + + // middle between two vectors that enclose the angle + Vector2D pos2d = lastPt2d.GetVectorFromOrigin() + vec2d * text2dDistance * text2dDistance; + + ls->m_VtkTextActor = vtkSmartPointer::New(); + + ls->m_VtkTextActor->SetPosition(pos2d[0],pos2d[1]); + ls->m_VtkTextActor->SetInput(buffer.str().c_str()); + ls->m_VtkTextActor->GetTextProperty()->SetColor(0.0, 1.0, 0.0); + + ls->m_VtkTextAngleActors.push_back(ls->m_VtkTextActor); + } + } + } + + if(pointDataIter != itkPointSet->GetPointData()->End()) + { + pointDataIter++; + count++; + } + } + + // add each single text actor to the assembly + for(i=0; i< ls->m_VtkTextLabelActors.size(); i++) + { + ls->m_PropAssembly->AddPart(ls->m_VtkTextLabelActors.at(i)); + } + + for(i=0; i< ls->m_VtkTextDistanceActors.size(); i++) + { + ls->m_PropAssembly->AddPart(ls->m_VtkTextDistanceActors.at(i)); + } + + for(i=0; i< ls->m_VtkTextAngleActors.size(); i++) + { + ls->m_PropAssembly->AddPart(ls->m_VtkTextAngleActors.at(i)); + } + + //---- CONTOUR -----// + + + //create lines between the points which intersect the plane + if (m_Polygon) + { + // draw line between first and last point which is rendered + if(m_PolygonClosed && NumberContourPoints > 1){ + + vtkSmartPointer closingLine = vtkSmartPointer::New(); + closingLine->GetPointIds()->SetId(0, 0); // index of first point + closingLine->GetPointIds()->SetId(1, NumberContourPoints-1); // index of last point + ls->m_ContourLines->InsertNextCell(closingLine); + } + + ls->m_VtkContourPolyData->SetPoints(ls->m_ContourPoints); + ls->m_VtkContourPolyData->SetLines(ls->m_ContourLines); + + ls->m_VtkContourPolyDataMapper->SetInput(ls->m_VtkContourPolyData); + ls->m_ContourActor->SetMapper(ls->m_VtkContourPolyDataMapper); + ls->m_ContourActor->GetProperty()->SetLineWidth(m_LineWidth); + + ls->m_PropAssembly->AddPart(ls->m_ContourActor); + + } + + // the point set must be transformed in order to obtain the appropriate glyph orientation + // according to the current view + vtkSmartPointer transform = vtkSmartPointer::New(); + vtkSmartPointer a,b = vtkSmartPointer::New(); + + a = planeGeometry->GetVtkTransform()->GetMatrix(); + b->DeepCopy( a ); + + // delete transformation from matrix, only take orientation + b->SetElement(3,3,1); + b->SetElement(2,3,0); + b->SetElement(1,3,0); + b->SetElement(0,3,0); + b->SetElement(3,2,0); + b->SetElement(3,1,0); + b->SetElement(3,0,0); + + transform->SetMatrix( b ); + + //---- UNSELECTED POINTS -----// + + // apply properties to glyph + ls->m_UnselectedGlyphSource2D->SetGlyphType(m_IdGlyph); + + if(m_FillGlyphs) + ls->m_UnselectedGlyphSource2D->FilledOn(); + else + ls->m_UnselectedGlyphSource2D->FilledOff(); + + // apply transform + vtkSmartPointer transformFilterU = vtkSmartPointer::New(); + transformFilterU->SetInputConnection(ls->m_UnselectedGlyphSource2D->GetOutputPort()); + transformFilterU->SetTransform(transform); + + ls->m_VtkUnselectedPointListPolyData->SetPoints(ls->m_UnselectedPoints); + ls->m_VtkUnselectedPointListPolyData->GetPointData()->SetVectors(ls->m_UnselectedScales); + + // apply transform of current plane to glyphs + ls->m_UnselectedGlyph3D->SetSourceConnection(transformFilterU->GetOutputPort()); + ls->m_UnselectedGlyph3D->SetInput(ls->m_VtkUnselectedPointListPolyData); + ls->m_UnselectedGlyph3D->SetScaleModeToScaleByVector(); + ls->m_UnselectedGlyph3D->SetVectorModeToUseVector(); + + ls->m_VtkUnselectedPolyDataMapper->SetInput(ls->m_UnselectedGlyph3D->GetOutput()); + ls->m_UnselectedActor->SetMapper(ls->m_VtkUnselectedPolyDataMapper); + ls->m_UnselectedActor->GetProperty()->SetLineWidth(m_PointLineWidth); + + ls->m_PropAssembly->AddPart(ls->m_UnselectedActor); + + + //---- SELECTED POINTS -----// + + ls->m_SelectedGlyphSource2D->SetGlyphTypeToDiamond(); + ls->m_SelectedGlyphSource2D->CrossOn(); + ls->m_SelectedGlyphSource2D->FilledOff(); + + // apply transform + vtkSmartPointer transformFilterS = vtkSmartPointer::New(); + transformFilterS->SetInputConnection(ls->m_SelectedGlyphSource2D->GetOutputPort()); + transformFilterS->SetTransform(transform); + + ls->m_VtkSelectedPointListPolyData->SetPoints(ls->m_SelectedPoints); + ls->m_VtkSelectedPointListPolyData->GetPointData()->SetVectors(ls->m_SelectedScales); + + + // apply transform of current plane to glyphs + ls->m_SelectedGlyph3D->SetSourceConnection(transformFilterS->GetOutputPort()); + ls->m_SelectedGlyph3D->SetInput(ls->m_VtkSelectedPointListPolyData); + ls->m_SelectedGlyph3D->SetScaleModeToScaleByVector(); + ls->m_SelectedGlyph3D->SetVectorModeToUseVector(); + + ls->m_VtkSelectedPolyDataMapper->SetInput(ls->m_SelectedGlyph3D->GetOutput()); + ls->m_SelectedActor->SetMapper(ls->m_VtkSelectedPolyDataMapper); + ls->m_SelectedActor->GetProperty()->SetLineWidth(m_PointLineWidth); + + ls->m_PropAssembly->AddPart(ls->m_SelectedActor); + +} + + +void mitk::PointSetVtkMapper2D::GenerateDataForRenderer( mitk::BaseRenderer *renderer ) +{ + + const mitk::DataNode* node = GetDataNode(); + if( node == NULL ) + return; + + LocalStorage *ls = m_LSH.GetLocalStorage(renderer); + bool needGenerateData = ls->IsGenerateDataRequired( renderer, this, GetDataNode() ); + + // toggle visibility + bool visible = true; + node->GetVisibility(visible, renderer, "visible"); + if(!visible) + { + ls->m_UnselectedActor->VisibilityOff(); + ls->m_SelectedActor->VisibilityOff(); + ls->m_ContourActor->VisibilityOff(); + ls->m_PropAssembly->VisibilityOff(); + return; + }else{ + ls->m_PropAssembly->VisibilityOn(); + } + + node->GetBoolProperty("show contour", m_Polygon, renderer); + node->GetBoolProperty("close contour", m_PolygonClosed, renderer); + node->GetBoolProperty("show points", m_ShowPoints, renderer); + node->GetBoolProperty("show distances", m_ShowDistances, renderer); + node->GetIntProperty("distance decimal digits", m_DistancesDecimalDigits, renderer); + node->GetBoolProperty("show angles", m_ShowAngles, renderer); + node->GetBoolProperty("show distant lines", m_ShowDistantLines, renderer); + node->GetIntProperty("line width", m_LineWidth, renderer); + node->GetIntProperty("point line width", m_PointLineWidth, renderer); + node->GetIntProperty("point 2D size", m_Point2DSize, renderer); + mitk::EnumerationProperty* eP = dynamic_cast (node->GetProperty("Pointset.2D.shape", renderer)); + m_IdGlyph = eP->GetValueAsId(); + node->GetBoolProperty("Pointset.2D.fill shape", m_FillGlyphs, renderer); + + + //check for color props and use it for rendering of selected/unselected points and contour + //due to different params in VTK (double/float) we have to convert + + + float unselectedColor[4]; + vtkFloatingPointType selectedColor[4]={1.0f,0.0f,0.0f,1.0f}; //red + vtkFloatingPointType contourColor[4]={1.0f,0.0f,0.0f,1.0f}; //red + + //different types for color + mitk::Color tmpColor; + float opacity = 1.0; + + GetDataNode()->GetOpacity(opacity, renderer); + + // apply color and opacity + if(m_ShowPoints) + { + ls->m_UnselectedActor->VisibilityOn(); + ls->m_SelectedActor->VisibilityOn(); + + //check if there is a color property + GetDataNode()->GetColor(unselectedColor); + + //get selected color property + if (dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("selectedcolor")) != NULL) + { + tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("selectedcolor"))->GetValue(); + + } + else if (dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("selectedcolor")) != NULL) + { + tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("selectedcolor"))->GetValue(); + } + + selectedColor[0] = tmpColor[0]; + selectedColor[1] = tmpColor[1]; + selectedColor[2] = tmpColor[2]; + selectedColor[3] = 1.0f; // alpha value + + ls->m_SelectedActor->GetProperty()->SetColor(selectedColor); + ls->m_SelectedActor->GetProperty()->SetOpacity(opacity); + + ls->m_UnselectedActor->GetProperty()->SetColor(unselectedColor[0],unselectedColor[1],unselectedColor[2]); + ls->m_UnselectedActor->GetProperty()->SetOpacity(opacity); + + } + else + { + ls->m_UnselectedActor->VisibilityOff(); + ls-> m_SelectedActor->VisibilityOff(); + } + + + if (m_Polygon) + { + ls->m_ContourActor->VisibilityOn(); + + //get contour color property + if (dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("contourcolor")) != NULL) + { + tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("contourcolor"))->GetValue(); + } + else if (dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("contourcolor")) != NULL) + { + tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("contourcolor"))->GetValue(); + } + + contourColor[0] = tmpColor[0]; + contourColor[1] = tmpColor[1]; + contourColor[2] = tmpColor[2]; + contourColor[3] = 1.0f; + + ls->m_ContourActor->GetProperty()->SetColor(contourColor); + ls->m_ContourActor->GetProperty()->SetOpacity(opacity); + } + else + { + ls->m_ContourActor->VisibilityOff(); + } + + if(needGenerateData) + { + // create new vtk render objects (e.g. a circle for a point) + this->CreateVTKRenderObjects(renderer); + } + +} + + + +void mitk::PointSetVtkMapper2D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) +{ + node->AddProperty( "line width", mitk::IntProperty::New(2), renderer, overwrite ); + node->AddProperty( "point line width", mitk::IntProperty::New(1), renderer, overwrite ); + node->AddProperty( "point 2D size", mitk::IntProperty::New(6), renderer, overwrite ); + node->AddProperty( "show contour", mitk::BoolProperty::New(false), renderer, overwrite ); + node->AddProperty( "close contour", mitk::BoolProperty::New(false), renderer, overwrite ); + node->AddProperty( "show points", mitk::BoolProperty::New(true), renderer, overwrite ); + node->AddProperty( "show distances", mitk::BoolProperty::New(false), renderer, overwrite ); + node->AddProperty( "distance decimal digits", mitk::IntProperty::New(2), renderer, overwrite ); + node->AddProperty( "show angles", mitk::BoolProperty::New(false), renderer, overwrite ); + node->AddProperty( "show distant lines", mitk::BoolProperty::New(false), renderer, overwrite ); + node->AddProperty( "layer", mitk::IntProperty::New(1), renderer, overwrite ); + + mitk::EnumerationProperty::Pointer glyphType = mitk::EnumerationProperty::New(); + glyphType->AddEnum("None", 0); + glyphType->AddEnum("Vertex", 1); + glyphType->AddEnum("Dash", 2); + glyphType->AddEnum("Cross", 3); + glyphType->AddEnum("ThickCross", 4); + glyphType->AddEnum("Triangle", 5); + glyphType->AddEnum("Square", 6); + glyphType->AddEnum("Circle", 7); + glyphType->AddEnum("Diamond", 8); + glyphType->AddEnum("Arrow", 9); + glyphType->AddEnum("ThickArrow", 10); + glyphType->AddEnum("HookedArrow", 11); + glyphType->SetValue("Cross"); + node->AddProperty( "Pointset.2D.shape", glyphType, renderer, overwrite); + + node->AddProperty("Pointset.2D.fill shape", mitk::BoolProperty::New(false), renderer, overwrite); // fill or do not fill the glyph shape + + Superclass::SetDefaultProperties(node, renderer, overwrite); +} diff --git a/Core/Code/Rendering/mitkPointSetVtkMapper2D.h b/Core/Code/Rendering/mitkPointSetVtkMapper2D.h new file mode 100644 index 0000000000..589867196a --- /dev/null +++ b/Core/Code/Rendering/mitkPointSetVtkMapper2D.h @@ -0,0 +1,215 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#ifndef MITKPointSetVtkMAPPER2D_H_HEADER_INCLUDED_C1902626 +#define MITKPointSetVtkMAPPER2D_H_HEADER_INCLUDED_C1902626 + +#include +#include "mitkVtkMapper.h" +#include "mitkBaseRenderer.h" +#include "mitkLocalStorageHandler.h" +#include +#include +#include +#include +#include +#include +#include + +class vtkActor; +class vtkPropAssembly; +class vtkAppendPolyData; +class vtkPolyData; +class vtkTubeFilter; +class vtkPolyDataMapper; +class vtkGlyphSource2D; +class vtkSphereSource; +class vtkGlyph3D; +class vtkFloatArray; + + +namespace mitk { + + class PointSet; + + /** + * @brief Vtk-based 2D mapper for PointSet + * + * Due to the need of different colors for selected + * and unselected points and the facts, that we also have a contour and + * labels for the points, the vtk structure is build up the following way: + * + * We have three PolyData, one selected, and one unselected and one + * for a contour between the points. Each one is connected to an own + * PolyDataMapper and an Actor. The different color for the unselected and + * selected state and for the contour is read from properties. + * + * This mapper has several additional functionalities, such as rendering + * a contour between points, calculating and displaying distances or angles + * between points. + * + * Then the three Actors are combined inside a vtkPropAssembly and this + * object is returned in GetProp() and so hooked up into the rendering + * pipeline. + + * Properties that can be set for point sets and influence the PointSetVTKMapper2D are: + * + * - \b "line width": (IntProperty 2) // line width of the line from one point to another + * - \b "point line width": (IntProperty 1) // line width of the cross marking a point + * - \b "point 2D size": (IntProperty 6) // size of the glyph marking a point + * - \b "show contour": (BoolProperty false) // enable contour rendering between points (lines) + * - \b "close contour": (BoolProperty false) // if enabled, the open strip is closed (first point connected with last point) + * - \b "show points": (BoolProperty true) // show or hide points + * - \b "show distances": (BoolProperty false) // show or hide distance measure + * - \b "distance decimal digits": (IntProperty 2) // set the number of decimal digits to be shown when rendering the distance information + * - \b "show angles": (BoolProperty false) // show or hide angle measurement + * - \b "show distant lines": (BoolProperty false) // show the line between to points from a distant view (equals "always on top" option) + * - \b "layer": (IntProperty 1) // default is drawing pointset above images (they have a default layer of 0) + * - \b "PointSet.2D.shape" (EnumerationProperty Cross) // provides different shapes marking a point + * 0 = "None", 1 = "Vertex", 2 = "Dash", 3 = "Cross", 4 = "ThickCross", 5 = "Triangle", 6 = "Square", 7 = "Circle", + * 8 = "Diamond", 9 = "Arrow", 10 = "ThickArrow", 11 = "HookedArrow", 12 = "Cross" + * - \b "PointSet.2D.fill shape": (BoolProperty::New(false)) // fill or do not fill the glyph shape + * + * + * Other Properties used here but not defined in this class: + * + * - \b "selectedcolor": (ColorProperty (1.0f, 0.0f, 0.0f)) // default color of the selected pointset e.g. the current point is red + * - \b "contourcolor" : (ColorProperty (1.0f, 0.0f, 0.0f)) // default color for the contour is red + * - \b "color": (ColorProperty (1.0f, 1.0f, 0.0f)) // default color of the (unselected) pointset is yellow + * - \b "opacity": (FloatProperty 1.0) // opacity of point set, contours + * - \b "label": (StringProperty NULL) // a label can be defined for each point, which is rendered in proximity to the point + * + * @ingroup Mapper + */ + class MITK_CORE_EXPORT PointSetVtkMapper2D : public VtkMapper + { + public: + mitkClassMacro(PointSetVtkMapper2D, VtkMapper); + + itkNewMacro(Self); + + virtual const mitk::PointSet* GetInput(); + + /** \brief returns the a prop assembly */ + virtual vtkProp* GetVtkProp(mitk::BaseRenderer* renderer); + + /** \brief set the default properties for this mapper */ + static void SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer = NULL, bool overwrite = false); + + /** \brief Internal class holding the mapper, actor, etc. for each of the 3 2D render windows */ + class LocalStorage : public mitk::Mapper::BaseLocalStorage + { + + public: + + /* constructor */ + LocalStorage(); + + /* destructor */ + ~LocalStorage(); + + // points + vtkSmartPointer m_UnselectedPoints; + vtkSmartPointer m_SelectedPoints; + vtkSmartPointer m_ContourPoints; + + // scales + vtkSmartPointer m_UnselectedScales; + vtkSmartPointer m_SelectedScales; + + // distances + vtkSmartPointer m_DistancesBetweenPoints; + + // lines + vtkSmartPointer m_ContourLines; + + // glyph source (provides different shapes for the points) + vtkSmartPointer m_UnselectedGlyphSource2D; + vtkSmartPointer m_SelectedGlyphSource2D; + + // glyph + vtkSmartPointer m_UnselectedGlyph3D; + vtkSmartPointer m_SelectedGlyph3D; + + // polydata + vtkSmartPointer m_VtkUnselectedPointListPolyData; + vtkSmartPointer m_VtkSelectedPointListPolyData; + vtkSmartPointer m_VtkContourPolyData; + + // actor + vtkSmartPointer m_UnselectedActor; + vtkSmartPointer m_SelectedActor; + vtkSmartPointer m_ContourActor; + vtkSmartPointer m_VtkTextActor; + + std::vector < vtkSmartPointer > m_VtkTextLabelActors; + std::vector < vtkSmartPointer > m_VtkTextDistanceActors; + std::vector < vtkSmartPointer > m_VtkTextAngleActors; + + // mappers + vtkSmartPointer m_VtkUnselectedPolyDataMapper; + vtkSmartPointer m_VtkSelectedPolyDataMapper; + vtkSmartPointer m_VtkContourPolyDataMapper; + + // propassembly + vtkSmartPointer m_PropAssembly; + + }; + + /** \brief The LocalStorageHandler holds all (three) LocalStorages for the three 2D render windows. */ + mitk::LocalStorageHandler m_LSH; + + + protected: + + /* constructor */ + PointSetVtkMapper2D(); + + /* destructor */ + virtual ~PointSetVtkMapper2D(); + + /* \brief Applies the color and opacity properties and calls CreateVTKRenderObjects */ + virtual void GenerateDataForRenderer(mitk::BaseRenderer* renderer); + /* \brief Toggles visiblity of the propassembly */ + virtual void ResetMapper( BaseRenderer* renderer ); + /* \brief Fills the vtk objects, thus it is only called when the point set has been changed. + * This function iterates over the input point set and uses a specific shape defined in vtk glyph source + * to mark each point. The glyphs need to be rotated in the 2D- render windows + * in order to be ortogonal to the view vector. Therefore, the rotation of the current PlaneGeometry is + * used to determine the appropriate orienation of the glyphs. */ + virtual void CreateVTKRenderObjects(mitk::BaseRenderer* renderer); + + // properties + bool m_Polygon; + bool m_PolygonClosed; + bool m_ShowPoints; + bool m_ShowDistances; + int m_DistancesDecimalDigits; + bool m_ShowAngles; + bool m_ShowDistantLines; + int m_LineWidth; + int m_PointLineWidth; + int m_Point2DSize; + int m_IdGlyph; + bool m_FillGlyphs; + + }; + + +} // namespace mitk + +#endif /* MITKPointSetVtkMAPPER2D_H_HEADER_INCLUDED_C1902626 */ diff --git a/Core/Code/Rendering/mitkVtkMapper2D.h b/Core/Code/Rendering/mitkVtkMapper2D.h index f9db3be352..1c18e0ef19 100644 --- a/Core/Code/Rendering/mitkVtkMapper2D.h +++ b/Core/Code/Rendering/mitkVtkMapper2D.h @@ -1,32 +1,32 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef BASEVTKMAPPER2D_H_HEADER_INCLUDED #define BASEVTKMAPPER2D_H_HEADER_INCLUDED #include "mitkVtkMapper.h" namespace mitk { // typedef allows integration of mappers into the new mapper architecture - // @deprecated Use VtkMapper instead. + // \deprecatedSince{2013_03} Use VtkMapper instead. DEPRECATED(typedef VtkMapper VtkMapper2D); } // namespace mitk #endif /* BASEVTKMAPPER2D_H_HEADER_INCLUDED */ diff --git a/Core/Code/Rendering/mitkVtkMapper3D.h b/Core/Code/Rendering/mitkVtkMapper3D.h index f31560ec0f..1958ac3614 100644 --- a/Core/Code/Rendering/mitkVtkMapper3D.h +++ b/Core/Code/Rendering/mitkVtkMapper3D.h @@ -1,31 +1,31 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef BASEVTKMAPPER3D_H_HEADER_INCLUDED #define BASEVTKMAPPER3D_H_HEADER_INCLUDED #include "mitkVtkMapper.h" namespace mitk { // typedef allows integration of mappers into the new mapper architecture - // @deprecated Use VtkMapper instead + // \deprecatedSince{2013_03} Use VtkMapper instead DEPRECATED(typedef VtkMapper VtkMapper3D); } // namespace mitk #endif /* BASEVTKMAPPER3D_H_HEADER_INCLUDED */ diff --git a/Core/Code/Rendering/mitkVtkPropRenderer.cpp b/Core/Code/Rendering/mitkVtkPropRenderer.cpp index 22e1a83215..60a42fefbc 100644 --- a/Core/Code/Rendering/mitkVtkPropRenderer.cpp +++ b/Core/Code/Rendering/mitkVtkPropRenderer.cpp @@ -1,927 +1,926 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkVtkPropRenderer.h" // MAPPERS #include "mitkMapper.h" #include "mitkImageVtkMapper2D.h" #include "mitkVtkMapper.h" #include "mitkGLMapper.h" #include "mitkGeometry2DDataVtkMapper3D.h" -#include "mitkPointSetGLMapper2D.h" #include "mitkImageSliceSelector.h" #include "mitkRenderingManager.h" #include "mitkGL.h" #include "mitkGeometry3D.h" #include "mitkDisplayGeometry.h" #include "mitkLevelWindow.h" #include "mitkCameraController.h" #include "mitkVtkInteractorCameraController.h" #include "mitkPlaneGeometry.h" #include "mitkProperties.h" #include "mitkSurface.h" #include "mitkNodePredicateDataType.h" #include "mitkVtkInteractorStyle.h" // VTK #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include mitk::VtkPropRenderer::VtkPropRenderer( const char* name, vtkRenderWindow * renWin, mitk::RenderingManager* rm ) : BaseRenderer(name,renWin, rm), m_VtkMapperPresent(false), m_CameraInitializedForMapperID(0) { didCount=false; m_WorldPointPicker = vtkWorldPointPicker::New(); m_PointPicker = vtkPointPicker::New(); m_PointPicker->SetTolerance( 0.0025 ); m_CellPicker = vtkCellPicker::New(); m_CellPicker->SetTolerance( 0.0025 ); mitk::Geometry2DDataVtkMapper3D::Pointer geometryMapper = mitk::Geometry2DDataVtkMapper3D::New(); m_CurrentWorldGeometry2DMapper = geometryMapper; m_CurrentWorldGeometry2DNode->SetMapper(2, geometryMapper); m_LightKit = vtkLightKit::New(); m_LightKit->AddLightsToRenderer(m_VtkRenderer); m_PickingMode = WorldPointPicking; m_TextRenderer = vtkRenderer::New(); m_TextRenderer->SetRenderWindow(renWin); m_TextRenderer->SetInteractive(0); m_TextRenderer->SetErase(0); } /*! \brief Destructs the VtkPropRenderer. */ mitk::VtkPropRenderer::~VtkPropRenderer() { // Workaround for GLDisplayList Bug { m_MapperID=0; checkState(); } if (m_LightKit != NULL) m_LightKit->Delete(); if (m_VtkRenderer!=NULL) { m_CameraController = NULL; m_VtkRenderer->Delete(); m_VtkRenderer = NULL; } else m_CameraController = NULL; if (m_WorldPointPicker != NULL) m_WorldPointPicker->Delete(); if (m_PointPicker != NULL) m_PointPicker->Delete(); if (m_CellPicker != NULL) m_CellPicker->Delete(); if (m_TextRenderer != NULL) m_TextRenderer->Delete(); } void mitk::VtkPropRenderer::SetDataStorage( mitk::DataStorage* storage ) { if ( storage == NULL ) return; BaseRenderer::SetDataStorage(storage); static_cast(m_CurrentWorldGeometry2DMapper.GetPointer())->SetDataStorageForTexture( m_DataStorage.GetPointer() ); // Compute the geometry from the current data tree bounds and set it as world geometry this->SetWorldGeometryToDataStorageBounds(); } bool mitk::VtkPropRenderer::SetWorldGeometryToDataStorageBounds() { if ( m_DataStorage.IsNull() ) return false; //initialize world geometry mitk::TimeSlicedGeometry::Pointer geometry = m_DataStorage->ComputeVisibleBoundingGeometry3D( NULL, "includeInBoundingBox" ); if ( geometry.IsNull() ) return false; this->SetWorldGeometry(geometry); //this->GetDisplayGeometry()->SetSizeInDisplayUnits( this->m_TextRenderer->GetRenderWindow()->GetSize()[0], this->m_TextRenderer->GetRenderWindow()->GetSize()[1] ); this->GetDisplayGeometry()->Fit(); this->GetVtkRenderer()->ResetCamera(); this->Modified(); return true; } /*! \brief Called by the vtkMitkRenderProp in order to start MITK rendering process. */ int mitk::VtkPropRenderer::Render(mitk::VtkPropRenderer::RenderType type) { // Do we have objects to render? if ( this->GetEmptyWorldGeometry()) return 0; if ( m_DataStorage.IsNull()) return 0; // Update mappers and prepare mapper queue if (type == VtkPropRenderer::Opaque) this->PrepareMapperQueue(); //go through the generated list and let the sorted mappers paint bool lastVtkBased = true; //bool sthVtkBased = false; for(MappersMapType::iterator it = m_MappersMap.begin(); it != m_MappersMap.end(); it++) { Mapper * mapper = (*it).second; VtkMapper* vtkmapper = dynamic_cast(mapper); if(vtkmapper) { //sthVtkBased = true; if(!lastVtkBased) { Disable2DOpenGL(); lastVtkBased = true; } } else if(lastVtkBased) { Enable2DOpenGL(); lastVtkBased = false; } mapper->MitkRender(this, type); } if (lastVtkBased == false) Disable2DOpenGL(); // Render text if (type == VtkPropRenderer::Overlay) { if (m_TextCollection.size() > 0) { for (TextMapType::iterator it = m_TextCollection.begin(); it != m_TextCollection.end() ; it++) m_TextRenderer->AddViewProp((*it).second); m_TextRenderer->Render(); } } return 1; } /*! \brief PrepareMapperQueue iterates the datatree PrepareMapperQueue iterates the datatree in order to find mappers which shall be rendered. Also, it sortes the mappers wrt to their layer. */ void mitk::VtkPropRenderer::PrepareMapperQueue() { // variable for counting LOD-enabled mappers m_NumberOfVisibleLODEnabledMappers = 0; // Do we have to update the mappers ? if ( m_LastUpdateTime < GetMTime() || m_LastUpdateTime < GetDisplayGeometry()->GetMTime() ) { Update(); } else if (m_MapperID>=1 && m_MapperID < 6) Update(); // remove all text properties before mappers will add new ones m_TextRenderer->RemoveAllViewProps(); for ( unsigned int i=0; iDelete(); } m_TextCollection.clear(); // clear priority_queue m_MappersMap.clear(); int mapperNo = 0; //DataStorage if( m_DataStorage.IsNull() ) return; DataStorage::SetOfObjects::ConstPointer allObjects = m_DataStorage->GetAll(); for (DataStorage::SetOfObjects::ConstIterator it = allObjects->Begin(); it != allObjects->End(); ++it) { DataNode::Pointer node = it->Value(); if ( node.IsNull() ) continue; mitk::Mapper::Pointer mapper = node->GetMapper(m_MapperID); if ( mapper.IsNull() ) continue; bool visible = true; node->GetVisibility(visible, this, "visible"); // The information about LOD-enabled mappers is required by RenderingManager if ( mapper->IsLODEnabled( this ) && visible ) { ++m_NumberOfVisibleLODEnabledMappers; } // mapper without a layer property get layer number 1 int layer = 1; node->GetIntProperty("layer", layer, this); int nr = (layer<<16) + mapperNo; m_MappersMap.insert( std::pair< int, Mapper * >( nr, mapper ) ); mapperNo++; } } /*! \brief Enable2DOpenGL() and Disable2DOpenGL() are used to switch between 2D rendering (orthographic projection) and 3D rendering (perspective projection) */ void mitk::VtkPropRenderer::Enable2DOpenGL() { GLint iViewport[4]; // Get a copy of the viewport glGetIntegerv( GL_VIEWPORT, iViewport ); // Save a copy of the projection matrix so that we can restore it // when it's time to do 3D rendering again. glMatrixMode( GL_PROJECTION ); glPushMatrix(); glLoadIdentity(); // Set up the orthographic projection glOrtho( iViewport[0], iViewport[0]+iViewport[2], iViewport[1], iViewport[1]+iViewport[3], -1.0, 1.0 ); glMatrixMode( GL_MODELVIEW ); glPushMatrix(); glLoadIdentity(); // Make sure depth testing and lighting are disabled for 2D rendering until // we are finished rendering in 2D glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_LIGHTING_BIT ); glDisable( GL_DEPTH_TEST ); glDisable( GL_LIGHTING ); // disable the texturing here so crosshair is painted in the correct colors // vtk will reenable texturing every time it is needed glDisable( GL_TEXTURE_1D ); glDisable( GL_TEXTURE_2D ); glLineWidth(1.0); } /*! \brief Initialize the VtkPropRenderer Enable2DOpenGL() and Disable2DOpenGL() are used to switch between 2D rendering (orthographic projection) and 3D rendering (perspective projection) */ void mitk::VtkPropRenderer::Disable2DOpenGL() { glPopAttrib(); glMatrixMode( GL_PROJECTION ); glPopMatrix(); glMatrixMode( GL_MODELVIEW ); glPopMatrix(); } void mitk::VtkPropRenderer::Update(mitk::DataNode* datatreenode) { if(datatreenode!=NULL) { mitk::Mapper::Pointer mapper = datatreenode->GetMapper(m_MapperID); if(mapper.IsNotNull()) { GLMapper* glmapper=dynamic_cast(mapper.GetPointer()); if(GetDisplayGeometry()->IsValid()) { if(glmapper != NULL) { glmapper->Update(this); m_VtkMapperPresent=false; } else { VtkMapper* vtkmapper=dynamic_cast(mapper.GetPointer()); if(vtkmapper != NULL) { vtkmapper->Update(this); vtkmapper->UpdateVtkTransform(this); m_VtkMapperPresent=true; } } } } } } void mitk::VtkPropRenderer::Update() { if( m_DataStorage.IsNull() ) return; m_VtkMapperPresent = false; mitk::DataStorage::SetOfObjects::ConstPointer all = m_DataStorage->GetAll(); for (mitk::DataStorage::SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it) Update(it->Value()); Modified(); m_LastUpdateTime = GetMTime(); } /*! \brief This method is called from the two Constructors */ void mitk::VtkPropRenderer::InitRenderer(vtkRenderWindow* renderWindow) { BaseRenderer::InitRenderer(renderWindow); if(renderWindow == NULL) { m_InitNeeded = false; m_ResizeNeeded = false; return; } m_InitNeeded = true; m_ResizeNeeded = true; m_LastUpdateTime = 0; } /*! \brief Resize the OpenGL Window */ void mitk::VtkPropRenderer::Resize(int w, int h) { BaseRenderer::Resize(w, h); m_RenderingManager->RequestUpdate(this->GetRenderWindow()); } void mitk::VtkPropRenderer::InitSize(int w, int h) { m_RenderWindow->SetSize(w,h); Superclass::InitSize(w, h); Modified(); Update(); if(m_VtkRenderer!=NULL) { int w=vtkObject::GetGlobalWarningDisplay(); vtkObject::GlobalWarningDisplayOff(); m_VtkRenderer->ResetCamera(); vtkObject::SetGlobalWarningDisplay(w); } } void mitk::VtkPropRenderer::SetMapperID(const MapperSlotId mapperId) { if(m_MapperID != mapperId) Superclass::SetMapperID(mapperId); // Workaround for GL Displaylist Bug checkState(); } /*! \brief Activates the current renderwindow. */ void mitk::VtkPropRenderer::MakeCurrent() { if(m_RenderWindow!=NULL) m_RenderWindow->MakeCurrent(); } void mitk::VtkPropRenderer::PickWorldPoint(const mitk::Point2D& displayPoint, mitk::Point3D& worldPoint) const { if(m_VtkMapperPresent) { //m_WorldPointPicker->SetTolerance (0.0001); switch ( m_PickingMode ) { case (WorldPointPicking) : { m_WorldPointPicker->Pick(displayPoint[0], displayPoint[1], 0, m_VtkRenderer); vtk2itk(m_WorldPointPicker->GetPickPosition(), worldPoint); break; } case (PointPicking) : { // create a new vtkRenderer // give it all necessary information (camera position, etc.) // get all surfaces from datastorage, get actors from them // add all those actors to the new renderer // give this new renderer to pointpicker /* vtkRenderer* pickingRenderer = vtkRenderer::New(); pickingRenderer->SetActiveCamera( ); DataStorage* dataStorage = m_DataStorage; TNodePredicateDataType isSurface; DataStorage::SetOfObjects::ConstPointer allSurfaces = dataStorage->GetSubset( isSurface ); MITK_INFO << "in picking: got " << allSurfaces->size() << " surfaces." << std::endl; for (DataStorage::SetOfObjects::const_iterator iter = allSurfaces->begin(); iter != allSurfaces->end(); ++iter) { const DataNode* currentNode = *iter; VtkMapper3D* baseVtkMapper3D = dynamic_cast( currentNode->GetMapper( BaseRenderer::Standard3D ) ); if ( baseVtkMapper3D ) { vtkActor* actor = dynamic_cast( baseVtkMapper3D->GetViewProp() ); if (actor) { MITK_INFO << "a" << std::flush; pickingRenderer->AddActor( actor ); } } } MITK_INFO << ";" << std::endl; */ m_PointPicker->Pick(displayPoint[0], displayPoint[1], 0, m_VtkRenderer); vtk2itk(m_PointPicker->GetPickPosition(), worldPoint); break; } } } else { Superclass::PickWorldPoint(displayPoint, worldPoint); } } mitk::DataNode * mitk::VtkPropRenderer::PickObject( const Point2D &displayPosition, Point3D &worldPosition ) const { if ( m_VtkMapperPresent ) { m_CellPicker->InitializePickList(); // Iterate over all DataStorage objects to determine all vtkProps intended // for picking DataStorage::SetOfObjects::ConstPointer allObjects = m_DataStorage->GetAll(); for ( DataStorage::SetOfObjects::ConstIterator it = allObjects->Begin(); it != allObjects->End(); ++it ) { DataNode *node = it->Value(); if ( node == NULL ) continue; bool pickable = false; node->GetBoolProperty( "pickable", pickable ); if ( !pickable ) continue; VtkMapper *mapper = dynamic_cast < VtkMapper * > ( node->GetMapper( m_MapperID ) ); if ( mapper == NULL ) continue; vtkProp *prop = mapper->GetVtkProp( (mitk::BaseRenderer *)this ); if ( prop == NULL ) continue; m_CellPicker->AddPickList( prop ); } // Do the picking and retrieve the picked vtkProp (if any) m_CellPicker->PickFromListOn(); m_CellPicker->Pick( displayPosition[0], displayPosition[1], 0.0, m_VtkRenderer ); m_CellPicker->PickFromListOff(); vtk2itk( m_CellPicker->GetPickPosition(), worldPosition ); vtkProp *prop = m_CellPicker->GetViewProp(); if ( prop == NULL ) { return NULL; } // Iterate over all DataStorage objects to determine if the retrieved // vtkProp is owned by any associated mapper. for ( DataStorage::SetOfObjects::ConstIterator it = allObjects->Begin(); it != allObjects->End(); ++it) { DataNode::Pointer node = it->Value(); if ( node.IsNull() ) continue; mitk::Mapper * mapper = node->GetMapper( m_MapperID ); if ( mapper == NULL) continue; mitk::VtkMapper * vtkmapper = dynamic_cast< VtkMapper * >(mapper); if(vtkmapper){ //if vtk-based, then ... if ( vtkmapper->HasVtkProp( prop, const_cast< mitk::VtkPropRenderer * >( this ) ) ) { return node; } } } return NULL; } else { return Superclass::PickObject( displayPosition, worldPosition ); } }; /*! \brief Writes some 2D text as overlay. Function returns an unique int Text_ID for each call, which can be used via the GetTextLabelProperty(int text_id) function in order to get a vtkTextProperty. This property enables the setup of font, font size, etc. */ int mitk::VtkPropRenderer::WriteSimpleText(std::string text, double posX, double posY, double color1, double color2, double color3, float opacity) { if(text.size() > 0) { vtkTextActor* textActor = vtkTextActor::New(); textActor->SetPosition(posX,posY); textActor->SetInput(text.c_str()); textActor->GetTextProperty()->SetColor(color1, color2, color3); //TODO: Read color from node property textActor->GetTextProperty()->SetOpacity( opacity ); int text_id = m_TextCollection.size(); m_TextCollection.insert(TextMapType::value_type(text_id,textActor)); return text_id; } return -1; } /*! \brief Can be used in order to get a vtkTextProperty for a specific text_id. This property enables the setup of font, font size, etc. */ vtkTextProperty* mitk::VtkPropRenderer::GetTextLabelProperty(int text_id) { return this->m_TextCollection[text_id]->GetTextProperty(); } void mitk::VtkPropRenderer::InitPathTraversal() { if (m_DataStorage.IsNotNull()) { m_PickingObjects = m_DataStorage->GetAll(); m_PickingObjectsIterator = m_PickingObjects->begin(); } } vtkAssemblyPath* mitk::VtkPropRenderer::GetNextPath() { if (m_DataStorage.IsNull() ) { return NULL; } if ( m_PickingObjectsIterator == m_PickingObjects->end() ) { return NULL; } vtkAssemblyPath* returnPath = vtkAssemblyPath::New(); //returnPath->Register(NULL); bool success = false; while (!success) { // loop until AddNode can be called successfully const DataNode* node = *m_PickingObjectsIterator; if (node) { Mapper* mapper = node->GetMapper( BaseRenderer::Standard3D ); if (mapper) { VtkMapper* vtkmapper = dynamic_cast( mapper ); if (vtkmapper) { vtkProp* prop = vtkmapper->GetVtkProp(this); if ( prop && prop->GetVisibility() ) { // add to assembly path returnPath->AddNode( prop, prop->GetMatrix() ); success = true; } } } } ++m_PickingObjectsIterator; if ( m_PickingObjectsIterator == m_PickingObjects->end() ) break; } if ( success ) { return returnPath; } else { return NULL; } } void mitk::VtkPropRenderer::ReleaseGraphicsResources(vtkWindow *renWin) { if( m_DataStorage.IsNull() ) return; DataStorage::SetOfObjects::ConstPointer allObjects = m_DataStorage->GetAll(); for (DataStorage::SetOfObjects::const_iterator iter = allObjects->begin(); iter != allObjects->end(); ++iter) { DataNode::Pointer node = *iter; if ( node.IsNull() ) continue; Mapper * mapper = node->GetMapper(m_MapperID); if (mapper) { VtkMapper* vtkmapper = dynamic_cast( mapper ); if(vtkmapper) vtkmapper->ReleaseGraphicsResources(renWin); } } } const vtkWorldPointPicker *mitk::VtkPropRenderer::GetWorldPointPicker() const { return m_WorldPointPicker; } const vtkPointPicker *mitk::VtkPropRenderer::GetPointPicker() const { return m_PointPicker; } const vtkCellPicker *mitk::VtkPropRenderer::GetCellPicker() const { return m_CellPicker; } mitk::VtkPropRenderer::MappersMapType mitk::VtkPropRenderer::GetMappersMap() const { return m_MappersMap; } // Workaround for GL Displaylist bug static int glWorkAroundGlobalCount = 0; bool mitk::VtkPropRenderer::useImmediateModeRendering() { return glWorkAroundGlobalCount>1; } void mitk::VtkPropRenderer::checkState() { if (m_MapperID == Standard3D) { if (!didCount) { didCount = true; glWorkAroundGlobalCount++; if (glWorkAroundGlobalCount == 2) { MITK_INFO << "Multiple 3D Renderwindows active...: turning Immediate Rendering ON for legacy mappers"; // vtkMapper::GlobalImmediateModeRenderingOn(); } //MITK_INFO << "GLOBAL 3D INCREASE " << glWorkAroundGlobalCount << "\n"; } } else { if(didCount) { didCount=false; glWorkAroundGlobalCount--; if(glWorkAroundGlobalCount==1) { MITK_INFO << "Single 3D Renderwindow active...: turning Immediate Rendering OFF for legacy mappers"; // vtkMapper::GlobalImmediateModeRenderingOff(); } //MITK_INFO << "GLOBAL 3D DECREASE " << glWorkAroundGlobalCount << "\n"; } } } //### Contains all methods which are neceassry before each VTK Render() call void mitk::VtkPropRenderer::PrepareRender() { if ( this->GetMapperID() != m_CameraInitializedForMapperID ) { Initialize2DvtkCamera(); //Set parallel projection etc. } AdjustCameraToScene(); //Prepare camera for 2D render windows } bool mitk::VtkPropRenderer::Initialize2DvtkCamera() { if ( this->GetMapperID() == Standard3D ) { //activate parallel projection for 2D this->GetVtkRenderer()->GetActiveCamera()->SetParallelProjection(false); this->GetRenderWindow()->GetInteractor()->SetInteractorStyle( vtkInteractorStyleTrackballCamera::New() ); m_CameraInitializedForMapperID = Standard3D; } else if( this->GetMapperID() == Standard2D) { //activate parallel projection for 2D this->GetVtkRenderer()->GetActiveCamera()->SetParallelProjection(true); //turn the light out in the scene in order to render correct grey values. //TODO Implement a property for light in the 2D render windows (in another method) this->GetVtkRenderer()->RemoveAllLights(); this->GetRenderWindow()->GetInteractor()->SetInteractorStyle( mitkVtkInteractorStyle::New() ); m_CameraInitializedForMapperID = Standard2D; } return true; } void mitk::VtkPropRenderer::AdjustCameraToScene(){ if(this->GetMapperID() == Standard2D) { const mitk::DisplayGeometry* displayGeometry = this->GetDisplayGeometry(); double objectHeightInMM = this->GetCurrentWorldGeometry2D()->GetExtentInMM(1);//the height of the current object slice in mm double displayHeightInMM = displayGeometry->GetSizeInMM()[1]; //the display height in mm (gets smaller when you zoom in) double zoomFactor = objectHeightInMM/displayHeightInMM; //displayGeometry->GetScaleFactorMMPerDisplayUnit() //determine how much of the object can be displayed Vector2D displayGeometryOriginInMM = displayGeometry->GetOriginInMM(); //top left of the render window (Origin) Vector2D displayGeometryCenterInMM = displayGeometryOriginInMM + displayGeometry->GetSizeInMM()*0.5; //center of the render window: (Origin + Size/2) //Scale the rendered object: //The image is scaled by a single factor, because in an orthographic projection sizes //are preserved (so you cannot scale X and Y axis with different parameters). The //parameter sets the size of the total display-volume. If you set this to the image //height, the image plus a border with the size of the image will be rendered. //Therefore, the size is imageHeightInMM / 2. this->GetVtkRenderer()->GetActiveCamera()->SetParallelScale(objectHeightInMM*0.5 ); //zooming with the factor calculated by dividing displayHeight through imegeHeight. The factor is inverse, because the VTK zoom method is working inversely. this->GetVtkRenderer()->GetActiveCamera()->Zoom(zoomFactor); //the center of the view-plane double viewPlaneCenter[3]; viewPlaneCenter[0] = displayGeometryCenterInMM[0]; viewPlaneCenter[1] = displayGeometryCenterInMM[1]; viewPlaneCenter[2] = 0.0; //the view-plane is located in the XY-plane with Z=0.0 //define which direction is "up" for the ciamera (like default for vtk (0.0, 1.0, 0.0) double cameraUp[3]; cameraUp[0] = 0.0; cameraUp[1] = 1.0; cameraUp[2] = 0.0; //the position of the camera (center[0], center[1], 900000) double cameraPosition[3]; cameraPosition[0] = viewPlaneCenter[0]; cameraPosition[1] = viewPlaneCenter[1]; cameraPosition[2] = 900000.0; //Reason for 900000: VTK seems to calculate the clipping planes wrong for small values. See VTK bug (id #7823) in VTK bugtracker. //set the camera corresponding to the textured plane vtkSmartPointer camera = this->GetVtkRenderer()->GetActiveCamera(); if (camera) { camera->SetPosition( cameraPosition ); //set the camera position on the textured plane normal (in our case this is the view plane normal) camera->SetFocalPoint( viewPlaneCenter ); //set the focal point to the center of the textured plane camera->SetViewUp( cameraUp ); //set the view-up for the camera // double distance = sqrt((cameraPosition[2]-viewPlaneCenter[2])*(cameraPosition[2]-viewPlaneCenter[2])); // camera->SetClippingRange(distance-50, distance+50); //Reason for huge range: VTK seems to calculate the clipping planes wrong for small values. See VTK bug (id #7823) in VTK bugtracker. camera->SetClippingRange(0.1, 1000000); //Reason for huge range: VTK seems to calculate the clipping planes wrong for small values. See VTK bug (id #7823) in VTK bugtracker. } const PlaneGeometry *planeGeometry = dynamic_cast< const PlaneGeometry * >( this->GetCurrentWorldGeometry2D() ); if ( planeGeometry != NULL ) { //Transform the camera to the current position (transveral, coronal and saggital plane). //This is necessary, because the SetUserTransform() method does not manipulate the vtkCamera. //(Without not all three planes would be visible). vtkSmartPointer trans = vtkSmartPointer::New(); vtkSmartPointer matrix = vtkSmartPointer::New(); Point3D origin; Vector3D right, bottom, normal; origin = planeGeometry->GetOrigin(); right = planeGeometry->GetAxisVector( 0 ); // right = Extent of Image in mm (worldspace) bottom = planeGeometry->GetAxisVector( 1 ); normal = planeGeometry->GetNormal(); right.Normalize(); bottom.Normalize(); normal.Normalize(); matrix->SetElement(0, 0, right[0]); matrix->SetElement(1, 0, right[1]); matrix->SetElement(2, 0, right[2]); matrix->SetElement(0, 1, bottom[0]); matrix->SetElement(1, 1, bottom[1]); matrix->SetElement(2, 1, bottom[2]); matrix->SetElement(0, 2, normal[0]); matrix->SetElement(1, 2, normal[1]); matrix->SetElement(2, 2, normal[2]); matrix->SetElement(0, 3, origin[0]); matrix->SetElement(1, 3, origin[1]); matrix->SetElement(2, 3, origin[2]); matrix->SetElement(3, 0, 0.0); matrix->SetElement(3, 1, 0.0); matrix->SetElement(3, 2, 0.0); matrix->SetElement(3, 3, 1.0); trans->SetMatrix(matrix); //Transform the camera to the current position (transveral, coronal and saggital plane). this->GetVtkRenderer()->GetActiveCamera()->ApplyTransform(trans); } } } diff --git a/Core/Code/Testing/CMakeLists.txt b/Core/Code/Testing/CMakeLists.txt index c8fb907410..7b28554211 100644 --- a/Core/Code/Testing/CMakeLists.txt +++ b/Core/Code/Testing/CMakeLists.txt @@ -1,157 +1,170 @@ # The core tests need relaxed compiler flags... # TODO fix core tests to compile without these additional no-error flags if(MSVC_VERSION) # disable deprecated warnings (they would lead to errors) mitkFunctionCheckCAndCXXCompilerFlags("/wd4996" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) else() mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=deprecated" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=deprecated-declarations" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) endif() MITK_CREATE_MODULE_TESTS(LABELS MITK-Core) # MITK_INSTALL_TARGETS(EXECUTABLES MitkTestDriver) mitkAddCustomModuleTest(mitkDICOMLocaleTest_spacingOk_CT mitkDICOMLocaleTest ${MITK_DATA_DIR}/spacing-ok-ct.dcm) mitkAddCustomModuleTest(mitkDICOMLocaleTest_spacingOk_MR mitkDICOMLocaleTest ${MITK_DATA_DIR}/spacing-ok-mr.dcm) mitkAddCustomModuleTest(mitkDICOMLocaleTest_spacingOk_SC mitkDICOMLocaleTest ${MITK_DATA_DIR}/spacing-ok-sc.dcm) mitkAddCustomModuleTest(mitkVolumeCalculatorTest_Png2D-bw mitkVolumeCalculatorTest ${MITK_DATA_DIR}/Png2D-bw.png ${MITK_DATA_DIR}/Pic2DplusT.nrrd) mitkAddCustomModuleTest(mitkEventMapperTest_Test1And2 mitkEventMapperTest ${MITK_DATA_DIR}/TestStateMachine1.xml ${MITK_DATA_DIR}/TestStateMachine2.xml) mitkAddCustomModuleTest(mitkEventConfigTest_CreateObjectInDifferentWays mitkEventConfigTest ${MITK_SOURCE_DIR}/Core/Code/Testing/Resources/Interactions/StatemachineConfigTest.xml) #mitkAddCustomModuleTest(mitkNodeDependentPointSetInteractorTest mitkNodeDependentPointSetInteractorTest ${MITK_DATA_DIR}/Pic3D.pic.gz ${MITK_DATA_DIR}/BallBinary30x30x30.pic.gz) mitkAddCustomModuleTest(mitkNodeDependentPointSetInteractorTest mitkNodeDependentPointSetInteractorTest ${MITK_DATA_DIR}/Pic3D.nrrd ${MITK_DATA_DIR}/BallBinary30x30x30.nrrd) mitkAddCustomModuleTest(mitkDataStorageTest_US4DCyl mitkDataStorageTest ${MITK_DATA_DIR}/US4DCyl.nrrd) mitkAddCustomModuleTest(mitkStateMachineFactoryTest_TestStateMachine1_2 mitkStateMachineFactoryTest ${MITK_DATA_DIR}/TestStateMachine1.xml ${MITK_DATA_DIR}/TestStateMachine2.xml) mitkAddCustomModuleTest(mitkDicomSeriesReaderTest_CTImage mitkDicomSeriesReaderTest ${MITK_DATA_DIR}/TinyCTAbdomen) mitkAddCustomModuleTest(mitkPointSetReaderTest mitkPointSetReaderTest ${MITK_DATA_DIR}/PointSetReaderTestData.mps) mitkAddCustomModuleTest(mitkImageTest_4DImageData mitkImageTest ${MITK_DATA_DIR}/US4DCyl.nrrd) mitkAddCustomModuleTest(mitkImageTest_2D+tImageData mitkImageTest ${MITK_DATA_DIR}/Pic2DplusT.nrrd) mitkAddCustomModuleTest(mitkImageTest_3DImageData mitkImageTest ${MITK_DATA_DIR}/Pic3D.nrrd) mitkAddCustomModuleTest(mitkImageTest_brainImage mitkImageTest ${MITK_DATA_DIR}/brain.mhd) #mitkAddCustomModuleTest(mitkImageTest_color2DImage mitkImageTest ${MITK_DATA_DIR}/NrrdWritingTestImage.jpg) mitkAddCustomModuleTest(mitkIOUtilTest mitkIOUtilTest #test for a randomly chosen Pic3D swivelled slice ${MITK_DATA_DIR}/Pic3D.nrrd ${MITK_DATA_DIR}/pointSet.mps ${MITK_DATA_DIR}/binary.stl ) mitkAddCustomModuleTest(mitkLevelWindowManagerTest mitkLevelWindowManagerTest ${MITK_DATA_DIR}/Pic3D.nrrd ) if(WIN32 OR APPLE OR MITK_ENABLE_GUI_TESTING) ### since the rendering test's do not run in ubuntu, yet, we build them only for other systems or if the user explicitly sets the variable MITK_ENABLE_GUI_TESTING mitkAddCustomModuleTest(mitkImageVtkMapper2D_rgbaImage640x480 mitkImageVtkMapper2DTest ${MITK_DATA_DIR}/RenderingTestData/rgbaImage.png #input image to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/rgbaImage640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleTest(mitkImageVtkMapper2D_pic3d640x480 mitkImageVtkMapper2DTest #test for standard Pic3D axial slice ${MITK_DATA_DIR}/Pic3D.nrrd #input image to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3d640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleTest(mitkImageVtkMapper2D_pic3dColorBlue640x480 mitkImageVtkMapper2DColorTest #test for color property (=blue) Pic3D sagittal slice ${MITK_DATA_DIR}/Pic3D.nrrd #input image to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3dColorBlue640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleTest(mitkImageVtkMapper2D_pic3dLevelWindow640x480 mitkImageVtkMapper2DLevelWindowTest #test for levelwindow property (=blood) #Pic3D sagittal slice ${MITK_DATA_DIR}/Pic3D.nrrd #input image to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3dLevelWindowBlood640x480REF.png #corresponding reference #screenshot ) mitkAddCustomModuleTest(mitkImageVtkMapper2D_pic3dOpacity640x480 mitkImageVtkMapper2DOpacityTest #test for opacity (=0.5) Pic3D coronal slice ${MITK_DATA_DIR}/Pic3D.nrrd #input image to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3dOpacity640x480REF.png corresponding reference screenshot ) mitkAddCustomModuleTest(mitkImageVtkMapper2D_pic3dSwivel640x480 mitkImageVtkMapper2DSwivelTest #test for a randomly chosen Pic3D swivelled slice ${MITK_DATA_DIR}/Pic3D.nrrd #input image to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3dSwivel640x480REF.png #corresponding reference screenshot ) +mitkAddCustomModuleTest(mitkPointSetVtkMapper2D_openMeAlone640x480 mitkPointSetVtkMapper2DTest + ${MITK_DATA_DIR}/RenderingTestData/openMeAlone.mps #input point set to load in data storage + -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/openMeAlone640x480REF.png #corresponding reference screenshot +) +mitkAddCustomModuleTest(mitkPointSetVtkMapper2D_Pic3DPointSetForPic3D640x480 mitkPointSetVtkMapper2DImageTest + ${MITK_DATA_DIR}/Pic3D.nrrd ${MITK_DATA_DIR}/RenderingTestData/PointSetForPic3D.mps #input point set and image to load in data storage + -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/Pic3DPointSetForPic3D640x480REF.png #corresponding reference screenshot +) +mitkAddCustomModuleTest(mitkPointSetVtkMapper2D_openMeAloneGlyphType640x480 mitkPointSetVtkMapper2DGlyphTypeTest + ${MITK_DATA_DIR}/RenderingTestData/openMeAlone.mps #input point set to load in data storage + -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/openMeAloneGlyphType640x480REF.png #corresponding reference screenshot +) + #Test reslice interpolation #note: nearest mode is already tested by swivel test mitkAddCustomModuleTest(ResliceInterpolationIsLinear mitkImageVtkMapper2DResliceInterpolationPropertyTest 1 #linear ${MITK_DATA_DIR}/Pic3D.nrrd -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3dRefLinear.png #corresponding reference screenshot LINEAR ) mitkAddCustomModuleTest(ResliceInterpolationIsCubic mitkImageVtkMapper2DResliceInterpolationPropertyTest 3 #cubic ${MITK_DATA_DIR}/Pic3D.nrrd -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/pic3dRefCubic.png #corresponding reference screenshot CUBIC ) #End test reslice interpolation # Testing of the rendering of binary images mitkAddCustomModuleTest(mitkImageVtkMapper2D_binaryTestImage640x480 mitkImageVtkMapper2DTest #test for standard Pic3D axial slice ${MITK_DATA_DIR}/RenderingTestData/binaryImage.nrrd #input image to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/binaryImage640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleTest(mitkImageVtkMapper2D_binaryTestImageWithRef640x480 mitkImageVtkMapper2DTest #test for standard Pic3D axial slice ${MITK_DATA_DIR}/Pic3D.nrrd ${MITK_DATA_DIR}/RenderingTestData/binaryImage.nrrd #input image to load in data storage -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/binaryImageWithRef640x480REF.png #corresponding reference screenshot ) # End of binary image tests mitkAddCustomModuleTest(mitkSurfaceVtkMapper3DTest_TextureProperty mitkSurfaceVtkMapper3DTest ${MITK_DATA_DIR}/ToF-Data/Kinect_LiverPhantom.vtp ${MITK_DATA_DIR}/ToF-Data/Kinect_LiverPhantom_RGBImage.nrrd -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/texturedLiver640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleTest(mitkImageVtkMapper2DTransferFunctionTest_Png2D-bw mitkImageVtkMapper2DTransferFunctionTest ${MITK_DATA_DIR}/Png2D-bw.png -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/Png2D-bw-TransferFunctionRGBImage640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleTest(mitkSurfaceGLMapper2DColorTest_RedBall mitkSurfaceGLMapper2DColorTest ${MITK_DATA_DIR}/ball.stl -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/ballColorRed640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleTest(mitkSurfaceGLMapper2DColorTest_DasArmeSchwein mitkSurfaceGLMapper2DColorTest ${MITK_DATA_DIR}/binary.stl -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/binaryColorRed640x480REF.png #corresponding reference screenshot ) mitkAddCustomModuleTest(mitkSurfaceGLMapper2DOpacityTest_BallOpacity mitkSurfaceGLMapper2DOpacityTest #opacity = 50% (0.5) ${MITK_DATA_DIR}/ball.stl -V ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/ballOpacity640x480REF.png #corresponding reference screenshot ) #Removed due to high rendering error. #mitkAddCustomModuleTest(mitkSurfaceVtkMapper3DTexturedSphereTest_Football mitkSurfaceVtkMapper3DTexturedSphereTest # ${MITK_DATA_DIR}/RenderingTestData/texture.jpg #input texture # -V # ${MITK_DATA_DIR}/RenderingTestData/ReferenceScreenshots/texturedSphere640x480REF.png corresponding reference screenshot #) -SET_PROPERTY(TEST mitkImageVtkMapper2D_rgbaImage640x480 mitkImageVtkMapper2D_pic3d640x480 mitkImageVtkMapper2D_pic3dColorBlue640x480 mitkImageVtkMapper2D_pic3dLevelWindow640x480 mitkImageVtkMapper2D_pic3dSwivel640x480 mitkImageVtkMapper2DTransferFunctionTest_Png2D-bw mitkImageVtkMapper2D_pic3dOpacity640x480 mitkSurfaceGLMapper2DOpacityTest_BallOpacity mitkSurfaceGLMapper2DColorTest_DasArmeSchwein mitkSurfaceGLMapper2DColorTest_RedBall mitkSurfaceVtkMapper3DTest_TextureProperty #mitkSurfaceVtkMapper3DTexturedSphereTest_Football +SET_PROPERTY(TEST mitkImageVtkMapper2D_rgbaImage640x480 mitkImageVtkMapper2D_pic3d640x480 mitkImageVtkMapper2D_pic3dColorBlue640x480 mitkImageVtkMapper2D_pic3dLevelWindow640x480 mitkImageVtkMapper2D_pic3dSwivel640x480 mitkImageVtkMapper2DTransferFunctionTest_Png2D-bw mitkImageVtkMapper2D_pic3dOpacity640x480 mitkSurfaceGLMapper2DOpacityTest_BallOpacity mitkSurfaceGLMapper2DColorTest_DasArmeSchwein mitkSurfaceGLMapper2DColorTest_RedBall mitkSurfaceVtkMapper3DTest_TextureProperty mitkPointSetVtkMapper2D_openMeAlone640x480 mitkPointSetVtkMapper2D_Pic3DPointSetForPic3D640x480 mitkPointSetVtkMapper2D_openMeAloneGlyphType640x480 #mitkSurfaceVtkMapper3DTexturedSphereTest_Football PROPERTY RUN_SERIAL TRUE) endif() add_test(mitkPointSetLocaleTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TESTDRIVER} mitkPointSetLocaleTest ${MITK_DATA_DIR}/pointSet.mps) set_property(TEST mitkPointSetLocaleTest PROPERTY LABELS MITK-Core) add_test(mitkImageWriterTest_nrrdImage ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TESTDRIVER} mitkImageWriterTest ${MITK_DATA_DIR}/NrrdWritingTestImage.jpg) add_test(mitkImageWriterTest_2DPNGImage ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TESTDRIVER} mitkImageWriterTest ${MITK_DATA_DIR}/Png2D-bw.png) add_test(mitkImageWriterTest_rgbPNGImage ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TESTDRIVER} mitkImageWriterTest ${MITK_DATA_DIR}/RenderingTestData/rgbImage.png) add_test(mitkImageWriterTest_rgbaPNGImage ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TESTDRIVER} mitkImageWriterTest ${MITK_DATA_DIR}/RenderingTestData/rgbaImage.png) set_property(TEST mitkImageWriterTest_nrrdImage PROPERTY LABELS MITK-Core) set_property(TEST mitkImageWriterTest_2DPNGImage PROPERTY LABELS MITK-Core) set_property(TEST mitkImageWriterTest_rgbPNGImage PROPERTY LABELS MITK-Core) set_property(TEST mitkImageWriterTest_rgbaPNGImage PROPERTY LABELS MITK-Core) add_subdirectory(DICOMTesting) diff --git a/Core/Code/Testing/files.cmake b/Core/Code/Testing/files.cmake index 1ddd129c03..b70a0d0d0c 100644 --- a/Core/Code/Testing/files.cmake +++ b/Core/Code/Testing/files.cmake @@ -1,146 +1,149 @@ # tests with no extra command line parameter set(MODULE_TESTS mitkAccessByItkTest.cpp mitkCoreObjectFactoryTest.cpp mitkMaterialTest.cpp mitkActionTest.cpp mitkDispatcherTest.cpp mitkEnumerationPropertyTest.cpp mitkEventTest.cpp mitkFocusManagerTest.cpp mitkGenericPropertyTest.cpp mitkGeometry3DTest.cpp mitkGeometryDataToSurfaceFilterTest.cpp mitkGlobalInteractionTest.cpp mitkImageDataItemTest.cpp #mitkImageMapper2DTest.cpp mitkImageGeneratorTest.cpp mitkBaseDataTest.cpp #mitkImageToItkTest.cpp mitkInstantiateAccessFunctionTest.cpp mitkInteractorTest.cpp #mitkITKThreadingTest.cpp mitkLevelWindowTest.cpp mitkMessageTest.cpp #mitkPipelineSmartPointerCorrectnessTest.cpp mitkPixelTypeTest.cpp mitkPlaneGeometryTest.cpp mitkPointSetFileIOTest.cpp mitkPointSetTest.cpp mitkPointSetWriterTest.cpp mitkPointSetReaderTest.cpp mitkPointSetInteractorTest.cpp mitkPropertyTest.cpp mitkPropertyListTest.cpp #mitkRegistrationBaseTest.cpp #mitkSegmentationInterpolationTest.cpp mitkSlicedGeometry3DTest.cpp mitkSliceNavigationControllerTest.cpp mitkStateMachineTest.cpp ##mitkStateMachineContainerTest.cpp ## rewrite test, indirect since no longer exported Bug 14529 mitkStateTest.cpp mitkSurfaceTest.cpp mitkSurfaceToSurfaceFilterTest.cpp mitkTimeSlicedGeometryTest.cpp mitkTransitionTest.cpp mitkUndoControllerTest.cpp mitkVtkWidgetRenderingTest.cpp mitkVerboseLimitedLinearUndoTest.cpp mitkWeakPointerTest.cpp mitkTransferFunctionTest.cpp #mitkAbstractTransformGeometryTest.cpp mitkStepperTest.cpp itkTotalVariationDenoisingImageFilterTest.cpp mitkRenderingManagerTest.cpp vtkMitkThickSlicesFilterTest.cpp mitkNodePredicateSourceTest.cpp mitkVectorTest.cpp mitkClippedSurfaceBoundsCalculatorTest.cpp mitkExceptionTest.cpp mitkExtractSliceFilterTest.cpp mitkLogTest.cpp mitkImageDimensionConverterTest.cpp mitkLoggingAdapterTest.cpp mitkUIDGeneratorTest.cpp mitkShaderRepositoryTest.cpp ) # test with image filename as an extra command line parameter set(MODULE_IMAGE_TESTS mitkPlanePositionManagerTest.cpp mitkSurfaceVtkWriterTest.cpp #mitkImageSliceSelectorTest.cpp mitkImageTimeSelectorTest.cpp # mitkVtkPropRendererTest.cpp mitkDataNodeFactoryTest.cpp #mitkSTLFileReaderTest.cpp mitkImageAccessorTest.cpp ) # list of images for which the tests are run set(MODULE_TESTIMAGES # Pic-Factory no more available in Core, test images now in .nrrd format US4DCyl.nrrd Pic3D.nrrd Pic2DplusT.nrrd BallBinary30x30x30.nrrd binary.stl ball.stl ) set(MODULE_CUSTOM_TESTS #mitkLabeledImageToSurfaceFilterTest.cpp #mitkExternalToolsTest.cpp mitkDataStorageTest.cpp mitkDataNodeTest.cpp mitkDicomSeriesReaderTest.cpp mitkDICOMLocaleTest.cpp mitkEventMapperTest.cpp mitkEventConfigTest.cpp mitkNodeDependentPointSetInteractorTest.cpp mitkStateMachineFactoryTest.cpp mitkPointSetLocaleTest.cpp mitkImageTest.cpp mitkImageWriterTest.cpp mitkImageVtkMapper2DTest.cpp mitkImageVtkMapper2DLevelWindowTest.cpp mitkImageVtkMapper2DOpacityTest.cpp mitkImageVtkMapper2DResliceInterpolationPropertyTest.cpp mitkImageVtkMapper2DColorTest.cpp mitkImageVtkMapper2DSwivelTest.cpp mitkImageVtkMapper2DTransferFunctionTest.cpp mitkIOUtilTest.cpp mitkSurfaceVtkMapper3DTest mitkSurfaceVtkMapper3DTexturedSphereTest.cpp mitkSurfaceGLMapper2DColorTest.cpp mitkSurfaceGLMapper2DOpacityTest.cpp mitkVolumeCalculatorTest.cpp mitkLevelWindowManagerTest.cpp + mitkPointSetVtkMapper2DTest.cpp + mitkPointSetVtkMapper2DImageTest.cpp + mitkPointSetVtkMapper2DGlyphTypeTest.cpp ) set(MODULE_RESOURCE_FILES Interactions/AddAndRemovePoints.xml Interactions/globalConfig.xml Interactions/StatemachineTest.xml Interactions/StatemachineConfigTest.xml ) # Create an artificial module initializing class for # the usServiceListenerTest.cpp usFunctionGenerateModuleInit(testdriver_init_file NAME ${MODULE_NAME}TestDriver DEPENDS "Mitk" VERSION "0.1.0" EXECUTABLE ) # Embed the resources set(testdriver_resources ) usFunctionEmbedResources(testdriver_resources EXECUTABLE_NAME ${MODULE_NAME}TestDriver ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Resources FILES ${MODULE_RESOURCE_FILES} ) set(TEST_CPP_FILES ${testdriver_init_file} ${testdriver_resources}) diff --git a/Core/Code/Testing/mitkDataNodeTest.cpp b/Core/Code/Testing/mitkDataNodeTest.cpp index 258838f21d..df60b455ca 100644 --- a/Core/Code/Testing/mitkDataNodeTest.cpp +++ b/Core/Code/Testing/mitkDataNodeTest.cpp @@ -1,300 +1,300 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkDataNode.h" #include #include "mitkVtkPropRenderer.h" #include "mitkTestingMacros.h" #include "mitkGlobalInteraction.h" #include //Basedata Test #include #include #include #include #include #include #include #include //Mapper Test #include #include #include -#include +#include #include #include #include #include #include #include //Interactors #include #include //Propertylist Test /** * Simple example for a test for the (non-existent) class "DataNode". * * argc and argv are the command line parameters which were passed to * the ADD_TEST command in the CMakeLists.txt file. For the automatic * tests, argv is either empty for the simple tests or contains the filename * of a test image for the image tests (see CMakeLists.txt). */ class mitkDataNodeTestClass { public: static void TestDataSetting(mitk::DataNode::Pointer dataNode) { mitk::BaseData::Pointer baseData; //NULL pointer Test dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a NULL pointer was set correctly" ) baseData = mitk::RenderWindowFrame::New(); dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a RenderWindowFrame object was set correctly" ) // MITK_TEST_CONDITION( baseData->GetGeometry(0)->GetVtkTransform() == dataNode->GetVtkTransform(0), "Testing if a NULL pointer was set correctly" ) baseData = mitk::GeometryData::New(); dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a GeometryData object was set correctly" ) baseData = mitk::Geometry2DData::New(); dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a Geometry2DData object was set correctly" ) baseData = mitk::GradientBackground::New(); dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a GradientBackground object was set correctly" ) baseData = mitk::ManufacturerLogo::New(); dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a ManufacturerLogo object was set correctly" ) baseData = mitk::PointSet::New(); dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a PointSet object was set correctly" ) baseData = mitk::Image::New(); dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a Image object was set correctly" ) baseData = mitk::Surface::New(); dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a Surface object was set correctly" ) } static void TestMapperSetting(mitk::DataNode::Pointer dataNode) { //tests the SetMapper() method //in dataNode is a mapper vector which can be accessed by index //in this test method we use only slot 0 (filled with null) and slot 1 //so we also test the destructor of the mapper classes mitk::Mapper::Pointer mapper; dataNode->SetMapper(0,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(0), "Testing if a NULL pointer was set correctly" ) mapper = mitk::Geometry2DDataMapper2D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a Geometry2DDataMapper2D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) mapper = mitk::ImageVtkMapper2D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a ImageVtkMapper2D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) - mapper = mitk::PointSetGLMapper2D::New(); + mapper = mitk::PointSetVtkMapper2D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a PointSetGLMapper2D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a PolyDataGLMapper2D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) mapper = mitk::SurfaceGLMapper2D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a SurfaceGLMapper2D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) mapper = mitk::Geometry2DDataVtkMapper3D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a Geometry2DDataVtkMapper3D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) mapper = mitk::PointSetVtkMapper3D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a PointSetVtkMapper3D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) mapper = mitk::SurfaceVtkMapper3D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a SurfaceVtkMapper3D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) mapper = mitk::VolumeDataVtkMapper3D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a VolumeDataVtkMapper3D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) //linker error //mapper = mitk::LineVtkMapper3D::New(); //dataNode->SetMapper(1,mapper); //MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a LineVtkMapper3D was set correctly" ) //MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) } static void TestInteractorSetting(mitk::DataNode::Pointer dataNode) { //this method tests the SetInteractor() and GetInteractor methods //the Interactor base class calls the DataNode->SetInteractor method mitk::Interactor::Pointer interactor; MITK_TEST_CONDITION( interactor == dataNode->GetInteractor(), "Testing if a NULL pointer was set correctly (Interactor)" ) interactor = mitk::AffineInteractor::New("AffineInteractions click to select", dataNode); dataNode->EnableInteractor(); dataNode->DisableInteractor(); MITK_TEST_CONDITION( interactor == dataNode->GetInteractor(), "Testing if a AffineInteractor was set correctly" ) interactor = mitk::PointSetInteractor::New("AffineInteractions click to select", dataNode); MITK_TEST_CONDITION( interactor == dataNode->GetInteractor(), "Testing if a PointSetInteractor was set correctly" ) } static void TestPropertyList(mitk::DataNode::Pointer dataNode) { mitk::PropertyList::Pointer propertyList = dataNode->GetPropertyList(); MITK_TEST_CONDITION(dataNode->GetPropertyList() != NULL, "Testing if the constructor set the propertylist" ) dataNode->SetIntProperty("int", -31337); int x; dataNode->GetIntProperty("int", x); MITK_TEST_CONDITION(x == -31337, "Testing Set/GetIntProperty"); dataNode->SetBoolProperty("bool", true); bool b; dataNode->GetBoolProperty("bool", b); MITK_TEST_CONDITION(b == true, "Testing Set/GetBoolProperty"); dataNode->SetFloatProperty("float", -31.337); float y; dataNode->GetFloatProperty("float", y); MITK_TEST_CONDITION(y - -31.337 < 0.01, "Testing Set/GetFloatProperty"); dataNode->SetStringProperty("string", "MITK"); std::string s = "GANZVIELPLATZ"; dataNode->GetStringProperty("string", s); MITK_TEST_CONDITION(s == "MITK", "Testing Set/GetStringProperty"); std::string name = "MyTestName"; dataNode->SetName(name.c_str()); MITK_TEST_CONDITION(dataNode->GetName() == name, "Testing Set/GetName"); name = "MySecondTestName"; dataNode->SetName(name); MITK_TEST_CONDITION(dataNode->GetName() == name, "Testing Set/GetName(std::string)"); MITK_TEST_CONDITION(propertyList == dataNode->GetPropertyList(), "Testing if the propertylist has changed during the last tests" ) } static void TestSelected(mitk::DataNode::Pointer dataNode) { vtkRenderWindow *renderWindow = vtkRenderWindow::New(); mitk::VtkPropRenderer::Pointer base = mitk::VtkPropRenderer::New( "the first renderer", renderWindow, mitk::RenderingManager::GetInstance() ); //with BaseRenderer==Null MITK_TEST_CONDITION(!dataNode->IsSelected(), "Testing if this node is not set as selected" ) dataNode->SetSelected(true); MITK_TEST_CONDITION(dataNode->IsSelected(), "Testing if this node is set as selected" ) dataNode->SetSelected(false); dataNode->SetSelected(true,base); MITK_TEST_CONDITION(dataNode->IsSelected(base), "Testing if this node with right base renderer is set as selected" ) //Delete RenderWindow correctly renderWindow->Delete(); } static void TestGetMTime(mitk::DataNode::Pointer dataNode) { unsigned long time; time = dataNode->GetMTime(); mitk::PointSet::Pointer pointSet = mitk::PointSet::New(); dataNode->SetData(pointSet); MITK_TEST_CONDITION( time != dataNode->GetMTime(), "Testing if the node timestamp is updated after adding data to the node" ) mitk::Point3D point; point.Fill(3.0); pointSet->SetPoint(0,point); //less or equal because dataNode timestamp is little later then the basedata timestamp MITK_TEST_CONDITION( pointSet->GetMTime() <= dataNode->GetMTime(), "Testing if the node timestamp is updated after base data was modified" ) // testing if changing anything in the property list also sets the node in a modified state unsigned long lastModified = dataNode->GetMTime(); dataNode->SetIntProperty("testIntProp", 2344); MITK_TEST_CONDITION( lastModified <= dataNode->GetMTime(), "Testing if the node timestamp is updated after property list was modified" ) } }; //mitkDataNodeTestClass int mitkDataNodeTest(int /* argc */, char* /*argv*/[]) { // always start with this! MITK_TEST_BEGIN("DataNode") // Global interaction must(!) be initialized mitk::GlobalInteraction::GetInstance()->Initialize("global"); // let's create an object of our class mitk::DataNode::Pointer myDataNode = mitk::DataNode::New(); // first test: did this work? // using MITK_TEST_CONDITION_REQUIRED makes the test stop after failure, since // it makes no sense to continue without an object. MITK_TEST_CONDITION_REQUIRED(myDataNode.IsNotNull(),"Testing instantiation") //test setData() Method mitkDataNodeTestClass::TestDataSetting(myDataNode); mitkDataNodeTestClass::TestMapperSetting(myDataNode); // //note, that no data is set to the dataNode mitkDataNodeTestClass::TestInteractorSetting(myDataNode); mitkDataNodeTestClass::TestPropertyList(myDataNode); mitkDataNodeTestClass::TestSelected(myDataNode); mitkDataNodeTestClass::TestGetMTime(myDataNode); // write your own tests here and use the macros from mitkTestingMacros.h !!! // do not write to std::cout and do not return from this function yourself! // always end with this! MITK_TEST_END() } diff --git a/Core/Code/Testing/mitkPointSetVtkMapper2DGlyphTypeTest.cpp b/Core/Code/Testing/mitkPointSetVtkMapper2DGlyphTypeTest.cpp new file mode 100644 index 0000000000..1557729adf --- /dev/null +++ b/Core/Code/Testing/mitkPointSetVtkMapper2DGlyphTypeTest.cpp @@ -0,0 +1,55 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +//MITK +#include "mitkTestingMacros.h" +#include "mitkRenderingTestHelper.h" +#include +#include +#include +#include + +//VTK +#include + + +int mitkPointSetVtkMapper2DGlyphTypeTest(int argc, char* argv[]) +{ + // load all arguments into a datastorage, take last argument as reference rendering + // setup a renderwindow of fixed size X*Y + // render the datastorage + // compare rendering to reference image + MITK_TEST_BEGIN("mitkPointSetVtkMapper2DGlyphTypeTest") + + mitkRenderingTestHelper renderingHelper(640, 480, argc, argv); + + renderingHelper.SetViewDirection(mitk::SliceNavigationController::ViewDirection::Sagittal); + + mitk::EnumerationProperty* eP = dynamic_cast (renderingHelper.GetDataStorage()->GetNode(mitk::NodePredicateDataType::New("PointSet"))->GetProperty("Pointset.2D.shape")); + // render triangles instead of crosses + eP->SetValue(5); + + //### Usage of CompareRenderWindowAgainstReference: See docu of mitkRrenderingTestHelper + MITK_TEST_CONDITION( renderingHelper.CompareRenderWindowAgainstReference(argc, argv) == true, "CompareRenderWindowAgainstReference test result positive?" ); + + //use this to generate a reference screenshot or save the file: + if(false) + { + renderingHelper.SaveReferenceScreenShot("C:/development_ITK4/output.png"); + } + + MITK_TEST_END(); +} \ No newline at end of file diff --git a/Core/Code/Testing/mitkPointSetVtkMapper2DImageTest.cpp b/Core/Code/Testing/mitkPointSetVtkMapper2DImageTest.cpp new file mode 100644 index 0000000000..50a600af61 --- /dev/null +++ b/Core/Code/Testing/mitkPointSetVtkMapper2DImageTest.cpp @@ -0,0 +1,45 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +//MITK +#include "mitkTestingMacros.h" +#include "mitkRenderingTestHelper.h" + +//VTK +#include + + +int mitkPointSetVtkMapper2DImageTest(int argc, char* argv[]) +{ + // load all arguments into a datastorage, take last argument as reference rendering + // setup a renderwindow of fixed size X*Y + // render the datastorage + // compare rendering to reference image + MITK_TEST_BEGIN("mitkPointSetVtkMapper2DImageTest") + + mitkRenderingTestHelper renderingHelper(640, 480, argc, argv); + + //### Usage of CompareRenderWindowAgainstReference: See docu of mitkRrenderingTestHelper + MITK_TEST_CONDITION( renderingHelper.CompareRenderWindowAgainstReference(argc, argv) == true, "CompareRenderWindowAgainstReference test result positive?" ); + + //use this to generate a reference screenshot or save the file: + if(false) + { + renderingHelper.SaveReferenceScreenShot("C:/development_ITK4/output.png"); + } + + MITK_TEST_END(); +} \ No newline at end of file diff --git a/Core/Code/Testing/mitkPointSetVtkMapper2DTest.cpp b/Core/Code/Testing/mitkPointSetVtkMapper2DTest.cpp new file mode 100644 index 0000000000..27377c36d6 --- /dev/null +++ b/Core/Code/Testing/mitkPointSetVtkMapper2DTest.cpp @@ -0,0 +1,48 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +//MITK +#include "mitkTestingMacros.h" +#include "mitkRenderingTestHelper.h" + +//VTK +#include + + +int mitkPointSetVtkMapper2DTest(int argc, char* argv[]) +{ + // load all arguments into a datastorage, take last argument as reference rendering + // setup a renderwindow of fixed size X*Y + // render the datastorage + // compare rendering to reference image + MITK_TEST_BEGIN("mitkPointSetVtkMapper2DTest") + + mitkRenderingTestHelper renderingHelper(640, 480, argc, argv); + + // sagittal view direction + renderingHelper.SetViewDirection(mitk::SliceNavigationController::ViewDirection::Sagittal); + + //### Usage of CompareRenderWindowAgainstReference: See docu of mitkRrenderingTestHelper + MITK_TEST_CONDITION( renderingHelper.CompareRenderWindowAgainstReference(argc, argv) == true, "CompareRenderWindowAgainstReference test result positive?" ); + + //use this to generate a reference screenshot or save the file: + if(false) + { + renderingHelper.SaveReferenceScreenShot("C:/development_ITK4/output.png"); + } + + MITK_TEST_END(); +} \ No newline at end of file diff --git a/Core/Code/files.cmake b/Core/Code/files.cmake index 1ffedad6eb..9cf6ec1bc6 100644 --- a/Core/Code/files.cmake +++ b/Core/Code/files.cmake @@ -1,361 +1,362 @@ set(H_FILES Algorithms/itkImportMitkImageContainer.h Algorithms/itkImportMitkImageContainer.txx Algorithms/itkLocalVariationImageFilter.h Algorithms/itkLocalVariationImageFilter.txx Algorithms/itkMITKScalarImageToHistogramGenerator.h Algorithms/itkMITKScalarImageToHistogramGenerator.txx Algorithms/itkTotalVariationDenoisingImageFilter.h Algorithms/itkTotalVariationDenoisingImageFilter.txx Algorithms/itkTotalVariationSingleIterationImageFilter.h Algorithms/itkTotalVariationSingleIterationImageFilter.txx Algorithms/mitkBilateralFilter.h Algorithms/mitkBilateralFilter.cpp Algorithms/mitkInstantiateAccessFunctions.h Algorithms/mitkPixelTypeList.h # Preprocessor macros taken from Boost Algorithms/mitkPPArithmeticDec.h Algorithms/mitkPPArgCount.h Algorithms/mitkPPCat.h Algorithms/mitkPPConfig.h Algorithms/mitkPPControlExprIIf.h Algorithms/mitkPPControlIf.h Algorithms/mitkPPControlIIf.h Algorithms/mitkPPDebugError.h Algorithms/mitkPPDetailAutoRec.h Algorithms/mitkPPDetailDMCAutoRec.h Algorithms/mitkPPExpand.h Algorithms/mitkPPFacilitiesEmpty.h Algorithms/mitkPPFacilitiesExpand.h Algorithms/mitkPPLogicalBool.h Algorithms/mitkPPRepetitionDetailDMCFor.h Algorithms/mitkPPRepetitionDetailEDGFor.h Algorithms/mitkPPRepetitionDetailFor.h Algorithms/mitkPPRepetitionDetailMSVCFor.h Algorithms/mitkPPRepetitionFor.h Algorithms/mitkPPSeqElem.h Algorithms/mitkPPSeqForEach.h Algorithms/mitkPPSeqForEachProduct.h Algorithms/mitkPPSeq.h Algorithms/mitkPPSeqEnum.h Algorithms/mitkPPSeqSize.h Algorithms/mitkPPSeqToTuple.h Algorithms/mitkPPStringize.h Algorithms/mitkPPTupleEat.h Algorithms/mitkPPTupleElem.h Algorithms/mitkPPTupleRem.h Algorithms/mitkClippedSurfaceBoundsCalculator.h Algorithms/mitkExtractSliceFilter.h Algorithms/mitkConvert2Dto3DImageFilter.h Algorithms/mitkPlaneClipping.h Common/mitkExceptionMacro.h Common/mitkServiceBaseObject.h Common/mitkTestingMacros.h DataManagement/mitkImageAccessByItk.h DataManagement/mitkImageCast.h DataManagement/mitkImagePixelAccessor.h DataManagement/mitkImagePixelReadAccessor.h DataManagement/mitkImagePixelWriteAccessor.h DataManagement/mitkImageReadAccessor.h DataManagement/mitkImageWriteAccessor.h DataManagement/mitkITKImageImport.h DataManagement/mitkITKImageImport.txx DataManagement/mitkImageToItk.h DataManagement/mitkImageToItk.txx Interactions/mitkEventMapperAddOn.h Interfaces/mitkIDataNodeReader.h Rendering/mitkLocalStorageHandler.h IO/mitkPixelTypeTraits.h ) set(CPP_FILES Algorithms/mitkBaseDataSource.cpp Algorithms/mitkDataNodeSource.cpp Algorithms/mitkGeometry2DDataToSurfaceFilter.cpp Algorithms/mitkHistogramGenerator.cpp Algorithms/mitkImageChannelSelector.cpp Algorithms/mitkImageSliceSelector.cpp Algorithms/mitkImageSource.cpp Algorithms/mitkImageTimeSelector.cpp Algorithms/mitkImageToImageFilter.cpp Algorithms/mitkPointSetSource.cpp Algorithms/mitkPointSetToPointSetFilter.cpp Algorithms/mitkRGBToRGBACastImageFilter.cpp Algorithms/mitkSubImageSelector.cpp Algorithms/mitkSurfaceSource.cpp Algorithms/mitkSurfaceToSurfaceFilter.cpp Algorithms/mitkUIDGenerator.cpp Algorithms/mitkVolumeCalculator.cpp Algorithms/mitkClippedSurfaceBoundsCalculator.cpp Algorithms/mitkExtractSliceFilter.cpp Algorithms/mitkConvert2Dto3DImageFilter.cpp Controllers/mitkBaseController.cpp Controllers/mitkCallbackFromGUIThread.cpp Controllers/mitkCameraController.cpp Controllers/mitkCameraRotationController.cpp Controllers/mitkCoreActivator.cpp Controllers/mitkFocusManager.cpp Controllers/mitkLimitedLinearUndo.cpp Controllers/mitkOperationEvent.cpp Controllers/mitkPlanePositionManager.cpp Controllers/mitkProgressBar.cpp Controllers/mitkRenderingManager.cpp Controllers/mitkSliceNavigationController.cpp Controllers/mitkSlicesCoordinator.cpp Controllers/mitkSlicesRotator.cpp Controllers/mitkSlicesSwiveller.cpp Controllers/mitkStatusBar.cpp Controllers/mitkStepper.cpp Controllers/mitkTestManager.cpp Controllers/mitkUndoController.cpp Controllers/mitkVerboseLimitedLinearUndo.cpp Controllers/mitkVtkInteractorCameraController.cpp Controllers/mitkVtkLayerController.cpp DataManagement/mitkAbstractTransformGeometry.cpp DataManagement/mitkAnnotationProperty.cpp DataManagement/mitkApplicationCursor.cpp DataManagement/mitkBaseData.cpp DataManagement/mitkBaseProperty.cpp DataManagement/mitkClippingProperty.cpp DataManagement/mitkChannelDescriptor.cpp DataManagement/mitkColorProperty.cpp DataManagement/mitkDataStorage.cpp #DataManagement/mitkDataTree.cpp DataManagement/mitkDataNode.cpp DataManagement/mitkDataNodeFactory.cpp #DataManagement/mitkDataTreeStorage.cpp DataManagement/mitkDisplayGeometry.cpp DataManagement/mitkEnumerationProperty.cpp DataManagement/mitkGeometry2D.cpp DataManagement/mitkGeometry2DData.cpp DataManagement/mitkGeometry3D.cpp DataManagement/mitkGeometryData.cpp DataManagement/mitkGroupTagProperty.cpp DataManagement/mitkImage.cpp DataManagement/mitkImageAccessorBase.cpp DataManagement/mitkImageCaster.cpp DataManagement/mitkImageCastPart1.cpp DataManagement/mitkImageCastPart2.cpp DataManagement/mitkImageCastPart3.cpp DataManagement/mitkImageCastPart4.cpp DataManagement/mitkImageDataItem.cpp DataManagement/mitkImageDescriptor.cpp DataManagement/mitkImageVtkAccessor.cpp DataManagement/mitkImageStatisticsHolder.cpp DataManagement/mitkLandmarkBasedCurvedGeometry.cpp DataManagement/mitkLandmarkProjectorBasedCurvedGeometry.cpp DataManagement/mitkLandmarkProjector.cpp DataManagement/mitkLevelWindow.cpp DataManagement/mitkLevelWindowManager.cpp DataManagement/mitkLevelWindowPreset.cpp DataManagement/mitkLevelWindowProperty.cpp DataManagement/mitkLookupTable.cpp DataManagement/mitkLookupTables.cpp # specializations of GenericLookupTable DataManagement/mitkMemoryUtilities.cpp DataManagement/mitkModalityProperty.cpp DataManagement/mitkModeOperation.cpp DataManagement/mitkNodePredicateAnd.cpp DataManagement/mitkNodePredicateBase.cpp DataManagement/mitkNodePredicateCompositeBase.cpp DataManagement/mitkNodePredicateData.cpp DataManagement/mitkNodePredicateDataType.cpp DataManagement/mitkNodePredicateDimension.cpp DataManagement/mitkNodePredicateFirstLevel.cpp DataManagement/mitkNodePredicateNot.cpp DataManagement/mitkNodePredicateOr.cpp DataManagement/mitkNodePredicateProperty.cpp DataManagement/mitkNodePredicateSource.cpp DataManagement/mitkPlaneOrientationProperty.cpp DataManagement/mitkPlaneGeometry.cpp DataManagement/mitkPlaneOperation.cpp DataManagement/mitkPointOperation.cpp DataManagement/mitkPointSet.cpp DataManagement/mitkProperties.cpp DataManagement/mitkPropertyList.cpp DataManagement/mitkRestorePlanePositionOperation.cpp DataManagement/mitkRotationOperation.cpp DataManagement/mitkSlicedData.cpp DataManagement/mitkSlicedGeometry3D.cpp DataManagement/mitkSmartPointerProperty.cpp DataManagement/mitkStandaloneDataStorage.cpp DataManagement/mitkStateTransitionOperation.cpp DataManagement/mitkStringProperty.cpp DataManagement/mitkSurface.cpp DataManagement/mitkSurfaceOperation.cpp DataManagement/mitkThinPlateSplineCurvedGeometry.cpp DataManagement/mitkTimeSlicedGeometry.cpp DataManagement/mitkTransferFunction.cpp DataManagement/mitkTransferFunctionProperty.cpp DataManagement/mitkTransferFunctionInitializer.cpp DataManagement/mitkVector.cpp DataManagement/mitkVtkInterpolationProperty.cpp DataManagement/mitkVtkRepresentationProperty.cpp DataManagement/mitkVtkResliceInterpolationProperty.cpp DataManagement/mitkVtkScalarModeProperty.cpp DataManagement/mitkVtkVolumeRenderingProperty.cpp DataManagement/mitkWeakPointerProperty.cpp DataManagement/mitkRenderingModeProperty.cpp DataManagement/mitkShaderProperty.cpp DataManagement/mitkResliceMethodProperty.cpp DataManagement/mitkMaterial.cpp Interactions/mitkAction.cpp Interactions/mitkAffineInteractor.cpp Interactions/mitkBindDispatcherInteractor.cpp Interactions/mitkCoordinateSupplier.cpp Interactions/mitkDataInteractor.cpp Interactions/mitkDispatcher.cpp Interactions/mitkDisplayCoordinateOperation.cpp Interactions/mitkDisplayInteractor.cpp Interactions/mitkDisplayPositionEvent.cpp # Interactions/mitkDisplayVectorInteractorLevelWindow.cpp # legacy, prob even now unneeded # Interactions/mitkDisplayVectorInteractorScroll.cpp Interactions/mitkEvent.cpp Interactions/mitkEventConfig.cpp Interactions/mitkEventDescription.cpp Interactions/mitkEventFactory.cpp Interactions/mitkInteractionEventHandler.cpp Interactions/mitkEventMapper.cpp Interactions/mitkEventStateMachine.cpp Interactions/mitkGlobalInteraction.cpp Interactions/mitkInteractor.cpp Interactions/mitkInternalEvent.cpp Interactions/mitkInteractionEvent.cpp Interactions/mitkInteractionEventConst.cpp Interactions/mitkInteractionPositionEvent.cpp Interactions/mitkInteractionKeyEvent.cpp Interactions/mitkMousePressEvent.cpp Interactions/mitkMouseMoveEvent.cpp Interactions/mitkMouseReleaseEvent.cpp Interactions/mitkMouseWheelEvent.cpp Interactions/mitkMouseModeSwitcher.cpp Interactions/mitkMouseMovePointSetInteractor.cpp Interactions/mitkMoveBaseDataInteractor.cpp Interactions/mitkNodeDepententPointSetInteractor.cpp Interactions/mitkPointSetDataInteractor.cpp Interactions/mitkPointSetInteractor.cpp Interactions/mitkPositionEvent.cpp Interactions/mitkPositionTracker.cpp Interactions/mitkStateMachineAction.cpp Interactions/mitkStateMachineState.cpp Interactions/mitkStateMachineTransition.cpp Interactions/mitkState.cpp Interactions/mitkStateMachineContainer.cpp Interactions/mitkStateEvent.cpp Interactions/mitkStateMachine.cpp Interactions/mitkStateMachineFactory.cpp Interactions/mitkTransition.cpp Interactions/mitkWheelEvent.cpp Interactions/mitkKeyEvent.cpp Interactions/mitkVtkEventAdapter.cpp Interactions/mitkVtkInteractorStyle.cxx Interactions/mitkCrosshairPositionEvent.cpp Interfaces/mitkInteractionEventObserver.cpp Interfaces/mitkIShaderRepository.cpp IO/mitkBaseDataIOFactory.cpp IO/mitkCoreDataNodeReader.cpp IO/mitkDicomSeriesReader.cpp IO/mitkFileReader.cpp IO/mitkFileSeriesReader.cpp IO/mitkFileWriter.cpp #IO/mitkIpPicGet.c IO/mitkImageGenerator.cpp IO/mitkImageWriter.cpp IO/mitkImageWriterFactory.cpp IO/mitkItkImageFileIOFactory.cpp IO/mitkItkImageFileReader.cpp IO/mitkItkLoggingAdapter.cpp IO/mitkItkPictureWrite.cpp IO/mitkIOUtil.cpp IO/mitkLookupTableProperty.cpp IO/mitkOperation.cpp #IO/mitkPicFileIOFactory.cpp #IO/mitkPicFileReader.cpp #IO/mitkPicFileWriter.cpp #IO/mitkPicHelper.cpp #IO/mitkPicVolumeTimeSeriesIOFactory.cpp #IO/mitkPicVolumeTimeSeriesReader.cpp IO/mitkPixelType.cpp IO/mitkPointSetIOFactory.cpp IO/mitkPointSetReader.cpp IO/mitkPointSetWriter.cpp IO/mitkPointSetWriterFactory.cpp IO/mitkRawImageFileReader.cpp IO/mitkStandardFileLocations.cpp IO/mitkSTLFileIOFactory.cpp IO/mitkSTLFileReader.cpp IO/mitkSurfaceVtkWriter.cpp IO/mitkSurfaceVtkWriterFactory.cpp IO/mitkVtkLoggingAdapter.cpp IO/mitkVtiFileIOFactory.cpp IO/mitkVtiFileReader.cpp IO/mitkVtkImageIOFactory.cpp IO/mitkVtkImageReader.cpp IO/mitkVtkSurfaceIOFactory.cpp IO/mitkVtkSurfaceReader.cpp IO/vtkPointSetXMLParser.cpp IO/mitkLog.cpp Rendering/mitkBaseRenderer.cpp Rendering/mitkVtkMapper.cpp Rendering/mitkRenderWindowFrame.cpp Rendering/mitkGeometry2DDataMapper2D.cpp Rendering/mitkGeometry2DDataVtkMapper3D.cpp Rendering/mitkGLMapper.cpp Rendering/mitkGradientBackground.cpp Rendering/mitkManufacturerLogo.cpp Rendering/mitkMapper.cpp Rendering/mitkPointSetGLMapper2D.cpp + Rendering/mitkPointSetVtkMapper2D.cpp Rendering/mitkPointSetVtkMapper3D.cpp Rendering/mitkPolyDataGLMapper2D.cpp Rendering/mitkSurfaceGLMapper2D.cpp Rendering/mitkSurfaceVtkMapper3D.cpp Rendering/mitkVolumeDataVtkMapper3D.cpp Rendering/mitkVtkPropRenderer.cpp Rendering/mitkVtkWidgetRendering.cpp Rendering/vtkMitkRectangleProp.cpp Rendering/vtkMitkRenderProp.cpp Rendering/mitkVtkEventProvider.cpp Rendering/mitkRenderWindow.cpp Rendering/mitkRenderWindowBase.cpp Rendering/mitkShaderRepository.cpp Rendering/mitkImageVtkMapper2D.cpp Rendering/vtkMitkThickSlicesFilter.cpp Rendering/vtkMitkLevelWindowFilter.cpp Rendering/vtkNeverTranslucentTexture.cpp Rendering/mitkRenderingTestHelper.cpp Common/mitkException.cpp Common/mitkCommon.h Common/mitkCoreObjectFactoryBase.cpp Common/mitkCoreObjectFactory.cpp Common/mitkCoreServices.cpp ) list(APPEND CPP_FILES ${CppMicroServices_SOURCES}) set(RESOURCE_FILES Interactions/globalConfig.xml Interactions/DisplayInteraction.xml Interactions/DisplayConfig.xml Interactions/DisplayConfigPACS.xml Interactions/DisplayConfigPACSPan.xml Interactions/DisplayConfigPACSScroll.xml Interactions/DisplayConfigPACSZoom.xml Interactions/DisplayConfigPACSLevelWindow.xml Interactions/DisplayConfigMITK.xml Interactions/PointSet.xml Interactions/Legacy/StateMachine.xml Interactions/Legacy/DisplayConfigMITKTools.xml Interactions/PointSetConfig.xml Shaders/mitkShaderLighting.xml mitkLevelWindowPresets.xml ) diff --git a/Core/Documentation/Doxygen/Concepts/QVTKRendering.dox b/Core/Documentation/Doxygen/Concepts/QVTKRendering.dox index fd50b5c7e7..6140aba57f 100644 --- a/Core/Documentation/Doxygen/Concepts/QVTKRendering.dox +++ b/Core/Documentation/Doxygen/Concepts/QVTKRendering.dox @@ -1,100 +1,125 @@ /** \page QVTKRendering Rendering Concept The MITK rendering pipeline is derived from the VTK rendering pipeline. \section QVTKRendering_Pipeline_VTK VTK Rendering Pipeline \image html RenderingOverviewVTK.png "Rendering in VTK" In VTK, the vtkRenderWindow coordinates the rendering process. Several vtkRenderers may be associated to one vtkRenderWindow. All visible objects, which can exist in a rendered scene (2D and 3D scene), inherit from vtkProp (or any subclass e.g. vtkActor). A vtkPropAssembly is an assembly of several vtkProps, which appears like one single vtkProp. MITK uses a new interface class, the "vtkMitkRenderProp", which is inherited from vtkProp. Similar to a vtkPropAssembly, all MITK rendering stuff is performed via this interface class. Thus, the MITK rendering process is completely integrated into the VTK rendering pipeline. From VTK point of view, MITK renders like a custom vtkProp object. More information about the VTK rendering pipeline can be found at http://www.vtk.org and in the several VTK books. \section QVTKRendering_Pipeline_MITK MITK Rendering Pipeline This process is tightly connected to VTK, which makes it straight forward and simple. We use the above mentioned "vtkMitkRenderProp" in conjunction with the mitk::VtkPropRenderer for integration into the VTK pipeline. The QmitkRenderWindow does not inherit from mitk::RenderWindow, but from the QVTKWidget, which is provided by VTK. The main classes of the MITK rendering process can be illustrated like this: \image html qVtkRenderingClassOverview.png "Rendering in MITK" A render request to the vtkRenderWindow does not only update the VTK pipeline, but also the MITK pipeline. However, the mitk::RenderingManager still coordinates the rendering update behavior. Update requests should be sent to the RenderingManager, which then, if needed, will request an update of the overall vtkRenderWindow. The vtkRenderWindow then starts to call the Render() function of all vtkRenderers, which are associated to the vtkRenderWindow. Currently, MITK uses specific vtkRenderers (outside the standard MITK rendering pipeline) for purposes, like displaying a gradient background (mitk::GradientBackground), displaying video sources (QmitkVideoBackround and mitk::VideoSource), or displaying a (department) logo (mitk::ManufacturerLogo), etc.. Despite these specific renderers, a kind of "SceneRenderer" is member of each QmitkRenderWindow. This vtkRenderer is associated with the custom vtkMitkRenderProp and is responsible for the MITK rendering. The vtkRenderer calls four different functions in vtkMitkRenderProp, namely RenderOpaqueGeometry(), RenderTranslucentPolygonalGeometry(), RenderVolumetricGeometry() and RenderOverlay(). These function calls are forwarded to the mitk::VtkPropRenderer. Then, depending on the mapper type (OpenGL- or VTK-based), OpenGL is enabled or disabled. In the case of OpenGL rendering, the Paint()-method of each individual mapper is called. If the mapper is VTK-based, the four function calls are forwarded to mitk::VtkMapper and within these methods the corresponding VtkProp is evaluated. Both strategies are illustrated in the sequence diagrams below: \image html qVtkRenderingSequenceVTK.png "Sequence diagram for MITK VTK rendering" In MITK, VTK-based mapper are more common and we recommend on implementing VTK-based mappers. However, MITK supports OpenGL-based mappers as well. \image html qVtkRenderingSequenceGL.png "Sequence diagram for MITK OpenGL rendering" \section QVTKRendering_Mapper MITK Mapper Architecture Mappers are used to transform the input data in tangible primitives, such as surfaces, points, lines, etc. The base class of all mappers is mitk::Mapper. The mapper hierarchy reflects the two possible ways to render in MITK: Subclasses of mitk::Mapper control the creation of rendering primitives that interface to the graphics library (e.g. via OpenGL, vtk). The mapper architecture is illustrated in the following UML diagram: \image html qVtkRenderingMapper.jpg "Mapper architecture" mitk::Mapper::Update() calls the time step of the input data for the specified renderer and checks whether the time step is valid and calls method mitk::Mapper::GenerateDataForRenderer(), which is reimplemented in the individual mappers and should be used to generate primitives. mitk::Mapper::SetDefaultProperties() should be used to define mapper-specific properties. \section QVTKRendering_programmerGuide User Guide: Programming hints for rendering related stuff (in plugins) \li The QmitkRenderWindow can be accessed like this: this->GetRenderWindowPart()->GetRenderWindow("axial"); \li The vtkRenderWindow can be accessed like this: this->GetRenderWindowPart()->GetRenderWindow("axial")->GetVtkRenderWindow(); \li The mitkBaseRenderer can be accessed like this: mitk::BaseRenderer* renderer = mitk::BaseRenderer::GetInstance(this->GetRenderWindowPart()->GetRenderWindow("sagittal")->GetRenderWindow()); \li An update request of the overall QmitkStdMultiWidget can be performed with: this->GetRenderWindowPart()->GetRenderingManager()->RequestUpdateAll(); \li A single QmitkRenderWindow update request can be done like this: this->GetRenderWindowPart()->GetRenderingManager()->RequestUpdate(this->GetRenderWindowPart()->GetRenderWindow("axial")->GetVtkRenderWindow()); \note The usage of ForceImmediateUpdateAll() is not desired in most common use-cases. \subsection QVTKRendering_distinctRenderWindow Setting up a distinct Rendering-Pipeline It is sometimes desired to have one (or more) QmitkRenderWindows that are managed totally independent of the 'usual' renderwindows defined by the QmitkStdMultiWidget. This may include the data that is rendered as well as possible interactions. In order to achieve this, a set of objects is needed: \li mitk::RenderingManager -> Manages the rendering \li mitk::DataStorage -> Manages the data that is rendered \li mitk::GlobalInteraction -> Manages all interaction \li QmitkRenderWindow -> Actually visualizes the data The actual setup, respectively the connection, of these classes is rather simple: \code // create a new instance of mitk::RenderingManager mitk::RenderingManager::Pointer renderingManager = mitk::RenderingManager::New(); // create new instances of DataStorage and GlobalInteraction mitk::DataStorage::Pointer dataStorage = mitk::DataStorage::New(); mitk::GlobalInteraction::Pointer globalInteraction = mitk::GlobalInteraction::New(); // add both to the RenderingManager renderingManager->SetDataStorage( dataStorage ); renderingManager->SetGlobalInteraction( globalInteraction ); // now create a new QmitkRenderWindow with this renderingManager as parameter QmitkRenderWindow* renderWindow = new QmitkRenderWindow( parent, "name", renderer, renderingManager ); \endcode That is basically all you need to setup your own rendering pipeline. Obviously you have to add all data you want to render to your new DataStorage. If you want to interact with this renderwindow, you will also have to add additional Interactors/Listeners. \note Dynamic casts of a mitk::BaseRenderer class to an OpenGLRenderer (or now, to an VtkPropRenderer) should be avoided. The "MITK Scene" vtkRenderer and the vtkRenderWindow as well, are therefore now included in the mitk::BaseRenderer. +\subsection QVTKRendering_userGuideMapper How to write your own Mapper + +If you want to write your own mapper, you first need to decide whether you want to write a VTK-based mapper or a GL-based mapper. +We recommend to write a VTK-based mapper, as VTK is easy to learn and some GL-based mappers can have unexpected site effects. +However, you need to derive from the respective classes. + +In the following we provide some programming hints for writing a Vtk-based mapper: + +\li include mitkLocalStorageHandler.h and derive from class BaseLocalStorage as a nested class in your own mapper. The LocalStorage instance should +contain all VTK ressources such as actors, textures, mappers, polydata etc. +The LocalStorageHandler is responsible for providing a LocalStorage to a concrete mitk::Mapper subclass. Each RenderWindow / mitk::BaseRenderer is +assigned its own LocalStorage instance so that all contained ressources (actors, shaders, textures, ...) are provided individually per window. + +\li GenerateDataForRenderer() should be reimplemented in order to generate the primitives that should be rendered. This method is called in each Mapper::Update() pass, thus, +all primitives that are rendered are recomputed. Employ LocalStorage::IsGenerateDataRequired() to determine whether it is necessary to generate the primitives again. It is not +necessary to generate them again in case the scene has just been translated or rotated. + +\li For 2D mappers, it is necessary to determine the 3D primitives close to the current plane that should be drawn. Use + planeGeometry = renderer->GetSliceNavigationController()->GetCurrentPlaneGeometry() to get the current plane. The distance to it can be determined by using planeGeometry->DistanceFromPlane(point). + +\li Reimplement GetVtkProp(), that should return the specific VtkProp generated in GenerateDataForRender() (e.g. a single actor or a propassembly, which is a combination of different actors). +The VtkProp is picked up in one of the four render passes and thus integrated into the VTK render pipeline. + +\li SetDefaultProperties() should be used to define mapper-specific properties. + */ diff --git a/Modules/MitkExt/Rendering/mitkLineMapper2D.h b/Modules/MitkExt/Rendering/mitkLineMapper2D.h index 522422e51c..ac1180f57e 100644 --- a/Modules/MitkExt/Rendering/mitkLineMapper2D.h +++ b/Modules/MitkExt/Rendering/mitkLineMapper2D.h @@ -1,56 +1,58 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKLINEMAPPER2D_H_HEADER_INCLUDED #define MITKLINEMAPPER2D_H_HEADER_INCLUDED #include "mitkCommon.h" #include "MitkExtExports.h" #include "mitkPointSetGLMapper2D.h" namespace mitk { class BaseRenderer; class PointSet; //##Documentation //## @brief OpenGL-based mapper to display Lines //## //## uses the information from the PointSet to build up the lines. //## Only lines in 2D in one Slice are drawn, not between slices! //## @ingroup Mapper -class MitkExt_EXPORT LineMapper2D : public PointSetGLMapper2D + +/** \deprecatedSince{2013_06} This mapper is deprecated. */ +DEPRECATED(class MitkExt_EXPORT LineMapper2D) : public PointSetGLMapper2D { public: mitkClassMacro(LineMapper2D, PointSetGLMapper2D); itkNewMacro(Self); //##Documentation //## @brief Get the PointDataList to map const PointSet * GetInput(void); virtual void Paint(mitk::BaseRenderer * renderer); protected: LineMapper2D(); virtual ~LineMapper2D(); }; } // namespace mitk #endif /* MITKLINEMAPPER2D_H_HEADER_INCLUDED */ diff --git a/Modules/MitkExt/Rendering/mitkSplineMapper2D.cpp b/Modules/MitkExt/Rendering/mitkSplineMapper2D.cpp index 5b2dab2357..18d1f35445 100755 --- a/Modules/MitkExt/Rendering/mitkSplineMapper2D.cpp +++ b/Modules/MitkExt/Rendering/mitkSplineMapper2D.cpp @@ -1,193 +1,193 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkSplineMapper2D.h" #include "mitkSplineVtkMapper3D.h" #include #include #include #include #include #include #include #include void mitk::SplineMapper2D::Paint ( mitk::BaseRenderer * renderer ) { Superclass::Paint ( renderer ); bool visible = true; GetDataNode()->GetVisibility(visible, renderer, "visible"); if ( !visible ) return; // // get the poly data of the splines in 3D // mitk::SplineVtkMapper3D::Pointer mapper3D = dynamic_cast ( this->GetDataNode()->GetMapper ( 2 ) ); if ( mapper3D.IsNull() ) { itkWarningMacro ( "Mapper used for 3D mapping is not a mitk::SplineVtkMapper3D!" ); return; } // // update the 3D spline, if the accoring mapper has not been updated yet // //if ( mapper3D->GetLastUpdateTime() < GetDataNode()->GetData()->GetMTime() ) - mapper3D->UpdateSpline(); + mapper3D->UpdateSpline(); vtkPolyData* spline3D = NULL; if ( mapper3D->SplinesAreAvailable() ) spline3D = mapper3D->GetSplinesPolyData(); else return; if ( spline3D == NULL ) { itkWarningMacro ( "3D spline is not available!" ); return; } // // get the transform associated with the data tree node // vtkLinearTransform* transform = this->GetDataNode()->GetVtkTransform(); if ( transform == NULL ) { itkWarningMacro("transfrom is NULL"); } // // get the plane geometry of the current renderer // mitk::Geometry2D::ConstPointer worldGeometry = renderer->GetCurrentWorldGeometry2D(); if ( worldGeometry.IsNull() ) { itkWarningMacro("worldGeometry is NULL!"); return; } PlaneGeometry::ConstPointer worldPlaneGeometry = dynamic_cast ( worldGeometry.GetPointer() ); if ( worldPlaneGeometry.IsNull() ) { itkWarningMacro("worldPlaneGeometry is NULL!"); return; } // // determine color of the spline // float color[3]; this->GetDataNode()->GetColor ( color, renderer ); // // iterate over the points // vtkPoints *vpoints = spline3D->GetPoints(); vtkCellArray *vlines = spline3D->GetLines(); if (vpoints == NULL) { itkWarningMacro("points are NULL!"); return; } if (vlines == NULL) { itkWarningMacro("lines are NULL!"); return; } mitk::Point3D currentPoint3D; mitk::Point2D currentPoint2D; vtkFloatingPointType currentPoint3DVtk[3]; vlines->InitTraversal(); int numberOfLines = vlines->GetNumberOfCells(); vtkFloatingPointType currentPointDistance; for ( int i = 0;i < numberOfLines; ++i ) { bool previousPointOnPlane = false; bool currentPointOnPlane = false; vtkIdType* cell ( NULL ); vtkIdType cellSize ( 0 ); vlines->GetNextCell ( cellSize, cell ); for ( int j = 0 ; j < cellSize; ++j ) { vpoints->GetPoint ( cell[j], currentPoint3DVtk ); // take transformation via vtktransform into account transform->TransformPoint ( currentPoint3DVtk, currentPoint3DVtk ); vtk2itk ( currentPoint3DVtk, currentPoint3D ); // check if the point has a distance to the plane // which is smaller than m_MaxProjectionDistance currentPointDistance = worldPlaneGeometry->DistanceFromPlane ( currentPoint3D ); if ( currentPointDistance < m_MaxProjectionDistance ) { currentPointOnPlane = true; //convert 3D point (in mm) to 2D point on slice (also in mm) worldGeometry->Map ( currentPoint3D, currentPoint2D ); //convert point (until now mm and in worldcoordinates) to display coordinates (units ) renderer->GetDisplayGeometry()->WorldToDisplay ( currentPoint2D, currentPoint2D ); } else currentPointOnPlane = false; // // check if we have to begin or end a GL_LINE // if ( ( previousPointOnPlane == false ) && ( currentPointOnPlane == true ) ) { glLineWidth ( m_LineWidth ); glColor3f ( color[0], color[1], color[2] ); glBegin ( GL_LINE_STRIP ); } else if ( ( previousPointOnPlane == true ) && ( currentPointOnPlane == false ) ) { glEnd (); glLineWidth ( 1.0 ); } // the current ponit is on the plane, add it as point to the // line segment if ( currentPointOnPlane == true ) { glVertex2f ( currentPoint2D[0], currentPoint2D[1] ); } previousPointOnPlane = currentPointOnPlane; } // the last point of the spline segment is on the plane, thus we have to // close the GL_LINE if ( previousPointOnPlane == true ) { glEnd (); glLineWidth ( 1.0 ); } previousPointOnPlane = false; } } void mitk::SplineMapper2D::ApplyProperties ( mitk::BaseRenderer* renderer ) { ApplyColorAndOpacityProperties ( renderer ); } mitk::SplineMapper2D::SplineMapper2D() { m_MaxProjectionDistance = 1; m_ShowDistantLines = false ; m_LineWidth = 1; } mitk::SplineMapper2D::~SplineMapper2D() {} diff --git a/Modules/MitkExt/Rendering/mitkSplineMapper2D.h b/Modules/MitkExt/Rendering/mitkSplineMapper2D.h index 30c6d704fa..dcb24752b7 100755 --- a/Modules/MitkExt/Rendering/mitkSplineMapper2D.h +++ b/Modules/MitkExt/Rendering/mitkSplineMapper2D.h @@ -1,83 +1,85 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKSplineMapper2D_H_HEADER_INCLUDED #define MITKSplineMapper2D_H_HEADER_INCLUDED #include "mitkCommon.h" #include "MitkExtExports.h" #include "mitkGLMapper.h" #include "mitkPointSetGLMapper2D.h" #include namespace mitk { class BaseRenderer; class PointSet; //##Documentation //## @brief OpenGL-based mapper to display a spline based on a mitk::PointSet in a 2D window. //## /** This mapper can actually more than just draw a number of points of a * mitk::PointSet. If you set the right properties of the mitk::DataNode, * which contains the point set, then this mapper will also draw lines * connecting the points, and calculate and display distances and angles * between adjacent points. Here is a complete list of boolean properties, * which might be of interest: * * - \b "show contour": Draw not only the points but also the connections between * them (default false) * - \b "line width": IntProperty which gives the width of the contour lines * - \b "show points": Wheter or not to draw the actual points (default true) * - \b "show distances": Wheter or not to calculate and print the distance * between adjacent points (default false) * - \b "show angles": Wheter or not to calculate and print the angle between * adjacent points (default false) * - \b "show distant lines": When true, the mapper will also draw contour * lines that are far away form the current slice (default true) * - \b "label": StringProperty with a label for this point set */ //## @ingroup Mapper -class MitkExt_EXPORT SplineMapper2D : public PointSetGLMapper2D + +/** \deprecatedSince{2013_06} This mapper is deprecated. */ +DEPRECATED(class MitkExt_EXPORT SplineMapper2D) : public PointSetGLMapper2D { public: mitkClassMacro ( SplineMapper2D, PointSetGLMapper2D ); itkNewMacro ( Self ); virtual void Paint ( mitk::BaseRenderer * renderer ); virtual void ApplyProperties ( mitk::BaseRenderer* renderer ); itkSetMacro ( MaxProjectionDistance, vtkFloatingPointType ); itkGetMacro ( MaxProjectionDistance, vtkFloatingPointType ); protected: SplineMapper2D(); virtual ~SplineMapper2D(); vtkFloatingPointType m_MaxProjectionDistance; }; } // namespace mitk #endif /* MITKSplineMapper2D_H_HEADER_INCLUDED */