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
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 *)