Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
mitkGizmo.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 #include "mitkGizmo.h"
18 #include "mitkGizmoInteractor.h"
19 
20 // MITK includes
21 #include <mitkBaseRenderer.h>
24 #include <mitkRenderingManager.h>
26 
27 // VTK includes
28 #include <vtkAppendPolyData.h>
29 #include <vtkCellArray.h>
30 #include <vtkCharArray.h>
31 #include <vtkConeSource.h>
32 #include <vtkCylinderSource.h>
33 #include <vtkMath.h>
34 #include <vtkPointData.h>
35 #include <vtkPoints.h>
36 #include <vtkPolyDataNormals.h>
37 #include <vtkRenderWindow.h>
38 #include <vtkSphereSource.h>
39 #include <vtkTransformPolyDataFilter.h>
40 #include <vtkTubeFilter.h>
41 
42 // ITK includes
43 #include <itkCommand.h>
44 
45 // MicroServices
46 #include <usGetModuleContext.h>
47 
48 namespace
49 {
50  const char *PROPERTY_KEY_ORIGINAL_OBJECT_OPACITY = "gizmo.originalObjectOpacity";
51 }
52 
53 namespace mitk
54 {
56  class GizmoRemover
57  {
58  public:
59  GizmoRemover() : m_Storage(nullptr), m_GizmoNode(nullptr), m_ManipulatedNode(nullptr), m_StorageObserverTag(0) {}
66  void UpdateStorageObservation(mitk::DataStorage *storage,
67  mitk::DataNode *gizmo_node,
68  mitk::DataNode *manipulated_node)
69  {
70  if (m_Storage != nullptr)
71  {
72  m_Storage->RemoveNodeEvent.RemoveListener(
73  mitk::MessageDelegate1<GizmoRemover, const mitk::DataNode *>(this, &GizmoRemover::OnDataNodeHasBeenRemoved));
74  m_Storage->RemoveObserver(m_StorageObserverTag);
75  }
76 
77  m_Storage = storage;
78  m_GizmoNode = gizmo_node;
79  m_ManipulatedNode = manipulated_node;
80 
81  if (m_Storage != nullptr)
82  {
83  m_Storage->RemoveNodeEvent.AddListener(
84  mitk::MessageDelegate1<GizmoRemover, const mitk::DataNode *>(this, &GizmoRemover::OnDataNodeHasBeenRemoved));
85 
87  command->SetCallbackFunction(this, &mitk::GizmoRemover::OnDataStorageDeleted);
88  m_StorageObserverTag = m_Storage->AddObserver(itk::ModifiedEvent(), command);
89  }
90  }
91 
93  void OnDataStorageDeleted() { m_Storage = nullptr; }
95  void OnDataNodeHasBeenRemoved(const mitk::DataNode *node)
96  {
97  if (node == m_ManipulatedNode)
98  {
99  // m_Storage is still alive because it is the emitter
100  if (m_Storage->Exists(m_GizmoNode))
101  {
102  m_Storage->Remove(m_GizmoNode);
103  // normally, gizmo will be deleted here (unless somebody
104  // still holds a reference to it)
105  }
106  }
107  }
108 
110  ~GizmoRemover()
111  {
112  if (m_Storage)
113  {
114  m_Storage->RemoveNodeEvent.RemoveListener(
115  mitk::MessageDelegate1<GizmoRemover, const mitk::DataNode *>(this, &GizmoRemover::OnDataNodeHasBeenRemoved));
116  m_Storage->RemoveObserver(m_StorageObserverTag);
117  }
118  }
119 
120  private:
121  mitk::DataStorage *m_Storage;
122  mitk::DataNode *m_GizmoNode;
123  mitk::DataNode *m_ManipulatedNode;
124  unsigned long m_StorageObserverTag;
125  };
126 
127 } // namespace MITK
128 
130 {
131  auto typeCondition = TNodePredicateDataType<Gizmo>::New();
132  auto gizmoChildren = storage->GetDerivations(node, typeCondition);
133  return !gizmoChildren->empty();
134 }
135 
137 {
138  if (node == nullptr || storage == nullptr)
139  {
140  return false;
141  }
142 
143  auto typeCondition = TNodePredicateDataType<Gizmo>::New();
144  auto gizmoChildren = storage->GetDerivations(node, typeCondition);
145 
146  for (auto &gizmoChild : *gizmoChildren)
147  {
148  Gizmo *gizmo = dynamic_cast<Gizmo *>(gizmoChild->GetData());
149  if (gizmo)
150  {
151  storage->Remove(gizmoChild);
152  gizmo->m_GizmoRemover->UpdateStorageObservation(nullptr, nullptr, nullptr);
153  }
154  }
155 
156  //--------------------------------------------------------------
157  // Restore original opacity if we changed it
158  //--------------------------------------------------------------
159  float originalOpacity = 1.0;
160  if (node->GetFloatProperty(PROPERTY_KEY_ORIGINAL_OBJECT_OPACITY, originalOpacity))
161  {
162  node->SetOpacity(originalOpacity);
163  node->GetPropertyList()->DeleteProperty(PROPERTY_KEY_ORIGINAL_OBJECT_OPACITY);
164  }
165 
166  return !gizmoChildren->empty();
167 }
168 
170 {
171  assert(node);
172  if (node->GetData() == nullptr || node->GetData()->GetGeometry() == nullptr)
173  {
174  return nullptr;
175  }
176  //--------------------------------------------------------------
177  // Add visual gizmo that follows the node to be manipulated
178  //--------------------------------------------------------------
179 
180  auto gizmo = Gizmo::New();
181  auto gizmoNode = DataNode::New();
182  gizmoNode->SetName("Gizmo");
183  gizmoNode->SetData(gizmo);
184  gizmo->FollowGeometry(node->GetData()->GetGeometry());
185 
186  //--------------------------------------------------------------
187  // Add interaction to the gizmo
188  //--------------------------------------------------------------
189 
191  interactor->LoadStateMachine("Gizmo3DStates.xml", us::GetModuleContext()->GetModule());
192  interactor->SetEventConfig("Gizmo3DConfig.xml", us::ModuleRegistry::GetModule("MitkGizmo"));
193 
194  interactor->SetGizmoNode(gizmoNode);
195  interactor->SetManipulatedObjectNode(node);
196 
197  //--------------------------------------------------------------
198  // Note current opacity for later restore and lower it
199  //--------------------------------------------------------------
200 
201  float currentNodeOpacity = 1.0;
202  if (node->GetOpacity(currentNodeOpacity, nullptr))
203  {
204  if (currentNodeOpacity > 0.5f)
205  {
206  node->SetFloatProperty(PROPERTY_KEY_ORIGINAL_OBJECT_OPACITY, currentNodeOpacity);
207  node->SetOpacity(0.5f);
208  }
209  }
210 
211  if (storage)
212  {
213  storage->Add(gizmoNode, node);
214  gizmo->m_GizmoRemover->UpdateStorageObservation(storage, gizmoNode, node);
215  }
216 
217  return gizmoNode;
218 }
219 
221  : Surface(), m_AllowTranslation(true), m_AllowRotation(true), m_AllowScaling(true), m_GizmoRemover(new GizmoRemover())
222 {
223  m_Center.Fill(0);
224 
225  m_AxisX.Fill(0);
226  m_AxisX[0] = 1;
227  m_AxisY.Fill(0);
228  m_AxisY[1] = 1;
229  m_AxisZ.Fill(0);
230  m_AxisZ[2] = 1;
231 
232  m_Radius.Fill(1);
233 
235 }
236 
238 {
239  if (m_FollowedGeometry.IsNotNull())
240  {
241  m_FollowedGeometry->RemoveObserver(m_FollowerTag);
242  }
243 }
244 
246 {
247  /* bounding box around the unscaled bounding object */
248  ScalarType bounds[6] = {-m_Radius[0] * 1.2,
249  +m_Radius[0] * 1.2,
250  -m_Radius[1] * 1.2,
251  +m_Radius[1] * 1.2,
252  -m_Radius[2] * 1.2,
253  +m_Radius[2] * 1.2};
254  GetGeometry()->SetBounds(bounds);
255  GetTimeGeometry()->Update();
256 
257  SetVtkPolyData(BuildGizmo());
258 }
259 
260 namespace
261 {
262  void AssignScalarValueTo(vtkPolyData *polydata, char value)
263  {
264  vtkSmartPointer<vtkCharArray> pointData = vtkSmartPointer<vtkCharArray>::New();
265 
266  int numberOfPoints = polydata->GetNumberOfPoints();
267  pointData->SetNumberOfComponents(1);
268  pointData->SetNumberOfTuples(numberOfPoints);
269  pointData->FillComponent(0, value);
270  polydata->GetPointData()->SetScalars(pointData);
271  }
272 
273  vtkSmartPointer<vtkPolyData> BuildAxis(const mitk::Point3D &center,
274  const mitk::Vector3D &axis,
275  double halflength,
276  bool drawRing,
277  char vertexValueAxis,
278  char vertexValueRing,
279  char vertexValueScale)
280  {
281  // Define all sizes relative to absolute size (thus that the gizmo will appear
282  // in the same relative size for huge (size >> 1) and tiny (size << 1) objects).
283  // This means that the gizmo will appear very different when a scene contains _both_
284  // huge and tiny objects at the same time, but when the users zooms in on his
285  // object of interest, the gizmo will always have the same relative size.
286  const double shaftRadius = halflength * 0.02;
287  const double arrowHeight = shaftRadius * 6;
288  const int tubeSides = 15;
289 
290  // poly data appender to collect cones and tube that make up the axis
291  vtkSmartPointer<vtkAppendPolyData> axisSource = vtkSmartPointer<vtkAppendPolyData>::New();
292 
293  // build two cones at the end of axis
294  for (double sign = -1.0; sign < 3.0; sign += 2)
295  {
296  vtkSmartPointer<vtkConeSource> cone = vtkConeSource::New();
297  // arrow tips at 110% of radius
298  cone->SetCenter(center[0] + sign * axis[0] * (halflength * 1.1 + arrowHeight * 0.5),
299  center[1] + sign * axis[1] * (halflength * 1.1 + arrowHeight * 0.5),
300  center[2] + sign * axis[2] * (halflength * 1.1 + arrowHeight * 0.5));
301  cone->SetDirection(sign * axis[0], sign * axis[1], sign * axis[2]);
302  cone->SetRadius(shaftRadius * 3);
303  cone->SetHeight(arrowHeight);
304  cone->SetResolution(tubeSides);
305  cone->CappingOn();
306  cone->Update();
307  AssignScalarValueTo(cone->GetOutput(), vertexValueScale);
308  axisSource->AddInputData(cone->GetOutput());
309  }
310 
311  // build the axis itself (as a tube around the line defining the axis)
312  vtkSmartPointer<vtkPolyData> shaftSkeleton = vtkSmartPointer<vtkPolyData>::New();
313  vtkSmartPointer<vtkPoints> shaftPoints = vtkSmartPointer<vtkPoints>::New();
314  shaftPoints->InsertPoint(0, (center - axis * halflength * 1.1).GetDataPointer());
315  shaftPoints->InsertPoint(1, (center + axis * halflength * 1.1).GetDataPointer());
316  shaftSkeleton->SetPoints(shaftPoints);
317 
318  vtkSmartPointer<vtkCellArray> shaftLines = vtkSmartPointer<vtkCellArray>::New();
319  vtkIdType shaftLinePoints[] = {0, 1};
320  shaftLines->InsertNextCell(2, shaftLinePoints);
321  shaftSkeleton->SetLines(shaftLines);
322 
323  vtkSmartPointer<vtkTubeFilter> shaftSource = vtkSmartPointer<vtkTubeFilter>::New();
324  shaftSource->SetInputData(shaftSkeleton);
325  shaftSource->SetNumberOfSides(tubeSides);
326  shaftSource->SetVaryRadiusToVaryRadiusOff();
327  shaftSource->SetRadius(shaftRadius);
328  shaftSource->Update();
329  AssignScalarValueTo(shaftSource->GetOutput(), vertexValueAxis);
330 
331  axisSource->AddInputData(shaftSource->GetOutput());
332  axisSource->Update();
333 
334  vtkSmartPointer<vtkTubeFilter> ringSource; // used after if block, so declare it here
335  if (drawRing)
336  {
337  // build the ring orthogonal to the axis (as another tube)
338  vtkSmartPointer<vtkPolyData> ringSkeleton = vtkSmartPointer<vtkPolyData>::New();
339  vtkSmartPointer<vtkPoints> ringPoints = vtkSmartPointer<vtkPoints>::New();
340  ringPoints->SetDataTypeToDouble(); // just some decision (see cast below)
341  unsigned int numberOfRingPoints = 100;
342  vtkSmartPointer<vtkCellArray> ringLines = vtkSmartPointer<vtkCellArray>::New();
343  ringLines->InsertNextCell(numberOfRingPoints + 1);
344  mitk::Vector3D ringPointer;
345  for (unsigned int segment = 0; segment < numberOfRingPoints; ++segment)
346  {
347  ringPointer[0] = 0;
348  ringPointer[1] = std::cos((double)(segment) / (double)numberOfRingPoints * 2.0 * vtkMath::Pi());
349  ringPointer[2] = std::sin((double)(segment) / (double)numberOfRingPoints * 2.0 * vtkMath::Pi());
350 
351  ringPoints->InsertPoint(segment, (ringPointer * halflength).GetDataPointer());
352 
353  ringLines->InsertCellPoint(segment);
354  }
355  ringLines->InsertCellPoint(0);
356 
357  // transform ring points (copied from vtkConeSource)
358  vtkSmartPointer<vtkTransform> t = vtkSmartPointer<vtkTransform>::New();
359  t->Translate(center.GetDataPointer());
360  double vMag = vtkMath::Norm(axis.GetDataPointer());
361  if (axis[0] < 0.0)
362  {
363  // flip x -> -x to avoid instability
364  t->RotateWXYZ(180.0, (axis[0] - vMag) / 2.0, axis[1] / 2.0, axis[2] / 2.0);
365  t->RotateWXYZ(180.0, 0, 1, 0);
366  }
367  else
368  {
369  t->RotateWXYZ(180.0, (axis[0] + vMag) / 2.0, axis[1] / 2.0, axis[2] / 2.0);
370  }
371 
372  double thisPoint[3];
373  for (unsigned int i = 0; i < numberOfRingPoints; ++i)
374  {
375  ringPoints->GetPoint(i, thisPoint);
376  t->TransformPoint(thisPoint, thisPoint);
377  ringPoints->SetPoint(i, thisPoint);
378  }
379 
380  ringSkeleton->SetPoints(ringPoints);
381  ringSkeleton->SetLines(ringLines);
382 
384  ringSource->SetInputData(ringSkeleton);
385  ringSource->SetNumberOfSides(tubeSides);
386  ringSource->SetVaryRadiusToVaryRadiusOff();
387  ringSource->SetRadius(shaftRadius);
388  ringSource->Update();
389  AssignScalarValueTo(ringSource->GetOutput(), vertexValueRing);
390  }
391 
392  // assemble axis and ring
393  vtkSmartPointer<vtkAppendPolyData> appenderGlobal = vtkSmartPointer<vtkAppendPolyData>::New();
394  appenderGlobal->AddInputData(axisSource->GetOutput());
395  if (drawRing)
396  {
397  appenderGlobal->AddInputData(ringSource->GetOutput());
398  }
399  appenderGlobal->Update();
400 
401  // make everything shiny by adding normals
402  vtkSmartPointer<vtkPolyDataNormals> normalsSource = vtkSmartPointer<vtkPolyDataNormals>::New();
403  normalsSource->SetInputConnection(appenderGlobal->GetOutputPort());
404  normalsSource->ComputePointNormalsOn();
405  normalsSource->ComputeCellNormalsOff();
406  normalsSource->SplittingOn();
407  normalsSource->Update();
408 
409  vtkSmartPointer<vtkPolyData> result = normalsSource->GetOutput();
410  return result;
411  }
412 
413 } // unnamed namespace
414 
416 {
417  double longestAxis = std::max(m_Radius[0], m_Radius[1]);
418  longestAxis = std::max(longestAxis, m_Radius[2]);
419  return longestAxis;
420 }
421 
422 vtkSmartPointer<vtkPolyData> mitk::Gizmo::BuildGizmo()
423 {
424  double longestAxis = GetLongestRadius();
425 
426  vtkSmartPointer<vtkAppendPolyData> appender = vtkSmartPointer<vtkAppendPolyData>::New();
427  appender->AddInputData(BuildAxis(m_Center,
428  m_AxisX,
429  longestAxis,
430  m_AllowRotation,
431  m_AllowTranslation ? MoveAlongAxisX : NoHandle,
432  m_AllowRotation ? RotateAroundAxisX : NoHandle,
433  m_AllowScaling ? ScaleX : NoHandle));
434  appender->AddInputData(BuildAxis(m_Center,
435  m_AxisY,
436  longestAxis,
437  m_AllowRotation,
438  m_AllowTranslation ? MoveAlongAxisY : NoHandle,
439  m_AllowRotation ? RotateAroundAxisY : NoHandle,
440  m_AllowScaling ? ScaleY : NoHandle));
441  appender->AddInputData(BuildAxis(m_Center,
442  m_AxisZ,
443  longestAxis,
444  m_AllowRotation,
445  m_AllowTranslation ? MoveAlongAxisZ : NoHandle,
446  m_AllowRotation ? RotateAroundAxisZ : NoHandle,
447  m_AllowScaling ? ScaleZ : NoHandle));
448 
449  auto sphereSource = vtkSmartPointer<vtkSphereSource>::New();
450  sphereSource->SetCenter(m_Center[0], m_Center[1], m_Center[2]);
451  sphereSource->SetRadius(longestAxis * 0.06);
452  sphereSource->Update();
453  AssignScalarValueTo(sphereSource->GetOutput(), MoveFreely);
454 
455  appender->AddInputData(sphereSource->GetOutput());
456 
457  appender->Update();
458  return appender->GetOutput();
459 }
460 
462 {
463  auto observer = itk::SimpleMemberCommand<Gizmo>::New();
464  observer->SetCallbackFunction(this, &Gizmo::OnFollowedGeometryModified);
465 
466  if (m_FollowedGeometry.IsNotNull())
467  {
468  m_FollowedGeometry->RemoveObserver(m_FollowerTag);
469  }
470 
471  m_FollowedGeometry = geom;
472  m_FollowerTag = m_FollowedGeometry->AddObserver(itk::ModifiedEvent(), observer);
473 
474  // initial adjustment
475  OnFollowedGeometryModified();
476 }
477 
479 {
480  m_Center = m_FollowedGeometry->GetCenter();
481 
482  m_AxisX = m_FollowedGeometry->GetAxisVector(0);
483  m_AxisY = m_FollowedGeometry->GetAxisVector(1);
484  m_AxisZ = m_FollowedGeometry->GetAxisVector(2);
485 
486  m_AxisX.Normalize();
487  m_AxisY.Normalize();
488  m_AxisZ.Normalize();
489 
490  for (int dim = 0; dim < 3; ++dim)
491  {
492  m_Radius[dim] = 0.5 * m_FollowedGeometry->GetExtentInMM(dim);
493  }
494 
495  UpdateRepresentation();
496 }
497 
499 {
500 #define CheckHandleType(type) \
501  if (static_cast<int>(value) == static_cast<int>(type)) \
502  return type;
503 
504  CheckHandleType(MoveFreely);
505  CheckHandleType(MoveAlongAxisX);
506  CheckHandleType(MoveAlongAxisY);
507  CheckHandleType(MoveAlongAxisZ);
508  CheckHandleType(RotateAroundAxisX);
509  CheckHandleType(RotateAroundAxisY);
510  CheckHandleType(RotateAroundAxisZ);
511  CheckHandleType(ScaleX);
512  CheckHandleType(ScaleY);
513  CheckHandleType(ScaleZ);
514  return NoHandle;
515 #undef CheckHandleType
516 }
517 
519 {
520  assert(GetVtkPolyData());
521  assert(GetVtkPolyData()->GetPointData());
522  assert(GetVtkPolyData()->GetPointData()->GetScalars());
523  double dataValue = GetVtkPolyData()->GetPointData()->GetScalars()->GetTuple1(id);
524  return GetHandleFromPointDataValue(dataValue);
525 }
526 
528 {
529 #define CheckHandleType(candidateType) \
530  if (type == candidateType) \
531  return std::string(#candidateType);
532 
533  CheckHandleType(MoveFreely);
534  CheckHandleType(MoveAlongAxisX);
535  CheckHandleType(MoveAlongAxisY);
536  CheckHandleType(MoveAlongAxisZ);
537  CheckHandleType(RotateAroundAxisX);
538  CheckHandleType(RotateAroundAxisY);
539  CheckHandleType(RotateAroundAxisZ);
540  CheckHandleType(ScaleX);
541  CheckHandleType(ScaleY);
542  CheckHandleType(ScaleZ);
543  CheckHandleType(NoHandle);
544  return "InvalidHandleType";
545 #undef CheckHandleType
546 }
virtual ~Gizmo()
Definition: mitkGizmo.cpp:237
virtual void Add(mitk::DataNode *node, const mitk::DataStorage::SetOfObjects *parents=nullptr)=0
Adds a DataNode containing a data object to its internal storage.
Class for storing surfaces (vtkPolyData).
Definition: mitkSurface.h:32
mitk::PropertyList * GetPropertyList(const mitk::BaseRenderer *renderer=nullptr) const
Get the PropertyList of the renderer. If renderer is NULL, the BaseRenderer-independent PropertyList ...
Data management class that handles 'was created by' relations.
itk::SmartPointer< Self > Pointer
HandleType GetHandleFromPointID(vtkIdType id)
Definition: mitkGizmo.cpp:518
virtual SetOfObjects::ConstPointer GetDerivations(const mitk::DataNode *node, const NodePredicateBase *condition=nullptr, bool onlyDirectDerivations=true) const =0
returns a set of derived objects for a given node.
double ScalarType
static DataNode::Pointer AddGizmoToNode(DataNode *node, DataStorage *storage)
Definition: mitkGizmo.cpp:169
static Module * GetModule(long id)
DataCollection - Class to facilitate loading/accessing structured data.
BaseData * GetData() const
Get the data object (instance of BaseData, e.g., an Image) managed by this DataNode.
static Pointer New()
#define CheckHandleType(type)
static bool HasGizmoAttached(mitk::DataNode *node, DataStorage *storage)
Definition: mitkGizmo.cpp:129
bool DeleteProperty(const std::string &propertyKey)
Remove a property from the list/map.
void FollowGeometry(BaseGeometry *geom)
Definition: mitkGizmo.cpp:461
HandleType
Names for the different parts of the gizmo.
Definition: mitkGizmo.h:65
void SetFloatProperty(const char *propertyKey, float floatValue, const mitk::BaseRenderer *renderer=nullptr)
Convenience method for setting float properties (instances of FloatProperty)
bool GetOpacity(float &opacity, const mitk::BaseRenderer *renderer, const char *propertyKey="opacity") const
Convenience access method for opacity properties (instances of FloatProperty)
void SetOpacity(float opacity, const mitk::BaseRenderer *renderer=nullptr, const char *propertyKey="opacity")
Convenience method for setting opacity properties (instances of FloatProperty)
static Pointer New()
bool GetFloatProperty(const char *propertyKey, float &floatValue, const mitk::BaseRenderer *renderer=nullptr) const
Convenience access method for float properties (instances of FloatProperty)
double GetLongestRadius() const
Return the longest of the three axes.
Definition: mitkGizmo.cpp:415
static T max(T x, T y)
Definition: svm.cpp:70
static Pointer New()
void UpdateRepresentation()
Updates the representing surface object after changes to center, axes, or radius. ...
Definition: mitkGizmo.cpp:245
mitk::Gizmo::HandleType GetHandleFromPointDataValue(double value)
Definition: mitkGizmo.cpp:498
virtual void Remove(const mitk::DataNode *node)=0
Removes node from the DataStorage.
mitk::BaseGeometry * GetGeometry(int t=0) const
Return the geometry, which is a TimeGeometry, of the data as non-const pointer.
Definition: mitkBaseData.h:129
vtkSmartPointer< vtkPolyData > BuildGizmo()
Creates a vtkPolyData representing the parameters defining the gizmo.
Definition: mitkGizmo.cpp:422
static ModuleContext * GetModuleContext()
Returns the module context of the calling module.
void OnFollowedGeometryModified()
The ITK callback to receive modified events of the followed geometry.
Definition: mitkGizmo.cpp:478
static std::string HandleTypeToString(HandleType type)
Conversion for any kind of logging/debug/... purposes.
Definition: mitkGizmo.cpp:527
BaseGeometry Describes the geometry of a data object.
Class for nodes of the DataTree.
Definition: mitkDataNode.h:66
static bool RemoveGizmoFromNode(DataNode *node, DataStorage *storage)
Definition: mitkGizmo.cpp:136
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.