Slicer  5.0
Slicer is a multi-platform, free and open source software package for visualization and medical image computing
vtkSlicerMarkupsWidget.h
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Copyright (c) ProxSim ltd., Kwun Tong, Hong Kong. All Rights Reserved.
4 
5  See COPYRIGHT.txt
6  or http://www.slicer.org/copyright/copyright.txt for details.
7 
8  Unless required by applicable law or agreed to in writing, software
9  distributed under the License is distributed on an "AS IS" BASIS,
10  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11  See the License for the specific language governing permissions and
12  limitations under the License.
13 
14  This file was originally developed by Davide Punzo, punzodavide@hotmail.it,
15  and development was supported by ProxSim ltd.
16 
17 =========================================================================*/
18 
28 #ifndef vtkSlicerMarkupsWidget_h
29 #define vtkSlicerMarkupsWidget_h
30 
31 #include "vtkSlicerMarkupsModuleVTKWidgetsExport.h"
32 #include "vtkMRMLAbstractWidget.h"
33 #include "vtkWidgetCallbackMapper.h"
34 
35 #include "vtkMRMLMarkupsNode.h"
36 
41 class vtkIdList;
42 class vtkPolyData;
44 
45 class VTK_SLICER_MARKUPS_MODULE_VTKWIDGETS_EXPORT vtkSlicerMarkupsWidget : public vtkMRMLAbstractWidget
46 {
47 public:
50  void PrintSelf(ostream& os, vtkIndent indent) override;
51 
53  virtual void CreateDefaultRepresentation(vtkMRMLMarkupsDisplayNode* markupsDisplayNode, vtkMRMLAbstractViewNode* viewNode, vtkRenderer* renderer) = 0;
54 
56  virtual vtkSlicerMarkupsWidget* CreateInstance() const = 0;
57 
59  enum
60  {
61  WidgetStateDefine = WidgetStateUser, // click in empty area will place a new point
62  WidgetStateTranslateControlPoint, // translating the active point by mouse move
63  WidgetStateOnTranslationHandle, // hovering over a translation interaction handle
64  WidgetStateOnRotationHandle, // hovering over a rotation interaction handle
65  WidgetStateOnScaleHandle, // hovering over a scale interaction handle
66  WidgetStateMarkups_Last
67  };
68 
70  enum
71  {
72  WidgetEventControlPointPlace = WidgetEventUser,
81  WidgetEventReserved, // this events is only to prevent other widgets from processing an event
82  WidgetEventMarkups_Last
83  };
84 
85  // Returns true if one of the markup points are just being previewed and not placed yet.
86  bool IsPointPreviewed();
87 
89  void UpdatePreviewPointIndex(vtkMRMLInteractionEventData* eventData);
90 
92  void UpdatePreviewPoint(vtkMRMLInteractionEventData* eventData, const char* associatedNodeID, int positionStatus);
93 
96  bool RemovePreviewPoint();
97 
98  // Places a new markup point.
99  // Reuses current preview point, if possible.
100  // Returns true if the event is processed.
101  virtual bool PlacePoint(vtkMRMLInteractionEventData* eventData);
102 
104  virtual int AddPointFromWorldCoordinate(const double worldCoordinates[3]);
105 
108  virtual int AddNodeOnWidget(const int displayPos[2]);
109 
111  bool CanProcessInteractionEvent(vtkMRMLInteractionEventData* eventData, double &distance2) override;
112 
114  bool ProcessInteractionEvent(vtkMRMLInteractionEventData* eventData) override;
115 
117  void Leave(vtkMRMLInteractionEventData* eventData) override;
118 
119  // Allows the widget to request interactive mode (faster updates)
120  bool GetInteractive() override;
121  // Allows the widget to request a cursor shape
122  int GetMouseCursor() override;
123 
124  vtkMRMLMarkupsNode* GetMarkupsNode();
125  vtkMRMLMarkupsDisplayNode* GetMarkupsDisplayNode();
126  int GetActiveControlPoint();
127 
128  vtkSlicerMarkupsWidgetRepresentation* GetMarkupsRepresentation();
129 
130  int GetActiveComponentType();
131  int GetActiveComponentIndex();
132 
133  vtkMRMLSelectionNode* selectionNode();
134 
135 protected:
137  ~vtkSlicerMarkupsWidget() override;
138 
139  void StartWidgetInteraction(vtkMRMLInteractionEventData* eventData);
140  void EndWidgetInteraction();
141 
142  virtual void TranslatePoint(double eventPos[2], bool snapToSlice = false);
143  virtual void TranslateWidget(double eventPos[2]);
144  virtual void ScaleWidget(double eventPos[2]);
145  virtual void RotateWidget(double eventPos[2]);
146 
147  bool IsAnyControlPointLocked();
148 
149  // Get accurate world position.
150  // World position that comes in the event data may be inaccurate, this method computes a more reliable position.
151  // Returns true on success.
152  // refWorldPos is an optional reference position: if point distance from camera cannot be determined then
153  // depth of this reference position is used.
154  bool ConvertDisplayPositionToWorld(const int displayPos[2], double worldPos[3], double worldOrientationMatrix[9],
155  double* refWorldPos = nullptr);
156 
160 
161  // Callback interface to capture events when
162  // placing the widget.
163  // Return true if the event is processed.
164  virtual bool ProcessMouseMove(vtkMRMLInteractionEventData* eventData);
165  virtual bool ProcessWidgetMenu(vtkMRMLInteractionEventData* eventData);
166  virtual bool ProcessWidgetAction(vtkMRMLInteractionEventData* eventData);
167  virtual bool ProcessWidgetStopPlace(vtkMRMLInteractionEventData* eventData);
168  virtual bool ProcessControlPointSnapToSlice(vtkMRMLInteractionEventData* eventData);
169  virtual bool ProcessControlPointDelete(vtkMRMLInteractionEventData* eventData);
170  virtual bool ProcessControlPointInsert(vtkMRMLInteractionEventData* eventData);
171  virtual bool ProcessControlPointMoveStart(vtkMRMLInteractionEventData* eventData);
172  virtual bool ProcessWidgetTranslateStart(vtkMRMLInteractionEventData* eventData);
173  virtual bool ProcessWidgetRotateStart(vtkMRMLInteractionEventData* eventData);
174  virtual bool ProcessWidgetScaleStart(vtkMRMLInteractionEventData* eventData);
175  virtual bool ProcessEndMouseDrag(vtkMRMLInteractionEventData* eventData);
176  virtual bool ProcessWidgetReset(vtkMRMLInteractionEventData* eventData);
177  virtual bool ProcessWidgetJumpCursor(vtkMRMLInteractionEventData* eventData);
178 
179  // Get the closest point on the line defined by the interaction handle axis.
180  // Input coordinates are in display coordinates, while output are in world coordinates.
181  virtual bool GetClosestPointOnInteractionAxis(int type, int index, const double inputDisplay[2], double outputIntersectionWorld[3]);
182 
183  // Get the closest point on the plane defined using the interaction handle axis as the plane normal.
184  // Input coordinates are in display coordinates, while output are in world coordinates
185  virtual bool GetIntersectionOnAxisPlane(int type, int index, const double inputDisplay[2], double outputIntersectionWorld[3]);
186 
187  // Variables for translate/rotate/scale
188  double LastEventPosition[2];
189  double StartEventOffsetPosition[2];
190 
191 private:
193  void operator=(const vtkSlicerMarkupsWidget&) = delete;
194 };
195 
196 //----------------------------------------------------------------------
197 // CREATE INSTANCE MACRO
198 
199 #ifdef VTK_HAS_INITIALIZE_OBJECT_BASE
200 #define vtkSlicerMarkupsWidgetCreateInstanceMacro(type) \
201 vtkSlicerMarkupsWidget* CreateInstance() const override\
202 { \
203  vtkObject* ret = vtkObjectFactory::CreateInstance(#type); \
204  if(ret) \
205  { \
206  return static_cast<type *>(ret); \
207  } \
208  type* result = new type; \
209  result->InitializeObjectBase(); \
210  return result; \
211 }
212 #else
213 #define vtkSlicerMarkupsWidgetCreateInstanceMacro(type) \
214 vtkSlicerMarkupsWidget* CreateInstance() const override\
215 { \
216  vtkObject* ret = vtkObjectFactory::CreateInstance(#type); \
217  if(ret) \
218  { \
219  return static_cast<type *>(ret); \
220  } \
221  return new type; \
222 }
223 #endif
224 
225 #endif
virtual bool CanProcessInteractionEvent(vtkMRMLInteractionEventData *eventData, double &distance2)
virtual bool GetInteractive()
Abstract MRML node to represent a view. The class holds the properties common to any view type (3D...
Process interaction events to update state of markup widget nodes.
this is a starting index that can be used for widget-specific events
virtual bool ProcessInteractionEvent(vtkMRMLInteractionEventData *eventData)
virtual void Leave(vtkMRMLInteractionEventData *eventData)
Called when the the widget loses the focus.
void PrintSelf(ostream &os, vtkIndent indent) override
virtual int GetMouseCursor()
Process interaction events to update state of MRML widget nodes.
MRML node for storing information about the active nodes in the scene.
this is a starting index that can be used for widget-specific states