Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkPaintbrushTool.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 "mitkPaintbrushTool.h"
18 
19 #include "ipSegmentation.h"
21 #include "mitkBaseRenderer.h"
22 #include "mitkImageDataItem.h"
24 #include "mitkToolManager.h"
25 
26 #include "mitkContourModelUtils.h"
27 #include "mitkLabelSetImage.h"
29 
30 #define ROUND(a) ((a) > 0 ? (int)((a) + 0.5) : -(int)(0.5 - (a)))
31 
33 
34 mitk::PaintbrushTool::PaintbrushTool(int paintingPixelValue)
35  : FeedbackContourTool("PressMoveReleaseWithCTRLInversionAllMouseMoves"),
36  m_PaintingPixelValue(paintingPixelValue),
37  m_LastContourSize(0) // other than initial mitk::PaintbrushTool::m_Size (around l. 28)
38 {
40  m_MasterContour->Initialize();
41  m_CurrentPlane = nullptr;
42 
44  m_WorkingNode->SetProperty("levelwindow", mitk::LevelWindowProperty::New(mitk::LevelWindow(0, 1)));
45  m_WorkingNode->SetProperty("binary", mitk::BoolProperty::New(true));
46 }
47 
49 {
50 }
51 
53 {
54  CONNECT_FUNCTION("PrimaryButtonPressed", OnMousePressed);
55  CONNECT_FUNCTION("Move", OnPrimaryButtonPressedMoved);
56  CONNECT_FUNCTION("MouseMove", OnMouseMoved);
57  CONNECT_FUNCTION("Release", OnMouseReleased);
58  CONNECT_FUNCTION("InvertLogic", OnInvertLogic);
59 }
60 
62 {
63  Superclass::Activated();
64 
66  SizeChanged.Send(m_Size);
67  m_ToolManager->WorkingDataChanged +=
69 }
70 
72 {
74  if (m_ToolManager->GetDataStorage()->Exists(m_WorkingNode))
75  m_ToolManager->GetDataStorage()->Remove(m_WorkingNode);
76  m_WorkingSlice = nullptr;
77  m_CurrentPlane = nullptr;
78  m_ToolManager->WorkingDataChanged -=
80 
81  Superclass::Deactivated();
82 }
83 
85 {
86  m_Size = value;
87 }
88 
90 {
91  p[0] -= 0.5;
92  p[1] += 0.5;
93  return p;
94 }
95 
97 {
98  // MITK_INFO<<"Update...";
99  // examine stateEvent and create a contour that matches the pixel mask that we are going to draw
100  // mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
101  // const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
102  if (!positionEvent)
103  return;
104 
105  // Get Spacing of current Slice
106  // mitk::Vector3D vSpacing = m_WorkingSlice->GetSlicedGeometry()->GetPlaneGeometry(0)->GetSpacing();
107 
108  //
109  // Draw a contour in Square according to selected brush size
110  //
111  int radius = (m_Size) / 2;
112  float fradius = static_cast<float>(m_Size) / 2.0f;
113 
114  ContourModel::Pointer contourInImageIndexCoordinates = ContourModel::New();
115 
116  // estimate center point of the brush ( relative to the pixel the mouse points on )
117  // -- left upper corner for even sizes,
118  // -- midpoint for uneven sizes
119  mitk::Point2D centerCorrection;
120  centerCorrection.Fill(0);
121 
122  // even --> correction of [+0.5, +0.5]
123  bool evenSize = ((m_Size % 2) == 0);
124  if (evenSize)
125  {
126  centerCorrection[0] += 0.5;
127  centerCorrection[1] += 0.5;
128  }
129 
130  // we will compute the control points for the upper left quarter part of a circle contour
131  std::vector<mitk::Point2D> quarterCycleUpperRight;
132  std::vector<mitk::Point2D> quarterCycleLowerRight;
133  std::vector<mitk::Point2D> quarterCycleLowerLeft;
134  std::vector<mitk::Point2D> quarterCycleUpperLeft;
135 
136  mitk::Point2D curPoint;
137  bool curPointIsInside = true;
138  curPoint[0] = 0;
139  curPoint[1] = radius;
140  quarterCycleUpperRight.push_back(upperLeft(curPoint));
141 
142  // to estimate if a pixel is inside the circle, we need to compare against the 'outer radius'
143  // i.e. the distance from the midpoint [0,0] to the border of the pixel [0,radius]
144  // const float outer_radius = static_cast<float>(radius) + 0.5;
145 
146  while (curPoint[1] > 0)
147  {
148  // Move right until pixel is outside circle
149  float curPointX_squared = 0.0f;
150  float curPointY_squared = (curPoint[1] - centerCorrection[1]) * (curPoint[1] - centerCorrection[1]);
151  while (curPointIsInside)
152  {
153  // increment posX and chec
154  curPoint[0]++;
155  curPointX_squared = (curPoint[0] - centerCorrection[0]) * (curPoint[0] - centerCorrection[0]);
156  const float len = sqrt(curPointX_squared + curPointY_squared);
157  if (len > fradius)
158  {
159  // found first Pixel in this horizontal line, that is outside the circle
160  curPointIsInside = false;
161  }
162  }
163  quarterCycleUpperRight.push_back(upperLeft(curPoint));
164 
165  // Move down until pixel is inside circle
166  while (!curPointIsInside)
167  {
168  // increment posX and chec
169  curPoint[1]--;
170  curPointY_squared = (curPoint[1] - centerCorrection[1]) * (curPoint[1] - centerCorrection[1]);
171  const float len = sqrt(curPointX_squared + curPointY_squared);
172  if (len <= fradius)
173  {
174  // found first Pixel in this horizontal line, that is outside the circle
175  curPointIsInside = true;
176  quarterCycleUpperRight.push_back(upperLeft(curPoint));
177  }
178 
179  // Quarter cycle is full, when curPoint y position is 0
180  if (curPoint[1] <= 0)
181  break;
182  }
183  }
184 
185  // QuarterCycle is full! Now copy quarter cycle to other quarters.
186 
187  if (!evenSize)
188  {
189  std::vector<mitk::Point2D>::const_iterator it = quarterCycleUpperRight.begin();
190  while (it != quarterCycleUpperRight.end())
191  {
192  mitk::Point2D p;
193  p = *it;
194 
195  // the contour points in the lower right corner have same position but with negative y values
196  p[1] *= -1;
197  quarterCycleLowerRight.push_back(p);
198 
199  // the contour points in the lower left corner have same position
200  // but with both x,y negative
201  p[0] *= -1;
202  quarterCycleLowerLeft.push_back(p);
203 
204  // the contour points in the upper left corner have same position
205  // but with x negative
206  p[1] *= -1;
207  quarterCycleUpperLeft.push_back(p);
208 
209  it++;
210  }
211  }
212  else
213  {
214  std::vector<mitk::Point2D>::const_iterator it = quarterCycleUpperRight.begin();
215  while (it != quarterCycleUpperRight.end())
216  {
217  mitk::Point2D p, q;
218  p = *it;
219 
220  q = p;
221  // the contour points in the lower right corner have same position but with negative y values
222  q[1] *= -1;
223  // correct for moved offset if size even = the midpoint is not the midpoint of the current pixel
224  // but its upper rigt corner
225  q[1] += 1;
226  quarterCycleLowerRight.push_back(q);
227 
228  q = p;
229  // the contour points in the lower left corner have same position
230  // but with both x,y negative
231  q[1] = -1.0f * q[1] + 1;
232  q[0] = -1.0f * q[0] + 1;
233  quarterCycleLowerLeft.push_back(q);
234 
235  // the contour points in the upper left corner have same position
236  // but with x negative
237  q = p;
238  q[0] *= -1;
239  q[0] += 1;
240  quarterCycleUpperLeft.push_back(q);
241 
242  it++;
243  }
244  }
245 
246  // fill contour with poins in right ordering, starting with the upperRight block
247  mitk::Point3D tempPoint;
248  for (unsigned int i = 0; i < quarterCycleUpperRight.size(); i++)
249  {
250  tempPoint[0] = quarterCycleUpperRight[i][0];
251  tempPoint[1] = quarterCycleUpperRight[i][1];
252  tempPoint[2] = 0;
253  contourInImageIndexCoordinates->AddVertex(tempPoint);
254  }
255  // the lower right has to be parsed in reverse order
256  for (int i = quarterCycleLowerRight.size() - 1; i >= 0; i--)
257  {
258  tempPoint[0] = quarterCycleLowerRight[i][0];
259  tempPoint[1] = quarterCycleLowerRight[i][1];
260  tempPoint[2] = 0;
261  contourInImageIndexCoordinates->AddVertex(tempPoint);
262  }
263  for (unsigned int i = 0; i < quarterCycleLowerLeft.size(); i++)
264  {
265  tempPoint[0] = quarterCycleLowerLeft[i][0];
266  tempPoint[1] = quarterCycleLowerLeft[i][1];
267  tempPoint[2] = 0;
268  contourInImageIndexCoordinates->AddVertex(tempPoint);
269  }
270  // the upper left also has to be parsed in reverse order
271  for (int i = quarterCycleUpperLeft.size() - 1; i >= 0; i--)
272  {
273  tempPoint[0] = quarterCycleUpperLeft[i][0];
274  tempPoint[1] = quarterCycleUpperLeft[i][1];
275  tempPoint[2] = 0;
276  contourInImageIndexCoordinates->AddVertex(tempPoint);
277  }
278 
279  m_MasterContour = contourInImageIndexCoordinates;
280 }
281 
286 {
287  if (m_WorkingSlice.IsNull())
288  return;
289 
290  mitk::InteractionPositionEvent *positionEvent = dynamic_cast<mitk::InteractionPositionEvent *>(interactionEvent);
291  if (!positionEvent)
292  return;
293 
294  m_WorkingSlice->GetGeometry()->WorldToIndex(positionEvent->GetPositionInWorld(), m_LastPosition);
295 
296  // create new working node
297  // a fresh node is needed to only display the actual drawing process for
298  // the undo function
299  if (m_ToolManager->GetDataStorage()->Exists(m_WorkingNode))
300  m_ToolManager->GetDataStorage()->Remove(m_WorkingNode);
301  m_WorkingSlice = nullptr;
302  m_CurrentPlane = nullptr;
303 
304  m_WorkingNode = DataNode::New();
305  m_WorkingNode->SetProperty("levelwindow", mitk::LevelWindowProperty::New(mitk::LevelWindow(0, 1)));
306  m_WorkingNode->SetProperty("binary", mitk::BoolProperty::New(true));
307 
308  this->m_WorkingNode->SetVisibility(true);
309 
310  m_LastEventSender = positionEvent->GetSender();
311  m_LastEventSlice = m_LastEventSender->GetSlice();
312 
313  m_MasterContour->SetClosed(true);
314  this->MouseMoved(interactionEvent, true);
315 }
316 
318 {
319  MouseMoved(interactionEvent, false);
320 }
321 
323 {
324  MouseMoved(interactionEvent, true);
325 }
326 
330 void mitk::PaintbrushTool::MouseMoved(mitk::InteractionEvent *interactionEvent, bool leftMouseButtonPressed)
331 {
332  mitk::InteractionPositionEvent *positionEvent = dynamic_cast<mitk::InteractionPositionEvent *>(interactionEvent);
333 
334  CheckIfCurrentSliceHasChanged(positionEvent);
335 
336  if (m_LastContourSize != m_Size)
337  {
338  UpdateContour(positionEvent);
339  m_LastContourSize = m_Size;
340  }
341 
342  Point3D worldCoordinates = positionEvent->GetPositionInWorld();
343  Point3D indexCoordinates;
344 
345  m_WorkingSlice->GetGeometry()->WorldToIndex(worldCoordinates, indexCoordinates);
346 
347  MITK_DEBUG << "Mouse at W " << worldCoordinates << std::endl;
348  MITK_DEBUG << "Mouse at I " << indexCoordinates << std::endl;
349 
350  // round to nearest voxel center (abort if this hasn't changed)
351  if (m_Size % 2 == 0) // even
352  {
353  indexCoordinates[0] = ROUND(indexCoordinates[0]); // /*+ 0.5*/) + 0.5;
354  indexCoordinates[1] = ROUND(indexCoordinates[1]); // /*+ 0.5*/ ) + 0.5;
355  }
356  else // odd
357  {
358  indexCoordinates[0] = ROUND(indexCoordinates[0]);
359  indexCoordinates[1] = ROUND(indexCoordinates[1]);
360  }
361 
362  static Point3D lastPos; // uninitialized: if somebody finds out how this can be initialized in a one-liner, tell me
363  if (fabs(indexCoordinates[0] - lastPos[0]) > mitk::eps || fabs(indexCoordinates[1] - lastPos[1]) > mitk::eps ||
364  fabs(indexCoordinates[2] - lastPos[2]) > mitk::eps || leftMouseButtonPressed)
365  {
366  lastPos = indexCoordinates;
367  }
368  else
369  {
370  MITK_DEBUG << "." << std::flush;
371  return;
372  }
373 
374  MITK_DEBUG << "Mouse at C " << indexCoordinates;
375 
376  int timestep = positionEvent->GetSender()->GetTimeStep();
377 
379  contour->Expand(timestep + 1);
380  contour->SetClosed(true, timestep);
381 
382  ContourModel::VertexIterator it = m_MasterContour->Begin();
383  ContourModel::VertexIterator end = m_MasterContour->End();
384 
385  while (it != end)
386  {
387  Point3D point = (*it)->Coordinates;
388  point[0] += indexCoordinates[0];
389  point[1] += indexCoordinates[1];
390 
391  contour->AddVertex(point, timestep);
392  it++;
393  }
394 
395  if (leftMouseButtonPressed)
396  {
397  const double dist = indexCoordinates.EuclideanDistanceTo(m_LastPosition);
398  const double radius = static_cast<double>(m_Size) / 2.0;
399 
400  DataNode *workingNode(m_ToolManager->GetWorkingData(0));
401  Image::Pointer image = dynamic_cast<Image *>(workingNode->GetData());
402  LabelSetImage *labelImage = dynamic_cast<LabelSetImage *>(image.GetPointer());
403 
404  int activeColor = 1;
405  if (labelImage)
406  {
407  activeColor = labelImage->GetActiveLabel(labelImage->GetActiveLayer())->GetValue();
408  }
409 
410  // m_PaintingPixelValue only decides whether to paint or erase
412  contour, timestep, m_WorkingSlice, image, m_PaintingPixelValue * activeColor);
413 
414  m_WorkingNode->SetData(m_WorkingSlice);
415  m_WorkingNode->Modified();
416 
417  // if points are >= radius away draw rectangle to fill empty holes
418  // in between the 2 points
419  if (dist > radius)
420  {
421  const mitk::Point3D &currentPos = indexCoordinates;
422  mitk::Point3D direction;
423  mitk::Point3D vertex;
424  mitk::Point3D normal;
425 
426  direction[0] = indexCoordinates[0] - m_LastPosition[0];
427  direction[1] = indexCoordinates[1] - m_LastPosition[1];
428  direction[2] = indexCoordinates[2] - m_LastPosition[2];
429 
430  direction[0] = direction.GetVnlVector().normalize()[0];
431  direction[1] = direction.GetVnlVector().normalize()[1];
432  direction[2] = direction.GetVnlVector().normalize()[2];
433 
434  // 90 degrees rotation of direction
435  normal[0] = -1.0 * direction[1];
436  normal[1] = direction[0];
437 
438  contour->Clear();
439 
440  // upper left corner
441  vertex[0] = m_LastPosition[0] + (normal[0] * radius);
442  vertex[1] = m_LastPosition[1] + (normal[1] * radius);
443 
444  contour->AddVertex(vertex);
445 
446  // upper right corner
447  vertex[0] = currentPos[0] + (normal[0] * radius);
448  vertex[1] = currentPos[1] + (normal[1] * radius);
449 
450  contour->AddVertex(vertex);
451 
452  // lower right corner
453  vertex[0] = currentPos[0] - (normal[0] * radius);
454  vertex[1] = currentPos[1] - (normal[1] * radius);
455 
456  contour->AddVertex(vertex);
457 
458  // lower left corner
459  vertex[0] = m_LastPosition[0] - (normal[0] * radius);
460  vertex[1] = m_LastPosition[1] - (normal[1] * radius);
461 
462  contour->AddVertex(vertex);
463 
464  mitk::ContourModelUtils::FillContourInSlice(contour, timestep, m_WorkingSlice, image, m_PaintingPixelValue * activeColor);
465  m_WorkingNode->SetData(m_WorkingSlice);
466  m_WorkingNode->Modified();
467  }
468  }
469  else
470  {
471  // switched from different renderwindow
472  // no activate hover highlighting. Otherwise undo / redo wont work
473  this->m_WorkingNode->SetVisibility(false);
474  }
475 
476  m_LastPosition = indexCoordinates;
477 
478  // visualize contour
480  displayContour->Clear();
481 
483  FeedbackContourTool::BackProjectContourFrom2DSlice(m_WorkingSlice->GetGeometry(), /*displayContour*/ contour);
484 
485  // copy transformed contour into display contour
486  it = tmp->Begin();
487  end = tmp->End();
488 
489  while (it != end)
490  {
491  Point3D point = (*it)->Coordinates;
492 
493  displayContour->AddVertex(point, timestep);
494  it++;
495  }
496 
497  m_FeedbackContourNode->GetData()->Modified();
498 
499  assert(positionEvent->GetSender()->GetRenderWindow());
500 
502 }
503 
505 {
506  // When mouse is released write segmentationresult back into image
507  mitk::InteractionPositionEvent *positionEvent = dynamic_cast<mitk::InteractionPositionEvent *>(interactionEvent);
508  if (!positionEvent)
509  return;
510 
511  this->WriteBackSegmentationResult(positionEvent, m_WorkingSlice->Clone());
512 
513  // deactivate visibility of helper node
514  m_WorkingNode->SetVisibility(false);
515 
517 }
518 
523 {
524  // Inversion only for 0 and 1 as painting values
525  if (m_PaintingPixelValue == 1)
526  {
527  m_PaintingPixelValue = 0;
529  }
530  else if (m_PaintingPixelValue == 0)
531  {
532  m_PaintingPixelValue = 1;
534  }
536 }
537 
539 {
540  const PlaneGeometry *planeGeometry((event->GetSender()->GetCurrentWorldPlaneGeometry()));
541  const AbstractTransformGeometry *abstractTransformGeometry(
542  dynamic_cast<const AbstractTransformGeometry *>(event->GetSender()->GetCurrentWorldPlaneGeometry()));
543  DataNode *workingNode(m_ToolManager->GetWorkingData(0));
544 
545  if (!workingNode)
546  return;
547 
548  Image::Pointer image = dynamic_cast<Image *>(workingNode->GetData());
549 
550  if (!image || !planeGeometry || abstractTransformGeometry)
551  return;
552 
553  if (m_CurrentPlane.IsNull() || m_WorkingSlice.IsNull())
554  {
555  m_CurrentPlane = const_cast<PlaneGeometry *>(planeGeometry);
556  m_WorkingSlice = SegTool2D::GetAffectedImageSliceAs2DImage(event, image)->Clone();
557  m_WorkingNode->ReplaceProperty("color", workingNode->GetProperty("color"));
558  m_WorkingNode->SetData(m_WorkingSlice);
559  }
560  else
561  {
562  bool isSameSlice(false);
563  isSameSlice = mitk::MatrixEqualElementWise(planeGeometry->GetIndexToWorldTransform()->GetMatrix(),
564  m_CurrentPlane->GetIndexToWorldTransform()->GetMatrix());
565  isSameSlice = mitk::Equal(planeGeometry->GetIndexToWorldTransform()->GetOffset(),
566  m_CurrentPlane->GetIndexToWorldTransform()->GetOffset());
567  if (!isSameSlice)
568  {
569  m_ToolManager->GetDataStorage()->Remove(m_WorkingNode);
570  m_CurrentPlane = nullptr;
571  m_WorkingSlice = nullptr;
572  m_WorkingNode = nullptr;
573  m_CurrentPlane = const_cast<PlaneGeometry *>(planeGeometry);
574  m_WorkingSlice = SegTool2D::GetAffectedImageSliceAs2DImage(event, image)->Clone();
575 
576  m_WorkingNode = mitk::DataNode::New();
577  m_WorkingNode->SetProperty("levelwindow", mitk::LevelWindowProperty::New(mitk::LevelWindow(0, 1)));
578  m_WorkingNode->SetProperty("binary", mitk::BoolProperty::New(true));
579 
580  m_WorkingNode->SetData(m_WorkingSlice);
581 
582  // So that the paintbrush contour vanished in the previous render window
584  }
585  }
586 
587  if (!m_ToolManager->GetDataStorage()->Exists(m_WorkingNode))
588  {
589  m_WorkingNode->SetProperty("outline binary", mitk::BoolProperty::New(true));
590  m_WorkingNode->SetProperty("color", workingNode->GetProperty("color"));
591  m_WorkingNode->SetProperty("name", mitk::StringProperty::New("Paintbrush_Node"));
592  m_WorkingNode->SetProperty("helper object", mitk::BoolProperty::New(true));
593  m_WorkingNode->SetProperty("opacity", mitk::FloatProperty::New(0.8));
594  m_WorkingNode->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false));
595  m_WorkingNode->SetVisibility(
597 
598  m_ToolManager->GetDataStorage()->Add(m_WorkingNode);
599  }
600 }
601 
603 {
604  // Here we simply set the current working slice to null. The next time the mouse is moved
605  // within a renderwindow a new slice will be extracted from the new working data
606  m_WorkingSlice = nullptr;
607 }
virtual void Deactivated() override
Called when the tool gets deactivated.
DataNode::Pointer m_WorkingNode
Super class for all position events.
virtual void OnMouseReleased(StateMachineAction *, InteractionEvent *)
virtual unsigned int GetSlice() const
virtual void OnPrimaryButtonPressedMoved(StateMachineAction *, InteractionEvent *)
BaseRenderer * GetSender() const
bool MatrixEqualElementWise(const vnl_matrix_fixed< TCoordRep, NRows, NCols > &matrix1, const vnl_matrix_fixed< TCoordRep, NRows, NCols > &matrix2, mitk::ScalarType epsilon=mitk::eps)
Check for element-wise matrix equality with a user defined accuracy.
Definition: mitkMatrix.h:144
void ConnectActionsAndFunctions() override
static BaseRenderer * GetInstance(vtkRenderWindow *renWin)
Image::Pointer GetAffectedImageSliceAs2DImage(const InteractionPositionEvent *positionEvent, const Image *image, unsigned int component=0)
Extract the slice of an image that the user just scribbles on. The given component denotes the vector...
static vtkRenderWindow * GetRenderWindowByName(const std::string &name)
void UpdateContour(const InteractionPositionEvent *)
virtual void OnMousePressed(StateMachineAction *, InteractionEvent *)
static void FillContourInSlice(ContourModel *projectedContour, Image *sliceImage, mitk::Image::Pointer workingImage, int paintingPixelValue=1)
Fill a contour in a 2D slice with a specified pixel value at time step 0.
static Pointer New()
void SetFeedbackContourColor(float r, float g, float b)
Provide values from 0.0 (black) to 1.0 (full color)
mitk::ContourElement::VertexIterator VertexIterator
#define MITK_DEBUG
Definition: mitkLogMacros.h:26
virtual const PlaneGeometry * GetCurrentWorldPlaneGeometry()
Get the current 2D-worldgeometry (m_CurrentWorldPlaneGeometry) used for 2D-rendering.
#define ROUND(a)
The LevelWindow class Class to store level/window values.
static Pointer New()
ContourModel::Pointer m_MasterContour
static Pointer New()
static RenderingManager * GetInstance()
Represents an action, that is executed after a certain event (in statemachine-mechanism) TODO: implem...
Image class for storing images.
Definition: mitkImage.h:76
PlaneGeometry::Pointer m_CurrentPlane
mitk::Label * GetActiveLabel(unsigned int layer=0)
Returns the active label of a specific layer.
Describes a geometry defined by an vtkAbstractTransform and a plane.
virtual void MouseMoved(mitk::InteractionEvent *interactionEvent, bool leftMouseButtonPressed)
virtual void Activated() override
Called when the tool gets activated.
ContourModel::Pointer BackProjectContourFrom2DSlice(const BaseGeometry *sliceGeometry, ContourModel *contourIn2D, bool correctionForIpSegmentation=false)
Projects a slice index coordinates of a contour back into world coordinates.
virtual unsigned int GetTimeStep() const
static Pointer New()
void RequestUpdate(vtkRenderWindow *renderWindow)
Base class for tools that use a contour for feedback.
void CheckIfCurrentSliceHasChanged(const InteractionPositionEvent *event)
MITKNEWMODULE_EXPORT bool Equal(mitk::ExampleDataStructure *leftHandSide, mitk::ExampleDataStructure *rightHandSide, mitk::ScalarType eps, bool verbose)
Returns true if the example data structures are considered equal.
mitk::Point2D upperLeft(mitk::Point2D p)
LabelSetImage class for handling labels and layers in a segmentation session.
MITKCORE_EXPORT const ScalarType eps
static Pointer New()
PaintbrushTool(int paintingPixelValue=1)
Describes a two-dimensional, rectangular plane.
#define CONNECT_FUNCTION(a, f)
unsigned int GetActiveLayer() const
Gets the ID of the currently active layer.
virtual void OnMouseMoved(StateMachineAction *, InteractionEvent *)
static Pointer New()
vtkRenderWindow * GetRenderWindow() const
Access the RenderWindow into which this renderer renders.
void RequestUpdateAll(RequestType type=REQUEST_UPDATE_ALL)
Class for nodes of the DataTree.
Definition: mitkDataNode.h:66
mitk::AffineTransform3D * GetIndexToWorldTransform()
Get the transformation used to convert from index to world coordinates.
virtual void OnInvertLogic(StateMachineAction *, InteractionEvent *)