26 #include <vtkGeneralTransform.h>
27 #include <vtkImageChangeInformation.h>
28 #include <vtkImageData.h>
29 #include <vtkPoints.h>
30 #include <vtkSmartPointer.h>
31 #include <vtkTransform.h>
32 #include <vtkTransform.h>
36 MITK_WARN <<
"Class ExtractDirectedPlaneImageFilter is deprecated! Use ExtractSliceFilter instead.";
49 if (m_ResliceInterpolationProperty !=
nullptr)
50 m_ResliceInterpolationProperty->Delete();
57 if (m_WorldGeometry ==
nullptr)
59 itkWarningMacro(<<
"No world geometry has been set. Returning.");
68 itkWarningMacro(<<
"No input set.");
73 if ((inputTimeGeometry ==
nullptr) || (inputTimeGeometry->CountTimeSteps() == 0))
75 itkWarningMacro(<<
"Error reading input image geometry.");
80 unsigned int timestep = m_TargetTimestep;
84 itkWarningMacro(<<
"This is not a valid timestep: " << timestep);
91 itkWarningMacro(<<
"No volume data existent at given timestep " << timestep);
96 requestedRegion.SetIndex(3, timestep);
97 requestedRegion.SetSize(3, 1);
98 requestedRegion.SetSize(4, 1);
104 if (inputData ==
nullptr)
106 itkWarningMacro(<<
"Could not extract vtk image data for given timestep" << timestep);
111 inputData->GetSpacing(spacing);
119 Vector3D rightInIndex, bottomInIndex;
125 if (inputGeometry ==
nullptr)
127 itkWarningMacro(<<
"There is no Geometry3D at given timestep " << timestep);
136 bool boundsInitialized =
false;
138 for (
auto &bound : bounds)
147 if (dynamic_cast<const PlaneGeometry *>(m_WorldGeometry) !=
nullptr &&
148 dynamic_cast<const AbstractTransformGeometry *>(m_WorldGeometry) ==
nullptr)
156 if (m_InPlaneResampleExtentByGeometry)
162 extent[0] = m_WorldGeometry->GetExtent(0);
163 extent[1] = m_WorldGeometry->GetExtent(1);
171 inputGeometry->WorldToIndex(right, rightInIndex);
172 inputGeometry->WorldToIndex(bottom, bottomInIndex);
173 extent[0] = rightInIndex.GetNorm();
174 extent[1] = bottomInIndex.GetNorm();
179 widthInMM = m_WorldGeometry->GetExtentInMM(0);
180 heightInMM = m_WorldGeometry->GetExtentInMM(1);
182 mmPerPixel[0] = widthInMM / extent[0];
183 mmPerPixel[1] = heightInMM / extent[1];
196 m_Reslicer->SetResliceTransform(inputGeometry->GetVtkTransform()->GetLinearInverse());
199 m_Reslicer->SetBackgroundLevel(-32768);
205 if (m_WorldGeometry->GetReferenceGeometry())
216 else if (dynamic_cast<const AbstractTransformGeometry *>(m_WorldGeometry))
227 mmPerPixel[0] = widthInMM / extent[0];
228 mmPerPixel[1] = heightInMM / extent[1];
244 composedResliceTransform->Identity();
245 composedResliceTransform->Concatenate(inputGeometry->GetVtkTransform()->GetLinearInverse());
248 m_Reslicer->SetResliceTransform(composedResliceTransform);
252 m_Reslicer->SetBackgroundLevel(-1023);
253 composedResliceTransform->Delete();
257 itkWarningMacro(<<
"World Geometry has to be a PlaneGeometry or an AbstractTransformGeometry.");
262 if ((extent[0] <= 2) && (extent[1] <= 2))
264 itkWarningMacro(<<
"Image is too small to be resliced...");
269 unitSpacingImageFilter->SetOutputSpacing(1.0, 1.0, 1.0);
270 unitSpacingImageFilter->SetInputData(inputData);
272 m_Reslicer->SetInputConnection(unitSpacingImageFilter->GetOutputPort());
276 m_Reslicer->SetOutputDimensionality(2);
277 m_Reslicer->SetOutputOrigin(0.0, 0.0, 0.0);
280 pixelsPerMM[0] = 1.0 / mmPerPixel[0];
281 pixelsPerMM[1] = 1.0 / mmPerPixel[1];
284 double originArray[3];
287 m_Reslicer->SetResliceAxesOrigin(originArray);
292 vnl2vtk(right.GetVnlVector(), cosines);
295 vnl2vtk(bottom.GetVnlVector(), cosines + 3);
298 vnl2vtk(normal.GetVnlVector(), cosines + 6);
300 m_Reslicer->SetResliceAxesDirectionCosines(cosines);
302 int xMin, xMax, yMin, yMax;
303 if (boundsInitialized)
305 xMin =
static_cast<int>(bounds[0] / mmPerPixel[0]);
306 xMax =
static_cast<int>(bounds[1] / mmPerPixel[0]);
307 yMin =
static_cast<int>(bounds[2] / mmPerPixel[1]);
308 yMax =
static_cast<int>(bounds[3] / mmPerPixel[1]);
316 xMax =
static_cast<int>(extent[0] - pixelsPerMM[0]);
317 yMax =
static_cast<int>(extent[1] - pixelsPerMM[1]);
320 m_Reslicer->SetOutputSpacing(mmPerPixel[0], mmPerPixel[1], 1.0);
324 m_Reslicer->SetOutputExtent(xMin, xMax - 1, yMin, yMax - 1, 0, 1);
329 m_Reslicer->Modified();
330 m_Reslicer->ReleaseDataFlagOn();
332 m_Reslicer->Update();
335 vtkImageData *reslicedImage = m_Reslicer->GetOutput();
337 if ((reslicedImage ==
nullptr) || (reslicedImage->GetDataDimension() < 1))
339 itkWarningMacro(<<
"Reslicer returned empty image");
343 unsigned int dimensions[2];
344 dimensions[0] = (
unsigned int)extent[0];
345 dimensions[1] = (
unsigned int)extent[1];
347 FillVector3D(spacingVector, mmPerPixel[0], mmPerPixel[1], 1.0);
350 resultImage->Initialize(input->
GetPixelType(), 2, dimensions);
351 resultImage->SetSpacing(spacingVector);
356 Superclass::GenerateOutputInformation();
376 points->InsertPoint(0, bbMin[0] - 0.5, bbMin[1] - 0.5, bbMin[2] - 0.5);
377 points->InsertPoint(1, bbMin[0] - 0.5, bbMin[1] - 0.5, bbMax[2] - 0.5);
378 points->InsertPoint(2, bbMin[0] - 0.5, bbMax[1] - 0.5, bbMax[2] - 0.5);
379 points->InsertPoint(3, bbMin[0] - 0.5, bbMax[1] - 0.5, bbMin[2] - 0.5);
380 points->InsertPoint(4, bbMax[0] - 0.5, bbMin[1] - 0.5, bbMin[2] - 0.5);
381 points->InsertPoint(5, bbMax[0] - 0.5, bbMin[1] - 0.5, bbMax[2] - 0.5);
382 points->InsertPoint(6, bbMax[0] - 0.5, bbMax[1] - 0.5, bbMax[2] - 0.5);
383 points->InsertPoint(7, bbMax[0] - 0.5, bbMax[1] - 0.5, bbMin[2] - 0.5);
387 points->InsertPoint(0, bbMin[0], bbMin[1], bbMin[2]);
388 points->InsertPoint(1, bbMin[0], bbMin[1], bbMax[2]);
389 points->InsertPoint(2, bbMin[0], bbMax[1], bbMax[2]);
390 points->InsertPoint(3, bbMin[0], bbMax[1], bbMin[2]);
391 points->InsertPoint(4, bbMax[0], bbMin[1], bbMin[2]);
392 points->InsertPoint(5, bbMax[0], bbMin[1], bbMax[2]);
393 points->InsertPoint(6, bbMax[0], bbMax[1], bbMax[2]);
394 points->InsertPoint(7, bbMax[0], bbMax[1], bbMin[2]);
400 transform->Identity();
401 transform->Concatenate(planeGeometry->
GetVtkTransform()->GetLinearInverse());
405 transform->TransformPoints(points, newPoints);
408 bounds[0] = bounds[2] = 10000000.0;
409 bounds[1] = bounds[3] = -10000000.0;
410 bounds[4] = bounds[5] = 0.0;
429 if ((bounds[0] > 9999999.0) || (bounds[2] > 9999999.0) || (bounds[1] < -9999999.0) || (bounds[3] < -9999999.0))
438 bounds[0] *= planeSpacing[0];
439 bounds[1] *= planeSpacing[0];
440 bounds[2] *= planeSpacing[1];
441 bounds[3] *= planeSpacing[1];
442 bounds[4] *= planeSpacing[2];
443 bounds[5] *= planeSpacing[2];
452 points->GetPoint(p1, point1);
453 points->GetPoint(p2, point2);
455 if ((point1[2] * point2[2] <= 0.0) && (point1[2] != point2[2]))
458 x = (point1[0] * point2[2] - point1[2] * point2[0]) / (point2[2] - point1[2]);
459 y = (point1[1] * point2[2] - point1[2] * point2[1]) / (point2[2] - point1[2]);
477 bounds[4] = bounds[5] = 0.0;
const Point3D GetOrigin() const
Get the origin, e.g. the upper-left corner of the plane.
itk::BoundingBox< unsigned long, 3, ScalarType > BoundingBox
Standard 3D-BoundingBox typedef.
static bool CalculateClippedPlaneBounds(const BaseGeometry *boundingGeometry, const PlaneGeometry *planeGeometry, double *bounds)
Calculate the bounding box of the resliced image. This is necessary for arbitrarily rotated planes in...
virtual bool IsVolumeSet(int t=0, int n=0) const override
Check whether volume at time t in channel n is set.
virtual void SetRequestedRegion(const itk::DataObject *data) override
const mitk::Vector3D GetSpacing() const
Get the spacing (size of a pixel).
virtual vtkImageData * GetVtkImageData(int t=0, int n=0)
Get a volume at a specific time t of channel n as a vtkImageData.
const mitk::TimeGeometry * GetTimeGeometry() const
Return the TimeGeometry of the data as const pointer.
void FillVector3D(Tout &out, mitk::ScalarType x, mitk::ScalarType y, mitk::ScalarType z)
Vector3D GetNormal() const
Normal of the plane.
Vector3D GetAxisVector(unsigned int direction) const
Get vector along bounding-box in the specified direction in mm.
void vnl2vtk(const vnl_vector< Tin > &in, Tout *out)
itk::ImageRegion< RegionDimension > RegionType
Image class for storing images.
const RegionType & GetLargestPossibleRegion() const
const mitk::PixelType GetPixelType(int n=0) const
Returns the PixelType of channel n.
void itk2vtk(const Tin &in, Tout &out)
static bool LineIntersectZero(vtkPoints *points, int p1, int p2, double *bounds)
Internal helper method for intersection testing used only in CalculateClippedPlaneBounds() ...
virtual BaseGeometry::Pointer GetGeometryForTimeStep(TimeStepType timeStep) const =0
Returns the geometry which corresponds to the given time step.
Describes a two-dimensional, rectangular plane.
vtkLinearTransform * GetVtkTransform() const
Get the m_IndexToWorldTransform as a vtkLinearTransform.
virtual bool GetImageGeometry() const
Is this an ImageGeometry?
virtual bool IsValidTimeStep(TimeStepType timeStep) const =0
Test for the given time step if a geometry is availible.
BaseGeometry Describes the geometry of a data object.
virtual const BoundingBoxType * GetBoundingBox()
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.