diff --git a/Core/Code/Algorithms/mitkClippedSurfaceBoundsCalculator.cpp b/Core/Code/Algorithms/mitkClippedSurfaceBoundsCalculator.cpp index 8cf5763fd9..ade2ae5f4b 100644 --- a/Core/Code/Algorithms/mitkClippedSurfaceBoundsCalculator.cpp +++ b/Core/Code/Algorithms/mitkClippedSurfaceBoundsCalculator.cpp @@ -1,354 +1,354 @@ /*=================================================================== 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 "mitkClippedSurfaceBoundsCalculator.h" #include "mitkLine.h" #define ROUND_P(x) ((x)>=0?(int)((x)+0.5):(int)((x)-0.5)) mitk::ClippedSurfaceBoundsCalculator::ClippedSurfaceBoundsCalculator( const mitk::PlaneGeometry* geometry, mitk::Image::Pointer image) : m_PlaneGeometry(NULL) , m_Geometry3D(NULL) , m_Image(NULL) { this->InitializeOutput(); this->SetInput(geometry, image); } mitk::ClippedSurfaceBoundsCalculator::ClippedSurfaceBoundsCalculator( - const mitk::Geometry3D* geometry, + const mitk::BaseGeometry* geometry, mitk::Image::Pointer image) : m_PlaneGeometry(NULL) , m_Geometry3D(NULL) , m_Image(NULL) { this->InitializeOutput(); this->SetInput(geometry, image); } mitk::ClippedSurfaceBoundsCalculator::ClippedSurfaceBoundsCalculator( const PointListType pointlist, mitk::Image::Pointer image ) : m_PlaneGeometry(NULL) , m_Geometry3D(NULL) , m_Image(image) { this->InitializeOutput(); m_ObjectPointsInWorldCoordinates = pointlist; } void mitk::ClippedSurfaceBoundsCalculator::InitializeOutput() { // initialize with meaningless slice indices m_MinMaxOutput.clear(); for(int i = 0; i < 3; i++) { m_MinMaxOutput.push_back( OutputType( std::numeric_limits::max() , std::numeric_limits::min() )); } } mitk::ClippedSurfaceBoundsCalculator::~ClippedSurfaceBoundsCalculator() { } void mitk::ClippedSurfaceBoundsCalculator::SetInput( const mitk::PlaneGeometry* geometry, mitk::Image* image) { if(geometry && image) { this->m_PlaneGeometry = geometry; this->m_Image = image; this->m_Geometry3D = NULL; //Not possible to set both m_ObjectPointsInWorldCoordinates.clear(); } } void mitk::ClippedSurfaceBoundsCalculator::SetInput( - const mitk::Geometry3D* geometry, + const mitk::BaseGeometry* geometry, mitk::Image* image) { if(geometry && image) { this->m_Geometry3D = geometry; this->m_Image = image; this->m_PlaneGeometry = NULL; //Not possible to set both m_ObjectPointsInWorldCoordinates.clear(); } } void mitk::ClippedSurfaceBoundsCalculator::SetInput( const std::vector pointlist, mitk::Image *image ) { if ( !pointlist.empty() && image ) { m_Geometry3D = NULL; m_PlaneGeometry = NULL; m_Image = image; m_ObjectPointsInWorldCoordinates = pointlist; } } mitk::ClippedSurfaceBoundsCalculator::OutputType mitk::ClippedSurfaceBoundsCalculator::GetMinMaxSpatialDirectionX() { return this->m_MinMaxOutput[0]; } mitk::ClippedSurfaceBoundsCalculator::OutputType mitk::ClippedSurfaceBoundsCalculator::GetMinMaxSpatialDirectionY() { return this->m_MinMaxOutput[1]; } mitk::ClippedSurfaceBoundsCalculator::OutputType mitk::ClippedSurfaceBoundsCalculator::GetMinMaxSpatialDirectionZ() { return this->m_MinMaxOutput[2]; } void mitk::ClippedSurfaceBoundsCalculator::Update() { this->m_MinMaxOutput.clear(); for(int i = 0; i < 3; i++) { this->m_MinMaxOutput.push_back(OutputType( std::numeric_limits::max() , std::numeric_limits::min() )); } if(m_PlaneGeometry.IsNotNull()) { this->CalculateIntersectionPoints(m_PlaneGeometry); } else if(m_Geometry3D.IsNotNull()) { // go through all slices of the image, ... const mitk::SlicedGeometry3D* slicedGeometry3D = dynamic_cast( m_Geometry3D.GetPointer() ); int allSlices = slicedGeometry3D->GetSlices(); this->CalculateIntersectionPoints(dynamic_cast(slicedGeometry3D->GetGeometry2D(0))); this->CalculateIntersectionPoints(dynamic_cast(slicedGeometry3D->GetGeometry2D(allSlices-1))); } else if( !m_ObjectPointsInWorldCoordinates.empty() ) { this->CalculateIntersectionPoints( m_ObjectPointsInWorldCoordinates ); } } void mitk::ClippedSurfaceBoundsCalculator::CalculateIntersectionPoints(const mitk::PlaneGeometry* geometry) { // SEE HEADER DOCUMENTATION for explanation typedef std::vector< std::pair > EdgesVector; Point3D origin; Vector3D xDirection, yDirection, zDirection; const Vector3D spacing = m_Image->GetGeometry()->GetSpacing(); origin = m_Image->GetGeometry()->GetOrigin(); //Left, bottom, front //Get axis vector for the spatial directions xDirection = m_Image->GetGeometry()->GetAxisVector(1); yDirection = m_Image->GetGeometry()->GetAxisVector(0); zDirection = m_Image->GetGeometry()->GetAxisVector(2); /* * For the calculation of the intersection points we need as corner points the center-based image coordinates. * With the method GetCornerPoint() of the class Geometry3D we only get the corner-based coordinates. * Therefore we need to calculate the center-based corner points here. For that we add/substract the corner- * based coordinates with the spacing of the geometry3D. */ for( int i = 0; i < 3; i++ ) { if(xDirection[i] < 0) { xDirection[i] += spacing[i]; } else if( xDirection[i] > 0 ) { xDirection[i] -= spacing[i]; } if(yDirection[i] < 0) { yDirection[i] += spacing[i]; } else if( yDirection[i] > 0 ) { yDirection[i] -= spacing[i]; } if(zDirection[i] < 0) { zDirection[i] += spacing[i]; } else if( zDirection[i] > 0 ) { zDirection[i] -= spacing[i]; } } Point3D leftBottomFront, leftTopFront, leftBottomBack, leftTopBack; Point3D rightBottomFront, rightTopFront, rightBottomBack, rightTopBack; leftBottomFront = origin; leftTopFront = origin + yDirection; leftBottomBack = origin + zDirection; leftTopBack = origin + yDirection + zDirection; rightBottomFront = origin + xDirection; rightTopFront = origin + xDirection + yDirection; rightBottomBack = origin + xDirection + zDirection; rightTopBack = origin + xDirection + yDirection + zDirection; EdgesVector edgesOf3DBox; edgesOf3DBox.push_back(std::make_pair(leftBottomBack, // x = left=xfront, y=bottom=yfront, z=front=zfront leftTopFront)); // left, top, front edgesOf3DBox.push_back(std::make_pair(leftBottomFront, // left, bottom, front leftBottomBack)); // left, bottom, back edgesOf3DBox.push_back(std::make_pair(leftBottomFront, // left, bottom, front rightBottomFront)); // right, bottom, front edgesOf3DBox.push_back(std::make_pair(leftTopFront, // left, top, front rightTopFront)); // right, top, front edgesOf3DBox.push_back(std::make_pair(leftTopFront, // left, top, front leftTopBack)); // left, top, back edgesOf3DBox.push_back(std::make_pair(rightTopFront, // right, top, front rightTopBack)); // right, top, back edgesOf3DBox.push_back(std::make_pair(rightTopFront, // right, top, front rightBottomFront)); // right, bottom, front edgesOf3DBox.push_back(std::make_pair(rightBottomFront, // right, bottom, front rightBottomBack)); // right, bottom, back edgesOf3DBox.push_back(std::make_pair(rightBottomBack, // right, bottom, back leftBottomBack)); // left, bottom, back edgesOf3DBox.push_back(std::make_pair(rightBottomBack, // right, bottom, back rightTopBack)); // right, top, back edgesOf3DBox.push_back(std::make_pair(rightTopBack, // right, top, back leftTopBack)); // left, top, back edgesOf3DBox.push_back(std::make_pair(leftTopBack, // left, top, back leftBottomBack)); // left, bottom, back for (EdgesVector::iterator iterator = edgesOf3DBox.begin(); iterator != edgesOf3DBox.end();iterator++) { Point3D startPoint = (*iterator).first; // start point of the line Point3D endPoint = (*iterator).second; // end point of the line Vector3D lineDirection = endPoint - startPoint; mitk::Line3D line(startPoint, lineDirection); Point3D intersectionWorldPoint; intersectionWorldPoint.Fill(std::numeric_limits::min()); // Get intersection point of line and plane geometry geometry->IntersectionPoint(line, intersectionWorldPoint); double t = -1.0; bool doesLineIntersectWithPlane(false); if(line.GetDirection().GetNorm() < mitk::eps && geometry->Distance(line.GetPoint1()) < mitk::sqrteps) { t = 1.0; doesLineIntersectWithPlane = true; intersectionWorldPoint = line.GetPoint1(); } else { geometry->IntersectionPoint(line, intersectionWorldPoint); doesLineIntersectWithPlane = geometry->IntersectionPointParam(line, t); } mitk::Point3D intersectionIndexPoint; //Get index point m_Image->GetGeometry()->WorldToIndex(intersectionWorldPoint, intersectionIndexPoint); if ( doesLineIntersectWithPlane && -mitk::sqrteps <= t && t <= 1.0 + mitk::sqrteps ) { for(int dim = 0; dim < 3; dim++) { // minimum //If new point value is lower than old if( this->m_MinMaxOutput[dim].first > ROUND_P(intersectionIndexPoint[dim]) ) { this->m_MinMaxOutput[dim].first = ROUND_P(intersectionIndexPoint[dim]); //set new value } // maximum //If new point value is higher than old if( this->m_MinMaxOutput[dim].second < ROUND_P(intersectionIndexPoint[dim]) ) { this->m_MinMaxOutput[dim].second = ROUND_P(intersectionIndexPoint[dim]); //set new value } } this->EnforceImageBounds(); } } } void mitk::ClippedSurfaceBoundsCalculator::CalculateIntersectionPoints( PointListType pointList ) { PointListType::iterator pointIterator; mitk::SlicedGeometry3D::Pointer imageGeometry = m_Image->GetSlicedGeometry(); for ( pointIterator = pointList.begin(); pointIterator != pointList.end(); pointIterator++ ) { mitk::Point3D pntInIndexCoordinates; imageGeometry->WorldToIndex( (*pointIterator), pntInIndexCoordinates ); m_MinMaxOutput[0].first = pntInIndexCoordinates[0] < m_MinMaxOutput[0].first ? ROUND_P(pntInIndexCoordinates[0]) : m_MinMaxOutput[0].first; m_MinMaxOutput[0].second = pntInIndexCoordinates[0] > m_MinMaxOutput[0].second ? ROUND_P(pntInIndexCoordinates[0]) : m_MinMaxOutput[0].second; m_MinMaxOutput[1].first = pntInIndexCoordinates[1] < m_MinMaxOutput[1].first ? ROUND_P(pntInIndexCoordinates[1]) : m_MinMaxOutput[1].first; m_MinMaxOutput[1].second = pntInIndexCoordinates[1] > m_MinMaxOutput[1].second ? ROUND_P(pntInIndexCoordinates[1]) : m_MinMaxOutput[1].second; m_MinMaxOutput[2].first = pntInIndexCoordinates[2] < m_MinMaxOutput[2].first ? ROUND_P(pntInIndexCoordinates[2]) : m_MinMaxOutput[2].first; m_MinMaxOutput[2].second = pntInIndexCoordinates[2] > m_MinMaxOutput[2].second ? ROUND_P(pntInIndexCoordinates[2]) : m_MinMaxOutput[2].second; } this->EnforceImageBounds(); } void mitk::ClippedSurfaceBoundsCalculator::EnforceImageBounds() { m_MinMaxOutput[0].first = std::max( m_MinMaxOutput[0].first, 0 ); m_MinMaxOutput[1].first = std::max( m_MinMaxOutput[1].first, 0 ); m_MinMaxOutput[2].first = std::max( m_MinMaxOutput[2].first, 0 ); m_MinMaxOutput[0].second = std::min( m_MinMaxOutput[0].second, (int) m_Image->GetDimension(0)-1 ); m_MinMaxOutput[1].second = std::min( m_MinMaxOutput[1].second, (int) m_Image->GetDimension(1)-1 ); m_MinMaxOutput[2].second = std::min( m_MinMaxOutput[2].second, (int) m_Image->GetDimension(2)-1 ); } diff --git a/Core/Code/Algorithms/mitkClippedSurfaceBoundsCalculator.h b/Core/Code/Algorithms/mitkClippedSurfaceBoundsCalculator.h index 690c10e554..8d9fe18283 100644 --- a/Core/Code/Algorithms/mitkClippedSurfaceBoundsCalculator.h +++ b/Core/Code/Algorithms/mitkClippedSurfaceBoundsCalculator.h @@ -1,122 +1,122 @@ /*=================================================================== 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 ClippedSurfaceBoundsCalculator_h_included #define ClippedSurfaceBoundsCalculator_h_included #include "mitkImage.h" #include "mitkPlaneGeometry.h" #include /** * \brief Find image slices visible on a given plane. * * The class name is not helpful in finding this class. Good suggestions welcome. * * Given a PlaneGeometry (e.g. the 2D plane of a render window), this class * calculates which slices of an mitk::Image are visible on this plane. * Calculation is done for X, Y, and Z direction, the result is available in * form of a pair (minimum,maximum) slice index. * * Such calculations are useful if you want to display information about the * currently visible slice (overlays, statistics, ...) and you don't want to * depend on any prior information about hat the renderwindow is currently showing. * * \warning The interface attempts to look like an ITK filter but it is far from being one. */ namespace mitk { class MITK_CORE_EXPORT ClippedSurfaceBoundsCalculator { public: typedef std::vector PointListType; ClippedSurfaceBoundsCalculator(const mitk::PlaneGeometry* geometry = NULL, mitk::Image::Pointer image = NULL); - ClippedSurfaceBoundsCalculator(const mitk::Geometry3D* geometry, + ClippedSurfaceBoundsCalculator(const mitk::BaseGeometry* geometry, mitk::Image::Pointer image); ClippedSurfaceBoundsCalculator(const PointListType pointlist, mitk::Image::Pointer image); void InitializeOutput(); virtual ~ClippedSurfaceBoundsCalculator(); void SetInput(const mitk::PlaneGeometry* geometry, mitk::Image* image); - void SetInput(const mitk::Geometry3D *geometry, mitk::Image *image); + void SetInput(const mitk::BaseGeometry *geometry, mitk::Image *image); void SetInput(const PointListType pointlist, mitk::Image *image); /** \brief Request calculation. How cut/visible slice indices are determined: 1. construct a bounding box of the image. This is the box that connect the outer voxel centers(!). 2. check the edges of this box. 3. intersect each edge with the plane geometry - if the intersection point is within the image box, we update the visible/cut slice indices for all dimensions. - else we ignore the cut */ void Update(); /** \brief Minimum (first) and maximum (second) slice index. */ typedef std::pair OutputType; /** \brief What X coordinates (slice indices) are cut/visible in given plane. */ OutputType GetMinMaxSpatialDirectionX(); /** \brief What Y coordinates (slice indices) are cut/visible in given plane. */ OutputType GetMinMaxSpatialDirectionY(); /** \brief What Z coordinates (slice indices) are cut/visible in given plane. */ OutputType GetMinMaxSpatialDirectionZ(); protected: void CalculateIntersectionPoints(const mitk::PlaneGeometry* geometry); void CalculateIntersectionPoints( PointListType pointList ); /** * \brief Clips the resulting index-coordinates to make sure they do * not exceed the imagebounds. */ void EnforceImageBounds(); mitk::PlaneGeometry::ConstPointer m_PlaneGeometry; - mitk::Geometry3D::ConstPointer m_Geometry3D; + mitk::BaseGeometry::ConstPointer m_Geometry3D; mitk::Image::Pointer m_Image; std::vector m_ObjectPointsInWorldCoordinates; std::vector< OutputType > m_MinMaxOutput; }; } //namespace mitk #endif diff --git a/Core/Code/Algorithms/mitkImageTimeSelector.cpp b/Core/Code/Algorithms/mitkImageTimeSelector.cpp index 57a8952a17..8cbd73a08e 100644 --- a/Core/Code/Algorithms/mitkImageTimeSelector.cpp +++ b/Core/Code/Algorithms/mitkImageTimeSelector.cpp @@ -1,99 +1,99 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkImageTimeSelector.h" mitk::ImageTimeSelector::ImageTimeSelector() : m_TimeNr(0), m_ChannelNr(0) { } mitk::ImageTimeSelector::~ImageTimeSelector() { } void mitk::ImageTimeSelector::GenerateOutputInformation() { Image::ConstPointer input = this->GetInput(); Image::Pointer output = this->GetOutput(); itkDebugMacro(<<"GenerateOutputInformation()"); int dim=(input->GetDimension()<3?input->GetDimension():3); output->Initialize(input->GetPixelType(), dim, input->GetDimensions()); if( (unsigned int) m_TimeNr >= input->GetDimension(3) ) { m_TimeNr = input->GetDimension(3)-1; } // initialize geometry mitk::SlicedGeometry3D::Pointer sliced_geo = input->GetSlicedGeometry(m_TimeNr); if( sliced_geo.IsNull() ) { mitkThrow() << "Failed to retrieve SlicedGeometry from input at timestep " << m_TimeNr; } mitk::SlicedGeometry3D::Pointer sliced_geo_clone = sliced_geo->Clone(); if( sliced_geo_clone.IsNull() ) { mitkThrow() << "Failed to clone the retrieved sliced geometry."; } - mitk::Geometry3D::Pointer geom_3d = dynamic_cast(sliced_geo_clone.GetPointer()); + mitk::BaseGeometry::Pointer geom_3d = dynamic_cast(sliced_geo_clone.GetPointer()); if( geom_3d.IsNotNull() ) { output->SetGeometry(geom_3d.GetPointer() ); } else { mitkThrow() << "Failed to cast the retrieved SlicedGeometry to a Geometry3D object."; } output->SetPropertyList(input->GetPropertyList()->Clone()); } void mitk::ImageTimeSelector::GenerateData() { const Image::RegionType& requestedRegion = this->GetOutput()->GetRequestedRegion(); //do we really need a complete volume at a time? if(requestedRegion.GetSize(2)>1) this->SetVolumeItem( this->GetVolumeData(m_TimeNr, m_ChannelNr), 0 ); else //no, so take just a slice! this->SetSliceItem( this->GetSliceData(requestedRegion.GetIndex(2), m_TimeNr, m_ChannelNr), requestedRegion.GetIndex(2), 0 ); } void mitk::ImageTimeSelector::GenerateInputRequestedRegion() { Superclass::GenerateInputRequestedRegion(); ImageToImageFilter::InputImagePointer input = const_cast< mitk::ImageToImageFilter::InputImageType * > ( this->GetInput() ); Image::Pointer output = this->GetOutput(); Image::RegionType requestedRegion; requestedRegion = output->GetRequestedRegion(); requestedRegion.SetIndex(3, m_TimeNr); requestedRegion.SetIndex(4, m_ChannelNr); requestedRegion.SetSize(3, 1); requestedRegion.SetSize(4, 1); input->SetRequestedRegion( & requestedRegion ); } diff --git a/Core/Code/DataManagement/mitkImagePixelAccessor.h b/Core/Code/DataManagement/mitkImagePixelAccessor.h index 52895dc5bb..5bfea1638e 100644 --- a/Core/Code/DataManagement/mitkImagePixelAccessor.h +++ b/Core/Code/DataManagement/mitkImagePixelAccessor.h @@ -1,117 +1,117 @@ /*=================================================================== 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 MITKIMAGEPIXELACCESSOR_H #define MITKIMAGEPIXELACCESSOR_H #include #include #include #include #include #include "mitkImageAccessorBase.h" #include "mitkImageDataItem.h" #include "mitkPixelType.h" #include "mitkImage.h" namespace mitk { class Image; //##Documentation //## @brief Provides templated image access for all inheriting classes //## @tparam TPixel defines the PixelType //## @tparam VDimension defines the dimension for accessing data //## @ingroup Data template class ImagePixelAccessor { friend class Image; public: typedef itk::Index IndexType; typedef ImagePixelAccessor ImagePixelAccessorType; /** Get Dimensions from ImageDataItem */ int GetDimension (int i) const { return m_ImageDataItem->GetDimension(i); } protected: /** \param ImageDataItem* specifies the allocated image part */ ImagePixelAccessor(mitk::Image::Pointer iP, mitk::ImageDataItem* iDI) : m_ImageDataItem(iDI) { if(iDI == NULL) m_ImageDataItem = iP->GetChannelData(); } /** Destructor */ virtual ~ImagePixelAccessor() { } protected: // protected members /** Holds the specified ImageDataItem */ ImageDataItem* m_ImageDataItem; /** \brief Pointer to the used Geometry. * Since Geometry can be different to the Image (if memory was forced to be coherent) it is necessary to store Geometry separately. */ - Geometry3D::Pointer m_Geometry; + BaseGeometry::Pointer m_Geometry; /** \brief A Subregion defines an arbitrary area within the image. * If no SubRegion is defined, the whole ImageDataItem or Image is regarded. * A subregion (e.g. subvolume) can lead to non-coherent memory access where every dimension has a start- and end-offset. */ itk::ImageRegion* m_SubRegion; /** \brief Stores all extended properties of an ImageAccessor. * The different flags in mitk::ImageAccessorBase::Options can be unified by bitwise operations. */ int m_Options; /** Get memory offset for a given image index */ unsigned int GetOffset(const IndexType & idx) const { const unsigned int * imageDims = m_ImageDataItem->m_Dimensions; unsigned int offset = 0; switch(VDimension) { case 4: offset += idx[3]*imageDims[0]*imageDims[1]*imageDims[2]; case 3: offset += idx[2]*imageDims[0]*imageDims[1]; case 2: offset += idx[0] + idx[1]*imageDims[0]; break; } return offset; } private: }; } #endif // MITKIMAGEACCESSOR_H diff --git a/Core/Code/DataManagement/mitkSlicedGeometry3D.h b/Core/Code/DataManagement/mitkSlicedGeometry3D.h index b64cf26d94..6aa00533b0 100644 --- a/Core/Code/DataManagement/mitkSlicedGeometry3D.h +++ b/Core/Code/DataManagement/mitkSlicedGeometry3D.h @@ -1,311 +1,311 @@ /*=================================================================== 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 MITKSLICEDGEOMETRY3D_H_HEADER_INCLUDED_C1EBD0AD #define MITKSLICEDGEOMETRY3D_H_HEADER_INCLUDED_C1EBD0AD -#include "mitkGeometry3D.h" +#include "mitkBaseGeometry.h" #include "mitkPlaneGeometry.h" namespace mitk { class SliceNavigationController; class NavigationController; /** \brief Describes the geometry of a data object consisting of slices. * * A Geometry2D can be requested for each slice. In the case of * \em evenly-spaced, \em plane geometries (m_EvenlySpaced==true), * only the 2D-geometry of the first slice has to be set (to an instance of * PlaneGeometry). The 2D geometries of the other slices are calculated * by shifting the first slice in the direction m_DirectionVector by * m_Spacing.z * sliceNumber. The m_Spacing member (which is only * relevant in the case m_EvenlySpaced==true) descibes the size of a voxel * (in mm), i.e., m_Spacing.x is the voxel width in the x-direction of the * plane. It is derived from the reference geometry of this SlicedGeometry3D, * which usually would be the global geometry describing how datasets are to * be resliced. * * By default, slices are oriented in the direction of one of the main axes * (x, y, z). However, by means of rotation, it is possible to realign the * slices in any possible direction. In case of an inclined plane, the spacing * is derived as a product of the (regular) geometry spacing and the direction * vector of the plane. * * SlicedGeometry3D and the associated Geometry2Ds have to be initialized in * the method GenerateOutputInformation() of BaseProcess (or CopyInformation / * UpdateOutputInformation of BaseData, if possible, e.g., by analyzing pic * tags in Image) subclasses. See also * * \sa itk::ProcessObject::GenerateOutputInformation(), * \sa itk::DataObject::CopyInformation() and * \a itk::DataObject::UpdateOutputInformation(). * * Rule: everything is in mm (or ms for temporal information) if not * stated otherwise. * * \warning The hull (i.e., transform, bounding-box and * time-bounds) is only guaranteed to be up-to-date after calling * UpdateInformation(). * * \ingroup Geometry */ - class MITK_CORE_EXPORT SlicedGeometry3D : public mitk::Geometry3D + class MITK_CORE_EXPORT SlicedGeometry3D : public mitk::BaseGeometry { public: - mitkClassMacro(SlicedGeometry3D, Geometry3D); + mitkClassMacro(SlicedGeometry3D, BaseGeometry); /** Method for creation through the object factory. */ itkNewMacro(Self); /** * \brief Returns the Geometry2D of the slice (\a s). * * If (a) m_EvenlySpaced==true, (b) we don't have a Geometry2D stored * for the requested slice, and (c) the first slice (s=0) * is a PlaneGeometry instance, then we calculate the geometry of the * requested as the plane of the first slice shifted by m_Spacing[3]*s * in the direction of m_DirectionVector. * * \warning The Geometry2Ds are not necessarily up-to-date and not even * initialized. * * The Geometry2Ds have to be initialized in the method * GenerateOutputInformation() of BaseProcess (or CopyInformation / * UpdateOutputInformation of BaseData, if possible, e.g., by analyzing * pic tags in Image) subclasses. See also * * \sa itk::ProcessObject::GenerateOutputInformation(), * \sa itk::DataObject::CopyInformation() and * \sa itk::DataObject::UpdateOutputInformation(). */ virtual mitk::Geometry2D* GetGeometry2D( int s ) const; /** * \brief Set Geometry2D of slice \a s. */ virtual bool SetGeometry2D( mitk::Geometry2D *geometry2D, int s ); //##Documentation //## @brief When switching from an Image Geometry to a normal Geometry (and the other way around), you have to change the origin as well (See Geometry Documentation)! This function will change the "isImageGeometry" bool flag and changes the origin respectively. virtual void ChangeImageGeometryConsideringOriginOffset( const bool isAnImageGeometry ); virtual const mitk::BoundingBox* GetBoundingBox() const; /** * \brief Get the number of slices */ itkGetConstMacro( Slices, unsigned int ); /** * \brief Check whether a slice exists */ virtual bool IsValidSlice( int s = 0 ) const; virtual void SetReferenceGeometry( BaseGeometry *referenceGeometry ); /** * \brief Set the SliceNavigationController corresponding to this sliced * geometry. * * The SNC needs to be informed when the number of slices in the geometry * changes, which can occur whenthe slices are re-oriented by rotation. */ virtual void SetSliceNavigationController( mitk::SliceNavigationController *snc ); mitk::SliceNavigationController *GetSliceNavigationController(); /** * \brief Set/Get whether the SlicedGeometry3D is evenly-spaced * (m_EvenlySpaced) * * If (a) m_EvenlySpaced==true, (b) we don't have a Geometry2D stored for * the requested slice, and (c) the first slice (s=0) is a PlaneGeometry * instance, then we calculate the geometry of the requested as the plane * of the first slice shifted by m_Spacing.z * s in the direction of * m_DirectionVector. * * \sa GetGeometry2D */ itkGetConstMacro(EvenlySpaced, bool); virtual void SetEvenlySpaced(bool on = true); /** * \brief Set/Get the vector between slices for the evenly-spaced case * (m_EvenlySpaced==true). * * If the direction-vector is (0,0,0) (the default) and the first * 2D geometry is a PlaneGeometry, then the direction-vector will be * calculated from the plane normal. * * \sa m_DirectionVector */ virtual void SetDirectionVector(const mitk::Vector3D& directionVector); itkGetConstMacro(DirectionVector, const mitk::Vector3D&); virtual itk::LightObject::Pointer InternalClone() const; static const std::string SLICES; const static std::string DIRECTION_VECTOR; const static std::string EVENLY_SPACED; /** * \brief Tell this instance how many Geometry2Ds it shall manage. Bounding * box and the Geometry2Ds must be set additionally by calling the respective * methods! * * \warning Bounding box and the 2D-geometries must be set additionally: use * SetBounds(), SetGeometry(). */ virtual void InitializeSlicedGeometry( unsigned int slices ); /** * \brief Completely initialize this instance as evenly-spaced with slices * parallel to the provided Geometry2D that is used as the first slice and * for spacing calculation. * * Initializes the bounding box according to the width/height of the * Geometry2D and \a slices. The spacing is calculated from the Geometry2D. */ virtual void InitializeEvenlySpaced( mitk::Geometry2D *geometry2D, unsigned int slices, bool flipped=false ); /** * \brief Completely initialize this instance as evenly-spaced with slices * parallel to the provided Geometry2D that is used as the first slice and * for spacing calculation (except z-spacing). * * Initializes the bounding box according to the width/height of the * Geometry2D and \a slices. The x-/y-spacing is calculated from the * Geometry2D. */ virtual void InitializeEvenlySpaced( mitk::Geometry2D *geometry2D, mitk::ScalarType zSpacing, unsigned int slices, bool flipped=false ); /** * \brief Completely initialize this instance as evenly-spaced plane slices * parallel to a side of the provided Geometry3D and using its spacing * information. * * Initializes the bounding box according to the width/height of the * Geometry3D and the number of slices according to * Geometry3D::GetExtent(2). * * \param planeorientation side parallel to which the slices will be oriented * \param top if \a true, create plane at top, otherwise at bottom * (for PlaneOrientation Axial, for other plane locations respectively) * \param frontside defines the side of the plane (the definition of * front/back is somewhat arbitrary) * * \param rotate rotates the plane by 180 degree around its normal (the * definition of rotated vs not rotated is somewhat arbitrary) */ virtual void InitializePlanes( const mitk::BaseGeometry *geometry3D, mitk::PlaneGeometry::PlaneOrientation planeorientation, bool top=true, bool frontside=true, bool rotated=false ); virtual void SetImageGeometry(const bool isAnImageGeometry); virtual void ExecuteOperation(Operation* operation); static double CalculateSpacing( const mitk::Vector3D spacing, const mitk::Vector3D &d ); protected: SlicedGeometry3D(); SlicedGeometry3D(const SlicedGeometry3D& other); virtual ~SlicedGeometry3D(); virtual void InternPostSetTimeBounds( const mitk::TimeBounds& timebounds ); /** * \brief Set the spacing (m_Spacing), in direction of the plane normal. * * INTERNAL METHOD. */ virtual void InternPreSetSpacing( const mitk::Vector3D &aSpacing ); /** * Reinitialize plane stack after rotation. More precisely, the first plane * of the stack needs to spatially aligned, in two respects: * * 1. Re-alignment with respect to the dataset center; this is necessary * since the distance from the first plane to the center could otherwise * continuously decrease or increase. * 2. Re-alignment with respect to a given reference point; the reference * point is a location which the user wants to be exactly touched by one * plane of the plane stack. The first plane is minimally shifted to * ensure this touching. Usually, the reference point would be the * point around which the geometry is rotated. */ virtual void ReinitializePlanes( const Point3D ¢er, const Point3D &referencePoint ); ScalarType GetLargestExtent( const BaseGeometry *geometry ); void PrintSelf(std::ostream& os, itk::Indent indent) const; /** Calculate "directed spacing", i.e. the spacing in directions * non-orthogonal to the coordinate axes. This is done via the * ellipsoid equation. */ double CalculateSpacing( const mitk::Vector3D &direction ) const; /** The extent of the slice stack, i.e. the number of slices, depends on the * plane normal. For rotated geometries, the geometry's transform needs to * be accounted in this calculation. */ mitk::Vector3D AdjustNormal( const mitk::Vector3D &normal ) const; /** * Container for the 2D-geometries contained within this SliceGeometry3D. */ mutable std::vector m_Geometry2Ds; /** * If (a) m_EvenlySpaced==true, (b) we don't have a Geometry2D stored * for the requested slice, and (c) the first slice (s=0) * is a PlaneGeometry instance, then we calculate the geometry of the * requested as the plane of the first slice shifted by m_Spacing.z*s * in the direction of m_DirectionVector. * * \sa GetGeometry2D */ bool m_EvenlySpaced; /** * Vector between slices for the evenly-spaced case (m_EvenlySpaced==true). * If the direction-vector is (0,0,0) (the default) and the first * 2D geometry is a PlaneGeometry, then the direction-vector will be * calculated from the plane normal. */ mutable mitk::Vector3D m_DirectionVector; /** Number of slices this SliceGeometry3D is descibing. */ unsigned int m_Slices; /** Underlying Geometry3D for this SlicedGeometry */ mitk::BaseGeometry *m_ReferenceGeometry; /** SNC correcsponding to this geometry; used to reflect changes in the * number of slices due to rotation. */ //mitk::NavigationController *m_NavigationController; mitk::SliceNavigationController *m_SliceNavigationController; }; } // namespace mitk #endif /* MITKSLICEDGEOMETRY3D_H_HEADER_INCLUDED_C1EBD0AD */ diff --git a/Core/Code/Testing/mitkClippedSurfaceBoundsCalculatorTest.cpp b/Core/Code/Testing/mitkClippedSurfaceBoundsCalculatorTest.cpp index 13d97a5ff8..ebf8d1c31d 100644 --- a/Core/Code/Testing/mitkClippedSurfaceBoundsCalculatorTest.cpp +++ b/Core/Code/Testing/mitkClippedSurfaceBoundsCalculatorTest.cpp @@ -1,484 +1,484 @@ /*=================================================================== 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 "mitkTestingMacros.h" #include #include "mitkClippedSurfaceBoundsCalculator.h" #include "mitkGeometry3D.h" #include "mitkGeometry2D.h" #include "mitkVector.h" -static void CheckPlanesInsideBoundingBoxOnlyOnOneSlice(mitk::Geometry3D::Pointer geometry3D) +static void CheckPlanesInsideBoundingBoxOnlyOnOneSlice(mitk::BaseGeometry::Pointer geometry3D) { //Check planes which are inside the bounding box mitk::ClippedSurfaceBoundsCalculator* calculator = new mitk::ClippedSurfaceBoundsCalculator(); mitk::Image::Pointer image = mitk::Image::New(); image->Initialize( mitk::MakePixelType(), *(geometry3D.GetPointer()) ); //Check planes which are only on one slice: //Slice 0 mitk::Point3D origin; origin[0] = 511; origin[1] = 0; origin[2] = 0; mitk::Vector3D normal; mitk::FillVector3D(normal, 0, 0, 1); mitk::PlaneGeometry::Pointer planeOnSliceZero = mitk::PlaneGeometry::New(); planeOnSliceZero->InitializePlane(origin, normal); calculator->SetInput( planeOnSliceZero , image); calculator->Update(); mitk::ClippedSurfaceBoundsCalculator::OutputType minMax = calculator->GetMinMaxSpatialDirectionZ(); MITK_TEST_CONDITION(minMax.first == minMax.second, "Check if plane is only on one slice"); MITK_TEST_CONDITION(minMax.first == 0 && minMax.second == 0, "Check if plane is on slice 0"); //Slice 3 origin[2] = 3; mitk::PlaneGeometry::Pointer planeOnSliceThree = mitk::PlaneGeometry::New(); planeOnSliceThree->InitializePlane(origin, normal); planeOnSliceThree->SetImageGeometry(false); calculator->SetInput( planeOnSliceThree , image); calculator->Update(); minMax = calculator->GetMinMaxSpatialDirectionZ(); MITK_TEST_CONDITION(minMax.first == minMax.second, "Check if plane is only on one slice"); MITK_TEST_CONDITION(minMax.first == 3 && minMax.second == 3, "Check if plane is on slice 3"); //Slice 17 origin[2] = 17; mitk::PlaneGeometry::Pointer planeOnSliceSeventeen = mitk::PlaneGeometry::New(); planeOnSliceSeventeen->InitializePlane(origin, normal); calculator->SetInput( planeOnSliceSeventeen , image); calculator->Update(); minMax = calculator->GetMinMaxSpatialDirectionZ(); MITK_TEST_CONDITION(minMax.first == minMax.second, "Check if plane is only on one slice"); MITK_TEST_CONDITION(minMax.first == 17 && minMax.second == 17, "Check if plane is on slice 17"); //Slice 20 origin[2] = 19; mitk::PlaneGeometry::Pointer planeOnSliceTwenty = mitk::PlaneGeometry::New(); planeOnSliceTwenty->InitializePlane(origin, normal); calculator->SetInput( planeOnSliceTwenty , image); calculator->Update(); minMax = calculator->GetMinMaxSpatialDirectionZ(); MITK_TEST_CONDITION(minMax.first == minMax.second, "Check if plane is only on one slice"); MITK_TEST_CONDITION(minMax.first == 19 && minMax.second == 19, "Check if plane is on slice 19"); delete calculator; } -static void CheckPlanesInsideBoundingBox(mitk::Geometry3D::Pointer geometry3D) +static void CheckPlanesInsideBoundingBox(mitk::BaseGeometry::Pointer geometry3D) { //Check planes which are inside the bounding box mitk::ClippedSurfaceBoundsCalculator* calculator = new mitk::ClippedSurfaceBoundsCalculator(); mitk::Image::Pointer image = mitk::Image::New(); image->Initialize( mitk::MakePixelType(), *(geometry3D.GetPointer()) ); //Check planes which are only on one slice: //Slice 0 mitk::Point3D origin; origin[0] = 511; // Set to 511.9 so that the intersection point is inside the bounding box origin[1] = 0; origin[2] = 0; mitk::Vector3D normal; mitk::FillVector3D(normal, 1, 0, 0); mitk::PlaneGeometry::Pointer planeSagittalOne = mitk::PlaneGeometry::New(); planeSagittalOne->InitializePlane(origin, normal); calculator->SetInput( planeSagittalOne , image); calculator->Update(); mitk::ClippedSurfaceBoundsCalculator::OutputType minMax = calculator->GetMinMaxSpatialDirectionZ(); MITK_TEST_CONDITION(minMax.first == 0 && minMax.second == 19, "Check if plane is from slice 0 to slice 19"); //Slice 3 origin[0] = 256; MITK_INFO << "Case1 origin: " << origin; mitk::PlaneGeometry::Pointer planeSagittalTwo = mitk::PlaneGeometry::New(); planeSagittalTwo->InitializePlane(origin, normal); MITK_INFO << "PlaneNormal: " << planeSagittalTwo->GetNormal(); MITK_INFO << "PlaneOrigin: " << planeSagittalTwo->GetOrigin(); calculator->SetInput( planeSagittalTwo , image); calculator->Update(); minMax = calculator->GetMinMaxSpatialDirectionZ(); MITK_INFO << "min: " << minMax.first << " max: " << minMax.second; MITK_TEST_CONDITION(minMax.first == 0 && minMax.second == 19, "Check if plane is from slice 0 to slice 19"); //Slice 17 origin[0] = 0; // Set to 0.1 so that the intersection point is inside the bounding box mitk::PlaneGeometry::Pointer planeOnSliceSeventeen = mitk::PlaneGeometry::New(); planeOnSliceSeventeen->InitializePlane(origin, normal); calculator->SetInput( planeOnSliceSeventeen , image); calculator->Update(); minMax = calculator->GetMinMaxSpatialDirectionZ(); MITK_TEST_CONDITION(minMax.first == 0 && minMax.second == 19, "Check if plane is from slice 0 to slice 19"); //Crooked planes: origin[0] = 0; origin[1] = 507; origin[2] = 0; normal[0] = 1; normal[1] = -1; normal[2] = 1; mitk::PlaneGeometry::Pointer planeCrookedOne = mitk::PlaneGeometry::New(); planeCrookedOne->InitializePlane(origin, normal); calculator->SetInput( planeCrookedOne , image); calculator->Update(); minMax = calculator->GetMinMaxSpatialDirectionZ(); MITK_INFO << "min: " << minMax.first << " max: " << minMax.second; MITK_TEST_CONDITION(minMax.first == 0 && minMax.second == 4, "Check if plane is from slice 0 to slice 4 with inclined plane"); origin[0] = 512; origin[1] = 0; origin[2] = 16; mitk::PlaneGeometry::Pointer planeCrookedTwo = mitk::PlaneGeometry::New(); planeCrookedTwo->InitializePlane(origin, normal); calculator->SetInput( planeCrookedTwo , image); calculator->Update(); minMax = calculator->GetMinMaxSpatialDirectionZ(); MITK_INFO << "min: " << minMax.first << " max: " << minMax.second; MITK_TEST_CONDITION(minMax.first == 17 && minMax.second == 19, "Check if plane is from slice 17 to slice 19 with inclined plane"); origin[0] = 511; origin[1] = 0; origin[2] = 0; normal[1] = 0; normal[2] = 0.04; mitk::PlaneGeometry::Pointer planeCrookedThree = mitk::PlaneGeometry::New(); planeCrookedThree->InitializePlane(origin, normal); calculator->SetInput( planeCrookedThree , image); calculator->Update(); minMax = calculator->GetMinMaxSpatialDirectionZ(); MITK_INFO << "min: " << minMax.first << " max: " << minMax.second; MITK_TEST_CONDITION(minMax.first == 0 && minMax.second == 19, "Check if plane is from slice 0 to slice 19 with inclined plane"); delete calculator; } -static void CheckPlanesOutsideOfBoundingBox(mitk::Geometry3D::Pointer geometry3D) +static void CheckPlanesOutsideOfBoundingBox(mitk::BaseGeometry::Pointer geometry3D) { //Check planes which are outside of the bounding box mitk::ClippedSurfaceBoundsCalculator* calculator = new mitk::ClippedSurfaceBoundsCalculator(); mitk::Image::Pointer image = mitk::Image::New(); image->Initialize( mitk::MakePixelType(), *(geometry3D.GetPointer()) ); //In front of the bounding box mitk::Point3D origin; origin[0] = 511; origin[1] = 0; origin[2] = -5; mitk::Vector3D normal; mitk::FillVector3D(normal, 0, 0, 1); mitk::PlaneGeometry::Pointer planeInFront = mitk::PlaneGeometry::New(); planeInFront->InitializePlane(origin, normal); calculator->SetInput( planeInFront , image); calculator->Update(); mitk::ClippedSurfaceBoundsCalculator::OutputType minMax = calculator->GetMinMaxSpatialDirectionZ(); MITK_TEST_CONDITION(minMax.first == std::numeric_limits::max(), "Check if min value hasn't been set"); MITK_TEST_CONDITION(minMax.second == std::numeric_limits::min(), "Check if max value hasn't been set"); //Behind the bounding box origin[2] = 515; mitk::PlaneGeometry::Pointer planeBehind = mitk::PlaneGeometry::New(); planeBehind->InitializePlane(origin, normal); calculator->SetInput( planeBehind , image); calculator->Update(); minMax = calculator->GetMinMaxSpatialDirectionZ(); MITK_TEST_CONDITION(minMax.first == std::numeric_limits::max(), "Check if min value hasn't been set"); MITK_TEST_CONDITION(minMax.second == std::numeric_limits::min(), "Check if max value hasn't been set"); //Above origin[1] = 515; mitk::FillVector3D(normal, 0, 1, 0); mitk::PlaneGeometry::Pointer planeAbove = mitk::PlaneGeometry::New(); planeAbove->InitializePlane(origin, normal); calculator->SetInput( planeAbove , image); calculator->Update(); minMax = calculator->GetMinMaxSpatialDirectionZ(); MITK_TEST_CONDITION(minMax.first == std::numeric_limits::max(), "Check if min value hasn't been set"); MITK_TEST_CONDITION(minMax.second == std::numeric_limits::min(), "Check if max value hasn't been set"); //Below origin[1] = -5; mitk::PlaneGeometry::Pointer planeBelow = mitk::PlaneGeometry::New(); planeBelow->InitializePlane(origin, normal); calculator->SetInput( planeBelow , image); calculator->Update(); minMax = calculator->GetMinMaxSpatialDirectionZ(); MITK_TEST_CONDITION(minMax.first == std::numeric_limits::max(), "Check if min value hasn't been set"); MITK_TEST_CONDITION(minMax.second == std::numeric_limits::min(), "Check if max value hasn't been set"); //Left side origin[0] = -5; mitk::FillVector3D(normal, 1, 0, 0); mitk::PlaneGeometry::Pointer planeLeftSide = mitk::PlaneGeometry::New(); planeLeftSide->InitializePlane(origin, normal); calculator->SetInput( planeLeftSide , image); calculator->Update(); minMax = calculator->GetMinMaxSpatialDirectionZ(); MITK_TEST_CONDITION(minMax.first == std::numeric_limits::max(), "Check if min value hasn't been set"); MITK_TEST_CONDITION(minMax.second == std::numeric_limits::min(), "Check if max value hasn't been set"); //Right side origin[1] = 515; mitk::PlaneGeometry::Pointer planeRightSide = mitk::PlaneGeometry::New(); planeRightSide->InitializePlane(origin, normal); calculator->SetInput( planeRightSide , image); calculator->Update(); minMax = calculator->GetMinMaxSpatialDirectionZ(); MITK_TEST_CONDITION(minMax.first == std::numeric_limits::max(), "Check if min value hasn't been set"); MITK_TEST_CONDITION(minMax.second == std::numeric_limits::min(), "Check if max value hasn't been set"); delete calculator; } -static void CheckIntersectionPointsOfTwoGeometry3D(mitk::Geometry3D::Pointer firstGeometry3D, mitk::Geometry3D::Pointer secondGeometry3D) +static void CheckIntersectionPointsOfTwoGeometry3D(mitk::BaseGeometry::Pointer firstGeometry3D, mitk::BaseGeometry::Pointer secondGeometry3D) { mitk::ClippedSurfaceBoundsCalculator* calculator = new mitk::ClippedSurfaceBoundsCalculator(); mitk::Image::Pointer firstImage = mitk::Image::New(); firstImage->Initialize( mitk::MakePixelType(), *(firstGeometry3D.GetPointer()) ); calculator->SetInput( secondGeometry3D, firstImage); calculator->Update(); mitk::ClippedSurfaceBoundsCalculator::OutputType minMax = calculator->GetMinMaxSpatialDirectionZ(); minMax = calculator->GetMinMaxSpatialDirectionZ(); MITK_INFO << "min: " << minMax.first << " max: " << minMax.second; MITK_TEST_CONDITION(minMax.first == 0 && minMax.second == 19, "Check if plane is from slice 0 to slice 19"); } -static void CheckIntersectionWithPointCloud( mitk::Geometry3D::Pointer geometry3D ) +static void CheckIntersectionWithPointCloud( mitk::BaseGeometry::Pointer geometry3D ) { //Check planes which are inside the bounding box mitk::Image::Pointer image = mitk::Image::New(); image->Initialize( mitk::MakePixelType(), *(geometry3D.GetPointer()) ); { mitk::Point3D pnt1, pnt2; pnt1[0] = 3; pnt1[1] = 5; pnt1[2] = 3; pnt2[0] = 8; pnt2[1] = 3; pnt2[2] = 8; mitk::ClippedSurfaceBoundsCalculator::PointListType pointlist; pointlist.push_back( pnt1 ); pointlist.push_back( pnt2 ); mitk::ClippedSurfaceBoundsCalculator calculator; calculator.SetInput( pointlist, image ); calculator.Update(); mitk::ClippedSurfaceBoundsCalculator::OutputType minMaxZ = calculator.GetMinMaxSpatialDirectionZ(); MITK_TEST_CONDITION(minMaxZ.first == 3 && minMaxZ.second == 8, "Check if points span from slice 3 to slice 8 in axial"); mitk::ClippedSurfaceBoundsCalculator::OutputType minMaxX = calculator.GetMinMaxSpatialDirectionX(); MITK_TEST_CONDITION(minMaxX.first == 3 && minMaxX.second == 5, "Check if points span from slice 3 to slice 5 in sagittal"); } { mitk::Point3D pnt1, pnt2; pnt1.Fill( -3 ); pnt2.Fill( 600 ); mitk::ClippedSurfaceBoundsCalculator::PointListType pointlist; pointlist.push_back( pnt1 ); pointlist.push_back( pnt2 ); mitk::ClippedSurfaceBoundsCalculator calculator; calculator.SetInput( pointlist, image ); calculator.Update(); mitk::ClippedSurfaceBoundsCalculator::OutputType minMaxZ = calculator.GetMinMaxSpatialDirectionZ(); MITK_TEST_CONDITION(minMaxZ.first == 0 && minMaxZ.second == 19, "Check if points are correctly clipped to slice 0 and slice 19 in axial"); mitk::ClippedSurfaceBoundsCalculator::OutputType minMaxX = calculator.GetMinMaxSpatialDirectionX(); MITK_TEST_CONDITION(minMaxX.first == 0 && minMaxX.second == 511, "Check if points are correctly clipped to slice 0 and slice 511 in sagittal"); } } int mitkClippedSurfaceBoundsCalculatorTest(int, char* []) { // always start with this! MITK_TEST_BEGIN("ClippedSurfaceBoundsCalculator"); /** The class mitkClippedSurfaceBoundsCalculator calculates the intersection points of a PlaneGeometry and a Geometry3D. * This unittest checks if the correct min and max values for the three spatial directions (x, y, z) * are calculated. To test this we define artifical PlaneGeometries and Geometry3Ds and test different * scenarios: * * 1. planes which are inside the bounding box of a 3D geometry but only on one slice * 2. planes which are outside of the bounding box * 3. planes which are inside the bounding box but over more than one slice * * Note: Currently rotated geometries are not tested! */ /********************* Define Geometry3D ***********************/ //Define origin: mitk::Point3D origin; origin[0] = 511; origin[1] = 0; origin[2] = 0; //Define normal: mitk::Vector3D normal; mitk::FillVector3D(normal, 0, 0, 1); //Initialize PlaneGeometry: mitk::PlaneGeometry::Pointer planeGeometry = mitk::PlaneGeometry::New(); planeGeometry->InitializePlane(origin, normal); //Set Bounds: mitk::BoundingBox::BoundsArrayType bounds = planeGeometry->GetBounds(); bounds[0] = 0; bounds[1] = 512; bounds[2] = 0; bounds[3] = 512; bounds[4] = 0; bounds[5] = 1; planeGeometry->SetBounds(bounds); //Initialize SlicedGeometry3D: mitk::SlicedGeometry3D::Pointer slicedGeometry3D = mitk::SlicedGeometry3D::New(); slicedGeometry3D->InitializeEvenlySpaced(dynamic_cast(planeGeometry.GetPointer()), 20); - mitk::Geometry3D::Pointer geometry3D = dynamic_cast< mitk::Geometry3D* > ( slicedGeometry3D.GetPointer() ); + mitk::BaseGeometry::Pointer geometry3D = dynamic_cast< mitk::BaseGeometry* > ( slicedGeometry3D.GetPointer() ); geometry3D->SetImageGeometry(true); //Define origin for second Geometry3D; mitk::Point3D origin2; origin2[0] = 511; origin2[1] = 60; origin2[2] = 0; //Define normal: mitk::Vector3D normal2; mitk::FillVector3D(normal2, 0, 1, 0); //Initialize PlaneGeometry: mitk::PlaneGeometry::Pointer planeGeometry2 = mitk::PlaneGeometry::New(); planeGeometry2->InitializePlane(origin2, normal2); //Initialize SlicedGeometry3D: mitk::SlicedGeometry3D::Pointer secondSlicedGeometry3D = mitk::SlicedGeometry3D::New(); secondSlicedGeometry3D->InitializeEvenlySpaced(dynamic_cast(planeGeometry2.GetPointer()), 20); - mitk::Geometry3D::Pointer secondGeometry3D = dynamic_cast< mitk::Geometry3D* > ( secondSlicedGeometry3D.GetPointer() ); + mitk::BaseGeometry::Pointer secondGeometry3D = dynamic_cast< mitk::BaseGeometry* > ( secondSlicedGeometry3D.GetPointer() ); secondGeometry3D->SetImageGeometry(true); /***************************************************************/ CheckPlanesInsideBoundingBoxOnlyOnOneSlice(geometry3D); CheckPlanesOutsideOfBoundingBox(geometry3D); CheckPlanesInsideBoundingBox(geometry3D); CheckIntersectionPointsOfTwoGeometry3D(geometry3D, secondGeometry3D); CheckIntersectionWithPointCloud( geometry3D ); /** ToDo: * test also rotated 3D geometry! */ MITK_TEST_END(); } diff --git a/Modules/MitkExt/Algorithms/mitkPlanesPerpendicularToLinesFilter.cpp b/Modules/MitkExt/Algorithms/mitkPlanesPerpendicularToLinesFilter.cpp index 26b8115c35..c162172885 100644 --- a/Modules/MitkExt/Algorithms/mitkPlanesPerpendicularToLinesFilter.cpp +++ b/Modules/MitkExt/Algorithms/mitkPlanesPerpendicularToLinesFilter.cpp @@ -1,212 +1,212 @@ /*=================================================================== 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 "mitkPlanesPerpendicularToLinesFilter.h" #include #include #include mitk::PlanesPerpendicularToLinesFilter::PlanesPerpendicularToLinesFilter() : m_Plane(NULL), m_UseAllPoints(false), m_CreatedGeometries(NULL), normal(3), targetRight(3) { m_CreatedGeometries = mitk::SlicedGeometry3D::New(); } mitk::PlanesPerpendicularToLinesFilter::~PlanesPerpendicularToLinesFilter() { } void mitk::PlanesPerpendicularToLinesFilter::GenerateOutputInformation() { mitk::Mesh::ConstPointer input = this->GetInput(); mitk::GeometryData::Pointer output = this->GetOutput(); itkDebugMacro(<<"GenerateOutputInformation()"); if(input.IsNull()) return; output->SetGeometry(m_CreatedGeometries); } void mitk::PlanesPerpendicularToLinesFilter::CreatePlane(const mitk::Point3D& curr) { int j; for(j=0;j<3;++j) normal[j] = last[j]-curr[j]; //@todo globally define normal direction of display xxx normal.normalize(); down = vnl_cross_3d(normal, targetRight); down.normalize(); right = vnl_cross_3d(down, normal); right.normalize(); itk2vtk(last.GetVnlVector()-right*halfWidthInMM-down*halfHeightInMM, origin); right *= targetSpacing[0]; down *= targetSpacing[1]; normal *= targetSpacing[2]; mitk::Matrix3D matrix; matrix.GetVnlMatrix().set_column(0, right); matrix.GetVnlMatrix().set_column(1, down); matrix.GetVnlMatrix().set_column(2, normal); PlaneGeometry::Pointer plane = PlaneGeometry::New(); plane->GetIndexToWorldTransform()->SetMatrix(matrix); plane->SetOrigin(origin); plane->SetBounds(bounds); planes.push_back(plane); last = curr; } void mitk::PlanesPerpendicularToLinesFilter::GenerateData() { mitk::Mesh::ConstPointer input = this->GetInput(); mitk::GeometryData::Pointer output = this->GetOutput(); if(m_Plane.IsNotNull()) { targetRight = m_Plane->GetMatrixColumn(0); targetSpacing = m_Plane->GetSpacing(); bounds = m_Plane->GetBoundingBox()->GetBounds(); halfWidthInMM = m_Plane->GetExtentInMM(0)*0.5; halfHeightInMM = m_Plane->GetExtentInMM(1)*0.5; } else { FillVector3D(targetRight, 1.0, 0.0, 0.0); targetSpacing.Fill(1.0); halfWidthInMM=halfHeightInMM=100.0; ScalarType stdBounds[6] = {0.0, 2.0*halfWidthInMM, 0.0, 2.0*halfHeightInMM, 0.0, 0.0}; bounds = stdBounds; } if(m_UseAllPoints==false) { int i, size; //iterate through all cells and build planes Mesh::ConstCellIterator cellIt, cellEnd; cellEnd = input->GetMesh()->GetCells()->End(); for( cellIt = input->GetMesh()->GetCells()->Begin(); cellIt != cellEnd; ++cellIt ) { Mesh::CellType& cell = *cellIt->Value(); Mesh::PointIdIterator ptIt, ptEnd; ptEnd = cell.PointIdsEnd(); size=cell.GetNumberOfPoints(); if(size<=1) continue; ptIt = cell.PointIdsBegin(); last = input->GetPoint(*ptIt); ++ptIt; for(i=1;iGetPoint(*ptIt)); } } } else //m_UseAllPoints==true { //iterate through all points and build planes mitk::PointSet::PointsConstIterator it, pend = input->GetPointSet()->GetPoints()->End(); it=input->GetPointSet()->GetPoints()->Begin(); last = it.Value(); ++it; for(;it!=pend;++it) { CreatePlane(it.Value()); } } if(planes.size()>0) { //initialize sliced-geometry for the number of created planes m_CreatedGeometries->InitializeSlicedGeometry(planes.size()+1); //set last plane at last point with same normal as the one before the last PlaneGeometry::Pointer plane = static_cast((*planes.rbegin())->Clone().GetPointer()); itk2vtk(last.GetVnlVector()-right*halfWidthInMM-down*halfHeightInMM, origin); plane->SetOrigin(origin); m_CreatedGeometries->SetGeometry2D(plane, planes.size()); //add all planes to sliced-geometry int s; for(s=0; planes.empty()==false; planes.pop_front(), ++s) { m_CreatedGeometries->SetGeometry2D(planes.front(), s); } m_CreatedGeometries->SetEvenlySpaced(false); if(m_FrameGeometry.IsNotNull()) { m_CreatedGeometries->SetIndexToWorldTransform(m_FrameGeometry->GetIndexToWorldTransform()); m_CreatedGeometries->SetBounds(m_FrameGeometry->GetBounds()); m_CreatedGeometries->SetReferenceGeometry(m_FrameGeometry); } } output->SetGeometry(m_CreatedGeometries); } void mitk::PlanesPerpendicularToLinesFilter::SetPlane(const mitk::PlaneGeometry* aPlane) { if(aPlane!=NULL) { m_Plane = static_cast(aPlane->Clone().GetPointer()); } else { if(m_Plane.IsNull()) return; m_Plane=NULL; } Modified(); } const mitk::Mesh *mitk::PlanesPerpendicularToLinesFilter::GetInput(void) { if (this->GetNumberOfInputs() < 1) { return 0; } return static_cast (this->ProcessObject::GetInput(0) ); } void mitk::PlanesPerpendicularToLinesFilter::SetInput(const mitk::Mesh *input) { // Process object is not const-correct so the const_cast is required here this->ProcessObject::SetNthInput(0, const_cast< mitk::Mesh * >( input ) ); } -void mitk::PlanesPerpendicularToLinesFilter::SetFrameGeometry(const mitk::Geometry3D* frameGeometry) +void mitk::PlanesPerpendicularToLinesFilter::SetFrameGeometry(const mitk::BaseGeometry* frameGeometry) { if((frameGeometry != NULL) && (frameGeometry->IsValid())) { - m_FrameGeometry = static_cast(frameGeometry->Clone().GetPointer()); + m_FrameGeometry = static_cast(frameGeometry->Clone().GetPointer()); } else { m_FrameGeometry = NULL; } } diff --git a/Modules/MitkExt/Algorithms/mitkPlanesPerpendicularToLinesFilter.h b/Modules/MitkExt/Algorithms/mitkPlanesPerpendicularToLinesFilter.h index cc4f3261ea..e5e0768b2d 100644 --- a/Modules/MitkExt/Algorithms/mitkPlanesPerpendicularToLinesFilter.h +++ b/Modules/MitkExt/Algorithms/mitkPlanesPerpendicularToLinesFilter.h @@ -1,144 +1,144 @@ /*=================================================================== 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 MITKPLANESPERPENDICULARTOLINES_H_HEADER_INCLUDED_C10B22CD #define MITKPLANESPERPENDICULARTOLINES_H_HEADER_INCLUDED_C10B22CD #include "mitkGeometryDataSource.h" #include "MitkExtExports.h" #include "mitkMesh.h" #include "mitkGeometryData.h" #include "mitkPlaneGeometry.h" #include "mitkSlicedGeometry3D.h" namespace mitk { //##Documentation //## @brief Create Planes perpendicular to lines contained in a Mesh. The planes data is generated as one SlicedGeometry3D data. //## To create the planes as input a //## mitk::mesh (for example a pointSet) and as geometry hint a geometry (for example from the original image) must be given. //## //## mitk::Mesh::Pointer mesh = mitk::Mesh::New(); //## mesh->SetMesh(pointSet->GetPointSet()); //## mitk::Image* currentImage = dynamic_cast (myDataStorage->GetNamedNode(IMAGE)->GetData()); //## const mitk::Geometry3D* imagegeometry = currentImage->GetUpdatedGeometry(); //## mitk::PlanesPerpendicularToLinesFilter::Pointer perpendicularPlanes = mitk::PlanesPerpendicularToLinesFilter::New(); //## perpendicularPlanes->SetInput(mesh); //## perpendicularPlanes->SetUseAllPoints(true); //## perpendicularPlanes->SetFrameGeometry(imagegeometry); //## perpendicularPlanes->Update(); //## //## To get one single plane out of these use SlicedGeometry3D->GetGeometry2D(int slicenumber). //## @ingroup Process class MitkExt_EXPORT PlanesPerpendicularToLinesFilter : public GeometryDataSource { public: mitkClassMacro(PlanesPerpendicularToLinesFilter, GeometryDataSource); itkNewMacro(Self); virtual void GenerateOutputInformation(); virtual void GenerateData(); const mitk::Mesh *GetInput(void); //## @brief Set the input mesh that is used to create the planes. virtual void SetInput(const mitk::Mesh *image); //##Documentation //## @brief Set plane to be used as an example of the planes to move //## along the lines in the input mesh. //## //## The size and spacing are copied from the plane. The in-plane //## orientation (right-vector) of the created planes are set as //## parallel as possible to the orientation (right-vector) of the //## the plane set using this method. //## @note The PlaneGeometry is cloned, @em not linked/referenced. virtual void SetPlane(const mitk::PlaneGeometry* aPlane); //##Documentation //## @brief Set if all points in the mesh should be interpreted as //## one long line. //## //## Cells are not used in this mode, but all points in the order //## of their indices form the line. //## Default is @a false. itkGetConstMacro(UseAllPoints, bool); //##Documentation //## @brief Set if all points of the mesh shall be used (true) or the cells (false) //## Default is @a false. itkSetMacro(UseAllPoints, bool); itkBooleanMacro(UseAllPoints); //##Documentation //## @brief Set an explicit frame of the created sliced geometry //## //## Set an explicit framegeometry for the created sliced geometry. This framegeometry is //## used as geometry for all created planes. //## Uses the IndexToWorldTransform and bounding box of the //## provided geometry. //## \sa CalculateFrameGeometry - virtual void SetFrameGeometry(const mitk::Geometry3D* frameGeometry); + virtual void SetFrameGeometry(const mitk::BaseGeometry* frameGeometry); protected: PlanesPerpendicularToLinesFilter(); virtual ~PlanesPerpendicularToLinesFilter(); //## @brief Creates the plane at point curr //## //## Creates the plane at point curr. To create this plane, the last point must //## must be renowned. //## \sa SetPlane void CreatePlane(const Point3D& curr); //## @brief Plane to be used as an example of the planes to move //## along the lines in the input mesh. //## //## The size and spacing are copied from the m_Plane. The in-plane //## orientation (right-vector) of the created planes are set as //## parallel as possible to the orientation (right-vector) of m_Plane. //## \sa SetPlane mitk::PlaneGeometry::Pointer m_Plane; bool m_UseAllPoints; //##Documentation //## @brief SlicedGeometry3D containing the created planes //## SlicedGeometry3D::Pointer m_CreatedGeometries; - mitk::Geometry3D::Pointer m_FrameGeometry; + mitk::BaseGeometry::Pointer m_FrameGeometry; private: std::deque planes; Point3D last; VnlVector normal; VnlVector right, down; VnlVector targetRight; Vector3D targetSpacing; ScalarType halfWidthInMM, halfHeightInMM; - mitk::Geometry3D::BoundsArrayType bounds; + mitk::BaseGeometry::BoundsArrayType bounds; Point3D origin; }; } // namespace mitk #endif /* MITKPLANESPERPENDICULARTOLINES_H_HEADER_INCLUDED_C10B22CD */ diff --git a/Modules/MitkExt/Algorithms/mitkProbeFilter.cpp b/Modules/MitkExt/Algorithms/mitkProbeFilter.cpp index f3c6416b1f..8b0ba5a2bf 100644 --- a/Modules/MitkExt/Algorithms/mitkProbeFilter.cpp +++ b/Modules/MitkExt/Algorithms/mitkProbeFilter.cpp @@ -1,213 +1,213 @@ /*=================================================================== 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 "mitkProbeFilter.h" #include "mitkSurface.h" #include "mitkImage.h" #include #include #include #include #include mitk::ProbeFilter::ProbeFilter() { } mitk::ProbeFilter::~ProbeFilter() { } const mitk::Surface *mitk::ProbeFilter::GetInput(void) { if (this->GetNumberOfInputs() < 1) { return 0; } return static_cast< const mitk::Surface * >(this->ProcessObject::GetInput(0) ); } const mitk::Image *mitk::ProbeFilter::GetSource(void) { return static_cast< const mitk::Image * >(this->ProcessObject::GetInput(1)); } void mitk::ProbeFilter::SetInput(const mitk::Surface *input) { this->ProcessObject::SetNthInput( 0, const_cast< mitk::Surface * >( input ) ); } void mitk::ProbeFilter::SetSource(const mitk::Image *source) { this->ProcessObject::SetNthInput( 1, const_cast< mitk::Image * >( source ) ); } void mitk::ProbeFilter::GenerateOutputInformation() { mitk::Surface::ConstPointer input = this->GetInput(); mitk::Image::ConstPointer source = this->GetSource(); mitk::Surface::Pointer output = this->GetOutput(); if(input.IsNull()) return; if(source.IsNull()) return; if(input->GetGeometry()==NULL) return; if(source->GetGeometry()==NULL) return; if( (input->GetTimeGeometry()->CountTimeSteps()==1) && (source->GetTimeGeometry()->CountTimeSteps()>1) ) { - Geometry3D::Pointer geometry3D = Geometry3D::New(); + BaseGeometry::Pointer geometry3D = BaseGeometry::New(); geometry3D->Initialize(); geometry3D->SetBounds(source->GetTimeGeometry()->GetBoundsInWorld()); geometry3D->SetTimeBounds(source->GetTimeGeometry()->GetGeometryForTimeStep(0)->GetTimeBounds()); ProportionalTimeGeometry::Pointer outputTimeGeometry = ProportionalTimeGeometry::New(); outputTimeGeometry->Initialize(geometry3D, source->GetTimeGeometry()->CountTimeSteps()); output->Expand(outputTimeGeometry->CountTimeSteps()); output->SetTimeGeometry( outputTimeGeometry ); } else - output->SetGeometry( static_cast(input->GetGeometry()->Clone().GetPointer()) ); + output->SetGeometry( static_cast(input->GetGeometry()->Clone().GetPointer()) ); itkDebugMacro(<<"GenerateOutputInformation()"); } void mitk::ProbeFilter::GenerateData() { mitk::Surface *input = const_cast< mitk::Surface * >(this->GetInput()); mitk::Image *source = const_cast< mitk::Image * >(this->GetSource()); mitk::Surface::Pointer output = this->GetOutput(); itkDebugMacro(<<"Generating Data"); if(output.IsNull()) { itkDebugMacro(<<"Output is NULL."); return; } mitk::Surface::RegionType outputRegion = output->GetRequestedRegion(); const TimeGeometry *outputTimeGeometry = output->GetTimeGeometry(); const TimeGeometry *inputTimeGeometry = input->GetTimeGeometry(); const TimeGeometry *sourceTimeGeometry = source->GetTimeGeometry(); TimePointType timeInMS; int timestep=0; int tstart, tmax; tstart=outputRegion.GetIndex(3); tmax=tstart+outputRegion.GetSize(3); int t; for(t=tstart;tTimeStepToTimePoint( t ); vtkProbeFilter* probe = vtkProbeFilter::New(); timestep = inputTimeGeometry->TimePointToTimeStep( timeInMS ); probe->SetInputData( input->GetVtkPolyData(timestep) ); timestep = sourceTimeGeometry->TimePointToTimeStep( timeInMS ); probe->SetSourceData( source->GetVtkImageData(timestep) ); output->SetVtkPolyData( probe->GetPolyDataOutput(), t ); probe->Update(); probe->Delete(); } } void mitk::ProbeFilter::GenerateInputRequestedRegion() { Superclass::GenerateInputRequestedRegion(); mitk::Surface *input = const_cast< mitk::Surface * >( this->GetInput() ); mitk::Image *source = const_cast< mitk::Image * >( this->GetSource() ); if(input==NULL) return; if(source==NULL) return; mitk::Surface::Pointer output = this->GetOutput(); mitk::Surface::RegionType outputRegion = output->GetRequestedRegion(); const TimeGeometry *outputTimeGeometry = output->GetTimeGeometry(); mitk::Surface::RegionType inputSurfaceRegion = outputRegion; Image::RegionType sourceImageRegion = source->GetLargestPossibleRegion(); if(outputRegion.GetSize(3)<1) { mitk::Surface::RegionType::SizeType surfacesize; surfacesize.Fill(0); inputSurfaceRegion.SetSize(surfacesize); input->SetRequestedRegion( &inputSurfaceRegion ); mitk::Image::RegionType::SizeType imagesize; imagesize.Fill(0); sourceImageRegion.SetSize(imagesize); source->SetRequestedRegion( &sourceImageRegion ); return; } //create and set input requested region for the input surface const TimeGeometry *inputTimeGeometry = input->GetTimeGeometry(); ScalarType timeInMS; int timestep=0; // convert the start-index-time of output in start-index-time of input via millisecond-time timeInMS = outputTimeGeometry->TimeStepToTimePoint(outputRegion.GetIndex(3)); timestep = inputTimeGeometry->TimePointToTimeStep( timeInMS ); if( ( timeInMS > ScalarTypeNumericTraits::NonpositiveMin() ) && ( inputTimeGeometry->IsValidTimeStep( timestep ) ) ) inputSurfaceRegion.SetIndex( 3, timestep ); else inputSurfaceRegion.SetIndex( 3, 0 ); // convert the end-index-time of output in end-index-time of input via millisecond-time timeInMS = outputTimeGeometry->TimeStepToTimePoint(outputRegion.GetIndex(3)+outputRegion.GetSize(3)-1); timestep = inputTimeGeometry->TimePointToTimeStep( timeInMS ); if( ( timeInMS > ScalarTypeNumericTraits::NonpositiveMin() ) && ( outputTimeGeometry->IsValidTimeStep( timestep ) ) ) inputSurfaceRegion.SetSize( 3, timestep - inputSurfaceRegion.GetIndex(3) + 1 ); else inputSurfaceRegion.SetSize( 3, 1 ); input->SetRequestedRegion( &inputSurfaceRegion ); //create and set input requested region for the source image const TimeGeometry *sourceTimeGeometry = source->GetTimeGeometry(); // convert the start-index-time of output in start-index-time of source via millisecond-time timeInMS = outputTimeGeometry->TimeStepToTimePoint(outputRegion.GetIndex(3)); timestep = sourceTimeGeometry->TimePointToTimeStep( timeInMS ); if( ( timeInMS > ScalarTypeNumericTraits::NonpositiveMin() ) && ( sourceTimeGeometry->IsValidTimeStep( timestep ) ) ) sourceImageRegion.SetIndex( 3, timestep ); else sourceImageRegion.SetIndex( 3, 0 ); // convert the end-index-time of output in end-index-time of source via millisecond-time timeInMS = outputTimeGeometry->TimeStepToTimePoint(outputRegion.GetIndex(3)+outputRegion.GetSize(3)-1); timestep = sourceTimeGeometry->TimePointToTimeStep( timeInMS ); if( ( timeInMS > ScalarTypeNumericTraits::NonpositiveMin() ) && ( outputTimeGeometry->IsValidTimeStep( timestep ) ) ) sourceImageRegion.SetSize( 3, timestep - sourceImageRegion.GetIndex(3) + 1 ); else sourceImageRegion.SetSize( 3, 1 ); sourceImageRegion.SetIndex( 4, 0 ); sourceImageRegion.SetSize( 4, 1 ); source->SetRequestedRegion( &sourceImageRegion ); } diff --git a/Modules/QmitkExt/QmitkSliceWidget.cpp b/Modules/QmitkExt/QmitkSliceWidget.cpp index dc18e6000b..ab6cac245a 100644 --- a/Modules/QmitkExt/QmitkSliceWidget.cpp +++ b/Modules/QmitkExt/QmitkSliceWidget.cpp @@ -1,334 +1,334 @@ /*=================================================================== 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 "QmitkSliceWidget.h" #include "QmitkStepperAdapter.h" #include "mitkNodePredicateDataType.h" #include //#include "QmitkRenderWindow.h" // //#include "mitkSliceNavigationController.h" //#include "QmitkLevelWindowWidget.h" // //#include //#include "mitkRenderingManager.h" #include #include QmitkSliceWidget::QmitkSliceWidget(QWidget* parent, const char* name, Qt::WindowFlags f) : QWidget(parent, f) { this->setupUi(this); if (name != 0) this->setObjectName(name); popUp = new QMenu(this); popUp->addAction("Axial"); popUp->addAction("Frontal"); popUp->addAction("Sagittal"); QObject::connect(popUp, SIGNAL(triggered(QAction*)), this, SLOT(ChangeView(QAction*)) ); setPopUpEnabled(false); m_SlicedGeometry = 0; m_View = mitk::SliceNavigationController::Axial; QHBoxLayout *hlayout = new QHBoxLayout(container); hlayout->setMargin(0); // create widget QString composedName("QmitkSliceWidget::"); if (!this->objectName().isEmpty()) composedName += this->objectName(); else composedName += "QmitkGLWidget"; m_RenderWindow = new QmitkRenderWindow(container, composedName); m_Renderer = m_RenderWindow->GetRenderer(); hlayout->addWidget(m_RenderWindow); new QmitkStepperAdapter(m_NavigatorWidget, m_RenderWindow->GetSliceNavigationController()->GetSlice(), "navigation"); SetLevelWindowEnabled(true); } mitk::VtkPropRenderer* QmitkSliceWidget::GetRenderer() { return m_Renderer; } QFrame* QmitkSliceWidget::GetSelectionFrame() { return SelectionFrame; } void QmitkSliceWidget::SetDataStorage( mitk::StandaloneDataStorage::Pointer storage) { m_DataStorage = storage; m_Renderer->SetDataStorage(m_DataStorage); } mitk::StandaloneDataStorage* QmitkSliceWidget::GetDataStorage() { return m_DataStorage; } void QmitkSliceWidget::SetData( mitk::DataStorage::SetOfObjects::ConstIterator it) { SetData(it->Value(), m_View); } void QmitkSliceWidget::SetData( mitk::DataStorage::SetOfObjects::ConstIterator it, mitk::SliceNavigationController::ViewDirection view) { SetData(it->Value(), view); } void QmitkSliceWidget::SetData(mitk::DataNode::Pointer node) { try { if (m_DataStorage.IsNotNull()) { m_DataStorage->Add(node); } } catch (...) { } SetData(node, m_View); } //void QmitkSliceWidget::AddData( mitk::DataNode::Pointer node) //{ // if ( m_DataTree.IsNull() ) // { // m_DataTree = mitk::DataTree::New(); // } // mitk::DataTreePreOrderIterator it(m_DataTree); // it.Add( node ); // SetData(&it, m_View); //} void QmitkSliceWidget::SetData(mitk::DataNode::Pointer node, mitk::SliceNavigationController::ViewDirection view) { mitk::Image::Pointer image = dynamic_cast(node->GetData()); if (image.IsNull()) { MITK_WARN << "QmitkSliceWidget data is not an image!"; return; } m_SlicedGeometry = image->GetSlicedGeometry(); this->InitWidget(view); } void QmitkSliceWidget::InitWidget( mitk::SliceNavigationController::ViewDirection viewDirection) { m_View = viewDirection; mitk::SliceNavigationController* controller = m_RenderWindow->GetSliceNavigationController(); if (viewDirection == mitk::SliceNavigationController::Axial) { controller->SetViewDirection( mitk::SliceNavigationController::Axial); } else if (viewDirection == mitk::SliceNavigationController::Frontal) { controller->SetViewDirection(mitk::SliceNavigationController::Frontal); } // init sagittal view else { controller->SetViewDirection(mitk::SliceNavigationController::Sagittal); } int currentPos = 0; if (m_RenderWindow->GetSliceNavigationController()) { currentPos = controller->GetSlice()->GetPos(); } if (m_SlicedGeometry.IsNull()) { return; } // compute bounding box with respect to first images geometry const mitk::BoundingBox::BoundsArrayType imageBounds = m_SlicedGeometry->GetBoundingBox()->GetBounds(); // mitk::SlicedGeometry3D::Pointer correctGeometry = m_SlicedGeometry.GetPointer(); - mitk::Geometry3D::Pointer + mitk::BaseGeometry::Pointer geometry = - static_cast (m_SlicedGeometry->Clone().GetPointer()); + static_cast (m_SlicedGeometry->Clone().GetPointer()); const mitk::BoundingBox::Pointer boundingbox = m_DataStorage->ComputeVisibleBoundingBox(GetRenderer(), NULL); if (boundingbox->GetPoints()->Size() > 0) { ////geometry = mitk::Geometry3D::New(); ////geometry->Initialize(); //geometry->SetBounds(boundingbox->GetBounds()); //geometry->SetSpacing(correctGeometry->GetSpacing()); //let's see if we have data with a limited live-span ... mitk::TimeBounds timebounds = m_DataStorage->ComputeTimeBounds( GetRenderer(), NULL); if (timebounds[1] < mitk::ScalarTypeNumericTraits::max()) { mitk::ScalarType duration = timebounds[1] - timebounds[0]; timebounds[1] = timebounds[0] + 1.0f; geometry->SetTimeBounds(timebounds); } mitk::ProportionalTimeGeometry::Pointer timeGeometry = mitk::ProportionalTimeGeometry::New(); timeGeometry->Initialize(geometry,1); if (const_cast (timeGeometry->GetBoundingBoxInWorld())->GetDiagonalLength2() >= mitk::eps) { controller->SetInputWorldTimeGeometry(timeGeometry); controller->Update(); } } GetRenderer()->GetDisplayGeometry()->Fit(); mitk::RenderingManager::GetInstance()->RequestUpdate( GetRenderer()->GetRenderWindow()); //int w=vtkObject::GetGlobalWarningDisplay(); //vtkObject::GlobalWarningDisplayOff(); //vtkRenderer * vtkrenderer = ((mitk::OpenGLRenderer*)(GetRenderer()))->GetVtkRenderer(); //if(vtkrenderer!=NULL) vtkrenderer->ResetCamera(); //vtkObject::SetGlobalWarningDisplay(w); } void QmitkSliceWidget::UpdateGL() { GetRenderer()->GetDisplayGeometry()->Fit(); mitk::RenderingManager::GetInstance()->RequestUpdate( GetRenderer()->GetRenderWindow()); } void QmitkSliceWidget::mousePressEvent(QMouseEvent * e) { if (e->button() == Qt::RightButton && popUpEnabled) { popUp->popup(QCursor::pos()); } } void QmitkSliceWidget::wheelEvent(QWheelEvent * e) { int val = m_NavigatorWidget->GetPos(); if (e->orientation() * e->delta() > 0) { m_NavigatorWidget->SetPos(val + 1); } else { if (val > 0) m_NavigatorWidget->SetPos(val - 1); } } void QmitkSliceWidget::ChangeView(QAction* val) { if (val->text() == "Axial") { InitWidget(mitk::SliceNavigationController::Axial); } else if (val->text() == "Frontal") { InitWidget(mitk::SliceNavigationController::Frontal); } else if (val->text() == "Sagittal") { InitWidget(mitk::SliceNavigationController::Sagittal); } } void QmitkSliceWidget::setPopUpEnabled(bool b) { popUpEnabled = b; } QmitkSliderNavigatorWidget* QmitkSliceWidget::GetNavigatorWidget() { return m_NavigatorWidget; } void QmitkSliceWidget::SetLevelWindowEnabled(bool enable) { levelWindow->setEnabled(enable); if (!enable) { levelWindow->setMinimumWidth(0); levelWindow->setMaximumWidth(0); } else { levelWindow->setMinimumWidth(28); levelWindow->setMaximumWidth(28); } } bool QmitkSliceWidget::IsLevelWindowEnabled() { return levelWindow->isEnabled(); } QmitkRenderWindow* QmitkSliceWidget::GetRenderWindow() { return m_RenderWindow; } mitk::SliceNavigationController* QmitkSliceWidget::GetSliceNavigationController() const { return m_RenderWindow->GetSliceNavigationController(); } mitk::CameraRotationController* QmitkSliceWidget::GetCameraRotationController() const { return m_RenderWindow->GetCameraRotationController(); } mitk::BaseController* QmitkSliceWidget::GetController() const { return m_RenderWindow->GetController(); }