Medical Imaging Interaction Toolkit  2025.12.02
Medical Imaging Interaction Toolkit
mitkSliceNavigationController.h
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #ifndef mitkSliceNavigationController_h
14 #define mitkSliceNavigationController_h
15 
16 #include <MitkCoreExports.h>
17 
18 #include <mitkBaseController.h>
19 #include <mitkMessage.h>
20 #include <mitkAnatomicalPlanes.h>
21 #include <mitkRenderingManager.h>
22 #include <mitkTimeGeometry.h>
23 
24 #pragma GCC visibility push(default)
25 #include <itkEventObject.h>
26 #pragma GCC visibility pop
27 
28 #include <itkCommand.h>
29 
30 namespace mitk
31 {
32 #define mitkTimeGeometryEventMacro(classname, super) \
33  class MITKCORE_EXPORT classname : public super \
34  { \
35  public: \
36  typedef classname Self; \
37  typedef super Superclass; \
38  classname(TimeGeometry *aTimeGeometry, unsigned int aPos) : Superclass(aTimeGeometry, aPos) {} \
39  virtual ~classname() {} \
40  virtual const char *GetEventName() const { return #classname; } \
41  virtual bool CheckEvent(const ::itk::EventObject *e) const { return dynamic_cast<const Self *>(e); } \
42  virtual ::itk::EventObject *MakeObject() const { return new Self(GetTimeGeometry(), GetPos()); } \
43  private: \
44  void operator=(const Self &); \
45  }
46 
47  class PlaneGeometry;
48  class BaseGeometry;
49  class BaseRenderer;
50 
131  {
132  public:
133 
135  itkNewMacro(Self);
136 
145  itkGetConstObjectMacro(InputWorldTimeGeometry, TimeGeometry);
146 
150  itkGetConstObjectMacro(CreatedWorldGeometry, TimeGeometry);
151  itkGetObjectMacro(CreatedWorldGeometry, TimeGeometry);
152 
162 
173  itkSetEnumMacro(DefaultViewDirection, AnatomicalPlane);
174  itkGetEnumMacro(DefaultViewDirection, AnatomicalPlane);
175 
176  const char *GetViewDirectionAsString() const;
177 
179 
185  virtual void Update();
186 
192  virtual void Update(AnatomicalPlane viewDirection, bool top = true, bool frontside = true, bool rotated = false);
193 
200  virtual void SendCreatedWorldGeometry();
201 
207 
214  virtual void SendSlice();
215 
216  class MITKCORE_EXPORT TimeGeometryEvent : public itk::AnyEvent
217  {
218  public:
220  typedef itk::AnyEvent Superclass;
221 
222  TimeGeometryEvent(TimeGeometry* aTimeGeometry, unsigned int aPos) : m_TimeGeometry(aTimeGeometry), m_Pos(aPos) {}
223  ~TimeGeometryEvent() override {}
224  const char* GetEventName() const override { return "TimeGeometryEvent"; }
225  bool CheckEvent(const ::itk::EventObject* e) const override { return dynamic_cast<const Self*>(e); }
226  ::itk::EventObject* MakeObject() const override { return new Self(m_TimeGeometry, m_Pos); }
227  TimeGeometry* GetTimeGeometry() const { return m_TimeGeometry; }
228  unsigned int GetPos() const { return m_Pos; }
229 
230  private:
231  TimeGeometry::Pointer m_TimeGeometry;
232  unsigned int m_Pos;
233  // TimeGeometryEvent(const Self&);
234  void operator=(const Self&); // just hide
235  };
236 
237 
241 
242  template <typename T>
243  void ConnectGeometrySendEvent(T* receiver)
244  {
245  auto eventReceptorCommand = itk::ReceptorMemberCommand<T>::New();
246  eventReceptorCommand->SetCallbackFunction(receiver, &T::SetGeometry);
247  unsigned long tag = AddObserver(GeometrySendEvent(nullptr, 0), eventReceptorCommand);
248  m_ReceiverToObserverTagsMap[static_cast<void*>(receiver)].push_back(tag);
249  }
250 
251  template <typename T>
252  void ConnectGeometryUpdateEvent(T* receiver)
253  {
254  auto eventReceptorCommand = itk::ReceptorMemberCommand<T>::New();
255  eventReceptorCommand->SetCallbackFunction(receiver, &T::UpdateGeometry);
256  unsigned long tag = AddObserver(GeometryUpdateEvent(nullptr, 0), eventReceptorCommand);
257  m_ReceiverToObserverTagsMap[static_cast<void*>(receiver)].push_back(tag);
258  }
259 
260  template <typename T>
261  void ConnectGeometrySliceEvent(T* receiver)
262  {
263  auto eventReceptorCommand = itk::ReceptorMemberCommand<T>::New();
264  eventReceptorCommand->SetCallbackFunction(receiver, &T::SetGeometrySlice);
265  unsigned long tag = AddObserver(GeometrySliceEvent(nullptr, 0), eventReceptorCommand);
266  m_ReceiverToObserverTagsMap[static_cast<void*>(receiver)].push_back(tag);
267  }
268 
269  // use a templated method to get the right offset when casting to void*
270  template <typename T>
271  void Disconnect(T* receiver)
272  {
273  auto i = m_ReceiverToObserverTagsMap.find(static_cast<void*>(receiver));
274  if (i == m_ReceiverToObserverTagsMap.end())
275  return;
276  const std::list<unsigned long>& tags = i->second;
277  for (auto tagIter = tags.begin(); tagIter != tags.end(); ++tagIter)
278  {
279  RemoveObserver(*tagIter);
280  }
281  m_ReceiverToObserverTagsMap.erase(i);
282  }
283 
285 
287  void SelectSliceByPoint(const Point3D& point);
288 
291 
296 
301  itkSetObjectMacro(Renderer, BaseRenderer);
302  itkGetMacro(Renderer, BaseRenderer*);
303 
309  void ReorientSlices(const Point3D& point, const Vector3D& normal);
310 
314  void ReorientSlices(const Point3D& point, const Vector3D& axisVec0, const Vector3D& axisVec1);
315 
316  void ExecuteOperation(Operation* operation) override;
317 
323  itkSetMacro(SliceLocked, bool);
324  itkGetMacro(SliceLocked, bool);
325  itkBooleanMacro(SliceLocked);
326 
333  itkSetMacro(SliceRotationLocked, bool);
334  itkGetMacro(SliceRotationLocked, bool);
335  itkBooleanMacro(SliceRotationLocked);
336 
342 
343  protected:
344 
347 
348  void CreateWorldGeometry(bool top, bool frontside, bool rotated);
349 
350  TimeGeometry::ConstPointer m_InputWorldTimeGeometry;
351  TimeGeometry::Pointer m_CreatedWorldGeometry;
352 
355 
356  RenderingManager::Pointer m_RenderingManager;
357 
359 
361 
364 
365  typedef std::map<void*, std::list<unsigned long>> ObserverTagsMapType;
367  };
368 
369 } // namespace mitk
370 
371 #endif
#define MITKCORE_EXPORT
Baseclass for renderer slice-/camera-/time-control.
BaseGeometry Describes the geometry of a data object.
Base class of all Operation-classes.
Definition: mitkOperation.h:30
Describes a two-dimensional, rectangular plane.
TimeGeometryEvent(TimeGeometry *aTimeGeometry, unsigned int aPos)
bool CheckEvent(const ::itk::EventObject *e) const override
Controls the selection of the slice the associated BaseRenderer will display.
void CreateWorldGeometry(bool top, bool frontside, bool rotated)
mitkClassMacro(SliceNavigationController, BaseController)
const BaseGeometry * GetCurrentGeometry3D()
Returns the BaseGeometry of the currently selected time step.
std::map< void *, std::list< unsigned long > > ObserverTagsMapType
void SetInputWorldTimeGeometry(const TimeGeometry *geometry)
Set the input world time geometry out of which the geometries for slicing will be created.
void AdjustSliceStepperRange()
Adjusts the numerical range of the slice stepper according to the current geometry orientation of thi...
itkSetEnumMacro(ViewDirection, AnatomicalPlane)
Set the desired view directions.
itkGetEnumMacro(DefaultViewDirection, AnatomicalPlane)
virtual void SendCreatedWorldGeometryUpdate()
Tell observers to re-read the currently selected 2D geometry.
virtual void SendCreatedWorldGeometry()
Send the created geometry to the connected observers (renderers)
virtual void SetViewDirectionToDefault()
itkGetEnumMacro(ViewDirection, AnatomicalPlane)
virtual void Update()
Do the actual creation and send it to the connected observers (renderers)
Message1< const Point3D & > SetCrosshairEvent
const char * GetViewDirectionAsString() const
void ReorientSlices(const Point3D &point, const Vector3D &normal)
Re-orients the slice stack. All slices will be oriented to the given normal vector....
virtual void SendSlice()
Send the currently selected slice to the connected observers (renderers)
void ExecuteOperation(Operation *operation) override
const PlaneGeometry * GetCurrentPlaneGeometry()
Returns the currently selected Plane in the current BaseGeometry (if existent).
itkSetEnumMacro(DefaultViewDirection, AnatomicalPlane)
Set the default view direction.
void SelectSliceByPoint(const Point3D &point)
Positions the SNC according to the specified point.
TimeGeometry::ConstPointer m_InputWorldTimeGeometry
virtual void Update(AnatomicalPlane viewDirection, bool top=true, bool frontside=true, bool rotated=false)
Extended version of Update, additionally allowing to specify the direction/orientation of the created...
void ReorientSlices(const Point3D &point, const Vector3D &axisVec0, const Vector3D &axisVec1)
Re-orients the slice stack so that all planes are oriented according to the given axis vectors....
#define mitkTimeGeometryEventMacro(classname, super)
Find image slices visible on a given plane.