| 20 | #include <mitkTimeNavigationController.h> |
| 21 | |
| 22 | unsigned int mitk::SliceNavigationHelper::SelectSliceByPoint(const TimeGeometry* timeGeometry, |
| 23 | const Point3D& point) |
| 24 | { |
| 25 | int selectedSlice = -1; |
| 26 | if (nullptr == timeGeometry) |
| 27 | { |
| 28 | return selectedSlice; |
| 29 | } |
| 30 | |
| 31 | // get the BaseGeometry of the selected time point |
| 32 | const auto selectedTimePoint = RenderingManager::GetInstance()->GetTimeNavigationController()->GetSelectedTimePoint(); |
| 33 | const auto currentGeometry = timeGeometry->GetGeometryForTimePoint(selectedTimePoint); |
| 34 | if (nullptr == currentGeometry) |
| 35 | { |
| 36 | // time point not valid for the ime geometry |
| 37 | mitkThrow() << "Cannot extract a base geometry. A time point is selected that is not covered by" |
| 38 | << "the given time geometry. Selected time point: " << selectedTimePoint; |
| 39 | } |
| 40 | |
| 41 | const auto* slicedGeometry = dynamic_cast<mitk::SlicedGeometry3D*>(currentGeometry.GetPointer()); |
| 42 | if (nullptr == slicedGeometry) |
| 43 | { |
| 44 | return selectedSlice; |
| 45 | } |
| 46 | |
| 47 | double bestDistance = itk::NumericTraits<double>::max(); |
| 48 | if (slicedGeometry->GetEvenlySpaced()) |
| 49 | { |
| 50 | PlaneGeometry* plane = slicedGeometry->GetPlaneGeometry(0); |
| 51 | const Vector3D& direction = slicedGeometry->GetDirectionVector(); |
| 52 | |
| 53 | Point3D projectedPoint; |
| 54 | plane->Project(point, projectedPoint); |
| 55 | |
| 56 | // check whether the point is somewhere within the slice stack volume |
| 57 | if (direction[0] * (point[0] - projectedPoint[0]) + direction[1] * (point[1] - projectedPoint[1]) + |
| 58 | direction[2] * (point[2] - projectedPoint[2]) >= 0) |
| 59 | { |
| 60 | selectedSlice = static_cast<int>(plane->Distance(point) / slicedGeometry->GetSpacing()[2] + 0.5); |
| 61 | } |
| 62 | } |
| 63 | else |
| 64 | { |
| 65 | const int numberOfSlices = slicedGeometry->GetSlices(); |
| 66 | Point3D projectedPoint; |
| 67 | for (int slice = 0; slice < numberOfSlices; ++slice) |
| 68 | { |
| 69 | slicedGeometry->GetPlaneGeometry(slice)->Project(point, projectedPoint); |
| 70 | const Vector3D distance = projectedPoint - point; |
| 71 | ScalarType currentDistance = distance.GetSquaredNorm(); |
| 72 | |
| 73 | if (currentDistance < bestDistance) |
| 74 | { |
| 75 | bestDistance = currentDistance; |
| 76 | selectedSlice = slice; |
| 77 | } |
| 78 | } |
| 79 | } |