Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
mitkPointSetVtkMapper2D.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 (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 
14 
15 // mitk includes
16 #include "mitkVtkPropRenderer.h"
17 #include <mitkDataNode.h>
18 #include <mitkPlaneGeometry.h>
19 #include <mitkPointSet.h>
20 #include <mitkProperties.h>
21 
22 // vtk includes
23 #include <vtkActor.h>
24 #include <vtkCellArray.h>
25 #include <vtkFloatArray.h>
26 #include <vtkGlyph3D.h>
27 #include <vtkGlyphSource2D.h>
28 #include <vtkLine.h>
29 #include <vtkPointData.h>
30 #include <vtkPolyDataMapper.h>
31 #include <vtkPropAssembly.h>
32 #include <vtkTextActor.h>
33 #include <vtkTextProperty.h>
34 #include <vtkTransform.h>
35 #include <vtkTransformFilter.h>
36 
37 #include <cstdlib>
38 
39 // constructor LocalStorage
41 {
42  // points
43  m_UnselectedPoints = vtkSmartPointer<vtkPoints>::New();
44  m_SelectedPoints = vtkSmartPointer<vtkPoints>::New();
45  m_ContourPoints = vtkSmartPointer<vtkPoints>::New();
46 
47  // scales
48  m_UnselectedScales = vtkSmartPointer<vtkFloatArray>::New();
49  m_SelectedScales = vtkSmartPointer<vtkFloatArray>::New();
50 
51  // distances
52  m_DistancesBetweenPoints = vtkSmartPointer<vtkFloatArray>::New();
53 
54  // lines
55  m_ContourLines = vtkSmartPointer<vtkCellArray>::New();
56 
57  // glyph source (provides the different shapes)
58  m_UnselectedGlyphSource2D = vtkSmartPointer<vtkGlyphSource2D>::New();
59  m_SelectedGlyphSource2D = vtkSmartPointer<vtkGlyphSource2D>::New();
60 
61  // glyphs
62  m_UnselectedGlyph3D = vtkSmartPointer<vtkGlyph3D>::New();
63  m_SelectedGlyph3D = vtkSmartPointer<vtkGlyph3D>::New();
64 
65  // polydata
66  m_VtkUnselectedPointListPolyData = vtkSmartPointer<vtkPolyData>::New();
67  m_VtkSelectedPointListPolyData = vtkSmartPointer<vtkPolyData>::New();
68  m_VtkContourPolyData = vtkSmartPointer<vtkPolyData>::New();
69 
70  // actors
71  m_UnselectedActor = vtkSmartPointer<vtkActor>::New();
72  m_SelectedActor = vtkSmartPointer<vtkActor>::New();
73  m_ContourActor = vtkSmartPointer<vtkActor>::New();
74 
75  // mappers
76  m_VtkUnselectedPolyDataMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
77  m_VtkSelectedPolyDataMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
78  m_VtkContourPolyDataMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
79 
80  // propassembly
81  m_PropAssembly = vtkSmartPointer<vtkPropAssembly>::New();
82 }
83 // destructor LocalStorage
85 {
86 }
87 
88 // input for this mapper ( = point set)
90 {
91  return static_cast<const mitk::PointSet *>(GetDataNode()->GetData());
92 }
93 
94 // constructor PointSetVtkMapper2D
96  : m_ShowContour(false),
97  m_CloseContour(false),
98  m_ShowPoints(true),
99  m_ShowDistances(false),
101  m_ShowAngles(false),
102  m_ShowDistantLines(false),
103  m_LineWidth(1),
104  m_PointLineWidth(1),
105  m_Point2DSize(6),
107  m_FillShape(false),
108  m_DistanceToPlane(4.0f)
109 {
110 }
111 
112 // destructor
114 {
115 }
116 
117 // reset mapper so that nothing is displayed e.g. toggle visiblity of the propassembly
119 {
120  LocalStorage *ls = m_LSH.GetLocalStorage(renderer);
121  ls->m_PropAssembly->VisibilityOff();
122 }
123 
124 // returns propassembly
126 {
127  LocalStorage *ls = m_LSH.GetLocalStorage(renderer);
128  return ls->m_PropAssembly;
129 }
130 
132 {
133  // The dot product of orthogonal vectors is zero.
134  // In two dimensions the slopes of perpendicular lines are negative reciprocals.
135  if ((fabs(in[0]) > 0) && ((fabs(in[0]) > fabs(in[1])) || (in[1] == 0)))
136  {
137  // negative reciprocal
138  out[0] = -in[1] / in[0];
139  out[1] = 1;
140  out.Normalize();
141  return true;
142  }
143  else if (fabs(in[1]) > 0)
144  {
145  out[0] = 1;
146  // negative reciprocal
147  out[1] = -in[0] / in[1];
148  out.Normalize();
149  return true;
150  }
151  else
152  return false;
153 }
154 
156 {
157  LocalStorage *ls = m_LSH.GetLocalStorage(renderer);
158 
159  unsigned i = 0;
160 
161  // The vtk text actors need to be removed manually from the propassembly
162  // since the same vtk text actors are not overwriten within this function,
163  // but new actors are added to the propassembly each time this function is executed.
164  // Thus, the actors from the last call must be removed in the beginning.
165  for (i = 0; i < ls->m_VtkTextLabelActors.size(); i++)
166  {
167  if (ls->m_PropAssembly->GetParts()->IsItemPresent(ls->m_VtkTextLabelActors.at(i)))
168  ls->m_PropAssembly->RemovePart(ls->m_VtkTextLabelActors.at(i));
169  }
170 
171  for (i = 0; i < ls->m_VtkTextDistanceActors.size(); i++)
172  {
173  if (ls->m_PropAssembly->GetParts()->IsItemPresent(ls->m_VtkTextDistanceActors.at(i)))
174  ls->m_PropAssembly->RemovePart(ls->m_VtkTextDistanceActors.at(i));
175  }
176 
177  for (i = 0; i < ls->m_VtkTextAngleActors.size(); i++)
178  {
179  if (ls->m_PropAssembly->GetParts()->IsItemPresent(ls->m_VtkTextAngleActors.at(i)))
180  ls->m_PropAssembly->RemovePart(ls->m_VtkTextAngleActors.at(i));
181  }
182 
183  // initialize polydata here, otherwise we have update problems when
184  // executing this function again
185  ls->m_VtkUnselectedPointListPolyData = vtkSmartPointer<vtkPolyData>::New();
186  ls->m_VtkSelectedPointListPolyData = vtkSmartPointer<vtkPolyData>::New();
187  ls->m_VtkContourPolyData = vtkSmartPointer<vtkPolyData>::New();
188 
189  // get input point set and update the PointSet
190  mitk::PointSet::Pointer input = const_cast<mitk::PointSet *>(this->GetInput());
191 
192  // only update the input data, if the property tells us to
193  bool update = true;
194  this->GetDataNode()->GetBoolProperty("updateDataOnRender", update);
195  if (update == true)
196  input->Update();
197 
198  int timestep = this->GetTimestep();
199  mitk::PointSet::DataType::Pointer itkPointSet = input->GetPointSet(timestep);
200 
201  if (itkPointSet.GetPointer() == nullptr)
202  {
203  ls->m_PropAssembly->VisibilityOff();
204  return;
205  }
206 
207  // iterator for point set
208  mitk::PointSet::PointsContainer::Iterator pointsIter = itkPointSet->GetPoints()->Begin();
209 
210  // PointDataContainer has additional information to each point, e.g. whether
211  // it is selected or not
212  mitk::PointSet::PointDataContainer::Iterator pointDataIter;
213  pointDataIter = itkPointSet->GetPointData()->Begin();
214 
215  // check if the list for the PointDataContainer is the same size as the PointsContainer.
216  // If not, then the points were inserted manually and can not be visualized according to the PointData
217  // (selected/unselected)
218  bool pointDataBroken = (itkPointSet->GetPointData()->Size() != itkPointSet->GetPoints()->Size());
219 
220  if (itkPointSet->GetPointData()->size() == 0 || pointDataBroken)
221  {
222  ls->m_PropAssembly->VisibilityOff();
223  return;
224  }
225 
226  ls->m_PropAssembly->VisibilityOn();
227 
228  // empty point sets, cellarrays, scalars
229  ls->m_UnselectedPoints->Reset();
230  ls->m_SelectedPoints->Reset();
231 
232  ls->m_ContourPoints->Reset();
233  ls->m_ContourLines->Reset();
234 
235  ls->m_UnselectedScales->Reset();
236  ls->m_SelectedScales->Reset();
237 
238  ls->m_DistancesBetweenPoints->Reset();
239 
240  ls->m_VtkTextLabelActors.clear();
241  ls->m_VtkTextDistanceActors.clear();
242  ls->m_VtkTextAngleActors.clear();
243 
244  ls->m_UnselectedScales->SetNumberOfComponents(3);
245  ls->m_SelectedScales->SetNumberOfComponents(3);
246 
247  int NumberContourPoints = 0;
248  bool pointsOnSameSideOfPlane = false;
249 
250  const int text2dDistance = 10;
251 
252  // initialize points with a random start value
253 
254  // current point in point set
255  itk::Point<ScalarType> point = pointsIter->Value();
256 
257  mitk::Point3D p = point; // currently visited point
258  mitk::Point3D lastP = point; // last visited point (predecessor in point set of "point")
259  mitk::Vector3D vec; // p - lastP
260  mitk::Vector3D lastVec; // lastP - point before lastP
261  vec.Fill(0.0);
262  lastVec.Fill(0.0);
263 
264  mitk::Point2D pt2d;
265  pt2d[0] = point[0]; // projected_p in display coordinates
266  pt2d[1] = point[1];
267  mitk::Point2D lastPt2d = pt2d; // last projected_p in display coordinates (predecessor in point set of "pt2d")
268  mitk::Point2D preLastPt2d = pt2d; // projected_p in display coordinates before lastPt2
269 
270  const mitk::PlaneGeometry *geo2D = renderer->GetCurrentWorldPlaneGeometry();
271 
272  vtkLinearTransform *dataNodeTransform = input->GetGeometry()->GetVtkTransform();
273 
274  int count = 0;
275 
276  for (pointsIter = itkPointSet->GetPoints()->Begin(); pointsIter != itkPointSet->GetPoints()->End(); pointsIter++)
277  {
278  lastP = p; // valid for number of points count > 0
279  preLastPt2d = lastPt2d; // valid only for count > 1
280  lastPt2d = pt2d; // valid for number of points count > 0
281 
282  lastVec = vec; // valid only for counter > 1
283 
284  // get current point in point set
285  point = pointsIter->Value();
286 
287  // transform point
288  {
289  float vtkp[3];
290  itk2vtk(point, vtkp);
291  dataNodeTransform->TransformPoint(vtkp, vtkp);
292  vtk2itk(vtkp, point);
293  }
294 
295  p[0] = point[0];
296  p[1] = point[1];
297  p[2] = point[2];
298 
299  renderer->WorldToDisplay(p, pt2d);
300 
301  vec = p - lastP; // valid only for counter > 0
302 
303  // compute distance to current plane
304  float dist = geo2D->Distance(point);
305 
306  // draw markers on slices a certain distance away from the points
307  // location according to the tolerance threshold (m_DistanceToPlane)
308  if (dist < m_DistanceToPlane)
309  {
310  // is point selected or not?
311  if (pointDataIter->Value().selected)
312  {
313  ls->m_SelectedPoints->InsertNextPoint(point[0], point[1], point[2]);
314  // point is scaled according to its distance to the plane
315  ls->m_SelectedScales->InsertNextTuple3(std::max(0.0f, m_Point2DSize - (2 * dist)), 0, 0);
316  }
317  else
318  {
319  ls->m_UnselectedPoints->InsertNextPoint(point[0], point[1], point[2]);
320  // point is scaled according to its distance to the plane
321  ls->m_UnselectedScales->InsertNextTuple3(std::max(0.0f, m_Point2DSize - (2 * dist)), 0, 0);
322  }
323 
324  //---- LABEL -----//
325  // paint label for each point if available
326  if (dynamic_cast<mitk::StringProperty *>(this->GetDataNode()->GetProperty("label")) != nullptr)
327  {
328  const char *pointLabel =
329  dynamic_cast<mitk::StringProperty *>(this->GetDataNode()->GetProperty("label"))->GetValue();
330  std::string l = pointLabel;
331  if (input->GetSize() > 1)
332  {
333  std::stringstream ss;
334  ss << pointsIter->Index();
335  l.append(ss.str());
336  }
337 
338  ls->m_VtkTextActor = vtkSmartPointer<vtkTextActor>::New();
339 
340  ls->m_VtkTextActor->SetDisplayPosition(pt2d[0] + text2dDistance, pt2d[1] + text2dDistance);
341  ls->m_VtkTextActor->SetInput(l.c_str());
342  ls->m_VtkTextActor->GetTextProperty()->SetOpacity(100);
343 
344  float unselectedColor[4] = {1.0, 1.0, 0.0, 1.0};
345 
346  // check if there is a color property
347  GetDataNode()->GetColor(unselectedColor);
348 
349  ls->m_VtkTextActor->GetTextProperty()->SetColor(unselectedColor[0], unselectedColor[1], unselectedColor[2]);
350 
351  ls->m_VtkTextLabelActors.push_back(ls->m_VtkTextActor);
352  }
353  }
354 
355  // draw contour, distance text and angle text in render window
356 
357  // lines between points, which intersect the current plane, are drawn
358  if (m_ShowContour && count > 0)
359  {
360  ScalarType distance = renderer->GetCurrentWorldPlaneGeometry()->SignedDistance(point);
361  ScalarType lastDistance = renderer->GetCurrentWorldPlaneGeometry()->SignedDistance(lastP);
362 
363  pointsOnSameSideOfPlane = (distance * lastDistance) > 0.5;
364 
365  // Points must be on different side of plane in order to draw a contour.
366  // If "show distant lines" is enabled this condition is disregarded.
367  if (!pointsOnSameSideOfPlane || m_ShowDistantLines)
368  {
369  vtkSmartPointer<vtkLine> line = vtkSmartPointer<vtkLine>::New();
370 
371  ls->m_ContourPoints->InsertNextPoint(lastP[0], lastP[1], lastP[2]);
372  line->GetPointIds()->SetId(0, NumberContourPoints);
373  NumberContourPoints++;
374 
375  ls->m_ContourPoints->InsertNextPoint(point[0], point[1], point[2]);
376  line->GetPointIds()->SetId(1, NumberContourPoints);
377  NumberContourPoints++;
378 
379  ls->m_ContourLines->InsertNextCell(line);
380 
381  if (m_ShowDistances) // calculate and print distance between adjacent points
382  {
383  float distancePoints = point.EuclideanDistanceTo(lastP);
384 
385  std::stringstream buffer;
386  buffer << std::fixed << std::setprecision(m_DistancesDecimalDigits) << distancePoints << " mm";
387 
388  // compute desired display position of text
389  Vector2D vec2d = pt2d - lastPt2d;
391  vec2d); // text is rendered within text2dDistance perpendicular to current line
392  Vector2D pos2d = (lastPt2d.GetVectorFromOrigin() + pt2d.GetVectorFromOrigin()) * 0.5 + vec2d * text2dDistance;
393 
394  ls->m_VtkTextActor = vtkSmartPointer<vtkTextActor>::New();
395 
396  ls->m_VtkTextActor->SetDisplayPosition(pos2d[0], pos2d[1]);
397  ls->m_VtkTextActor->SetInput(buffer.str().c_str());
398  ls->m_VtkTextActor->GetTextProperty()->SetColor(0.0, 1.0, 0.0);
399 
400  ls->m_VtkTextDistanceActors.push_back(ls->m_VtkTextActor);
401  }
402 
403  if (m_ShowAngles && count > 1) // calculate and print angle between connected lines
404  {
405  std::stringstream buffer;
406  buffer << angle(vec.GetVnlVector(), -lastVec.GetVnlVector()) * 180 / vnl_math::pi << "°";
407 
408  // compute desired display position of text
409  Vector2D vec2d = pt2d - lastPt2d; // first arm enclosing the angle
410  vec2d.Normalize();
411  Vector2D lastVec2d = lastPt2d - preLastPt2d; // second arm enclosing the angle
412  lastVec2d.Normalize();
413  vec2d = vec2d - lastVec2d; // vector connecting both arms
414  vec2d.Normalize();
415 
416  // middle between two vectors that enclose the angle
417  Vector2D pos2d = lastPt2d.GetVectorFromOrigin() + vec2d * text2dDistance * text2dDistance;
418 
419  ls->m_VtkTextActor = vtkSmartPointer<vtkTextActor>::New();
420 
421  ls->m_VtkTextActor->SetDisplayPosition(pos2d[0], pos2d[1]);
422  ls->m_VtkTextActor->SetInput(buffer.str().c_str());
423  ls->m_VtkTextActor->GetTextProperty()->SetColor(0.0, 1.0, 0.0);
424 
425  ls->m_VtkTextAngleActors.push_back(ls->m_VtkTextActor);
426  }
427  }
428  }
429 
430  if (pointDataIter != itkPointSet->GetPointData()->End())
431  {
432  pointDataIter++;
433  count++;
434  }
435  }
436 
437  // add each single text actor to the assembly
438  for (i = 0; i < ls->m_VtkTextLabelActors.size(); i++)
439  {
440  ls->m_PropAssembly->AddPart(ls->m_VtkTextLabelActors.at(i));
441  }
442 
443  for (i = 0; i < ls->m_VtkTextDistanceActors.size(); i++)
444  {
445  ls->m_PropAssembly->AddPart(ls->m_VtkTextDistanceActors.at(i));
446  }
447 
448  for (i = 0; i < ls->m_VtkTextAngleActors.size(); i++)
449  {
450  ls->m_PropAssembly->AddPart(ls->m_VtkTextAngleActors.at(i));
451  }
452 
453  //---- CONTOUR -----//
454 
455  // create lines between the points which intersect the plane
456  if (m_ShowContour)
457  {
458  // draw line between first and last point which is rendered
459  if (m_CloseContour && NumberContourPoints > 1)
460  {
461  vtkSmartPointer<vtkLine> closingLine = vtkSmartPointer<vtkLine>::New();
462  closingLine->GetPointIds()->SetId(0, 0); // index of first point
463  closingLine->GetPointIds()->SetId(1, NumberContourPoints - 1); // index of last point
464  ls->m_ContourLines->InsertNextCell(closingLine);
465  }
466 
467  ls->m_VtkContourPolyData->SetPoints(ls->m_ContourPoints);
468  ls->m_VtkContourPolyData->SetLines(ls->m_ContourLines);
469 
470  ls->m_VtkContourPolyDataMapper->SetInputData(ls->m_VtkContourPolyData);
471  ls->m_ContourActor->SetMapper(ls->m_VtkContourPolyDataMapper);
472  ls->m_ContourActor->GetProperty()->SetLineWidth(m_LineWidth);
473 
474  ls->m_PropAssembly->AddPart(ls->m_ContourActor);
475  }
476 
477  // the point set must be transformed in order to obtain the appropriate glyph orientation
478  // according to the current view
479  vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
480  vtkSmartPointer<vtkMatrix4x4> a, b = vtkSmartPointer<vtkMatrix4x4>::New();
481 
482  a = geo2D->GetVtkTransform()->GetMatrix();
483  b->DeepCopy(a);
484 
485  // delete transformation from matrix, only take orientation
486  b->SetElement(3, 3, 1);
487  b->SetElement(2, 3, 0);
488  b->SetElement(1, 3, 0);
489  b->SetElement(0, 3, 0);
490  b->SetElement(3, 2, 0);
491  b->SetElement(3, 1, 0);
492  b->SetElement(3, 0, 0);
493 
494  Vector3D spacing = geo2D->GetSpacing();
495 
496  // If you find a way to simplyfy the following, feel free to change!
497  b->SetElement(0, 0, b->GetElement(0, 0) / spacing[0]);
498  b->SetElement(1, 0, b->GetElement(1, 0) / spacing[0]);
499  b->SetElement(2, 0, b->GetElement(2, 0) / spacing[0]);
500  b->SetElement(1, 1, b->GetElement(1, 1) / spacing[1]);
501  b->SetElement(2, 1, b->GetElement(2, 1) / spacing[1]);
502 
503  b->SetElement(0, 2, b->GetElement(0, 2) / spacing[2]);
504  b->SetElement(1, 2, b->GetElement(1, 2) / spacing[2]);
505  b->SetElement(2, 2, b->GetElement(2, 2) / spacing[2]);
506 
507  transform->SetMatrix(b);
508 
509  //---- UNSELECTED POINTS -----//
510 
511  // apply properties to glyph
512  ls->m_UnselectedGlyphSource2D->SetGlyphType(m_IDShapeProperty);
513 
514  if (m_FillShape)
515  ls->m_UnselectedGlyphSource2D->FilledOn();
516  else
517  ls->m_UnselectedGlyphSource2D->FilledOff();
518 
519  // apply transform
520  vtkSmartPointer<vtkTransformFilter> transformFilterU = vtkSmartPointer<vtkTransformFilter>::New();
521  transformFilterU->SetInputConnection(ls->m_UnselectedGlyphSource2D->GetOutputPort());
522  transformFilterU->SetTransform(transform);
523 
525  ls->m_VtkUnselectedPointListPolyData->GetPointData()->SetVectors(ls->m_UnselectedScales);
526 
527  // apply transform of current plane to glyphs
528  ls->m_UnselectedGlyph3D->SetSourceConnection(transformFilterU->GetOutputPort());
530  ls->m_UnselectedGlyph3D->SetScaleModeToScaleByVector();
531  ls->m_UnselectedGlyph3D->SetVectorModeToUseVector();
532 
533  ls->m_VtkUnselectedPolyDataMapper->SetInputConnection(ls->m_UnselectedGlyph3D->GetOutputPort());
535  ls->m_UnselectedActor->GetProperty()->SetLineWidth(m_PointLineWidth);
536 
537  ls->m_PropAssembly->AddPart(ls->m_UnselectedActor);
538 
539  //---- SELECTED POINTS -----//
540 
541  ls->m_SelectedGlyphSource2D->SetGlyphTypeToDiamond();
542  ls->m_SelectedGlyphSource2D->CrossOn();
543  ls->m_SelectedGlyphSource2D->FilledOff();
544 
545  // apply transform
546  vtkSmartPointer<vtkTransformFilter> transformFilterS = vtkSmartPointer<vtkTransformFilter>::New();
547  transformFilterS->SetInputConnection(ls->m_SelectedGlyphSource2D->GetOutputPort());
548  transformFilterS->SetTransform(transform);
549 
551  ls->m_VtkSelectedPointListPolyData->GetPointData()->SetVectors(ls->m_SelectedScales);
552 
553  // apply transform of current plane to glyphs
554  ls->m_SelectedGlyph3D->SetSourceConnection(transformFilterS->GetOutputPort());
555  ls->m_SelectedGlyph3D->SetInputData(ls->m_VtkSelectedPointListPolyData);
556  ls->m_SelectedGlyph3D->SetScaleModeToScaleByVector();
557  ls->m_SelectedGlyph3D->SetVectorModeToUseVector();
558 
559  ls->m_VtkSelectedPolyDataMapper->SetInputConnection(ls->m_SelectedGlyph3D->GetOutputPort());
560  ls->m_SelectedActor->SetMapper(ls->m_VtkSelectedPolyDataMapper);
561  ls->m_SelectedActor->GetProperty()->SetLineWidth(m_PointLineWidth);
562 
563  ls->m_PropAssembly->AddPart(ls->m_SelectedActor);
564 }
565 
567 {
568  const mitk::DataNode *node = GetDataNode();
569  if (node == nullptr)
570  return;
571 
572  LocalStorage *ls = m_LSH.GetLocalStorage(renderer);
573 
574  // check whether the input data has been changed
575  bool needGenerateData = ls->IsGenerateDataRequired(renderer, this, GetDataNode());
576 
577  // toggle visibility
578  bool visible = true;
579  node->GetVisibility(visible, renderer, "visible");
580  if (!visible)
581  {
582  ls->m_UnselectedActor->VisibilityOff();
583  ls->m_SelectedActor->VisibilityOff();
584  ls->m_ContourActor->VisibilityOff();
585  ls->m_PropAssembly->VisibilityOff();
586  return;
587  }
588  else
589  {
590  ls->m_PropAssembly->VisibilityOn();
591  }
592 
593  node->GetBoolProperty("show contour", m_ShowContour, renderer);
594  node->GetBoolProperty("close contour", m_CloseContour, renderer);
595  node->GetBoolProperty("show points", m_ShowPoints, renderer);
596  node->GetBoolProperty("show distances", m_ShowDistances, renderer);
597  node->GetIntProperty("distance decimal digits", m_DistancesDecimalDigits, renderer);
598  node->GetBoolProperty("show angles", m_ShowAngles, renderer);
599  node->GetBoolProperty("show distant lines", m_ShowDistantLines, renderer);
600  node->GetIntProperty("line width", m_LineWidth, renderer);
601  node->GetIntProperty("point line width", m_PointLineWidth, renderer);
602  if (!node->GetFloatProperty(
603  "point 2D size", m_Point2DSize, renderer)) // re-defined to float 2015-08-13, keep a fallback
604  {
605  int oldPointSize = m_Point2DSize;
606  if (node->GetIntProperty("point 2D size", oldPointSize, renderer))
607  {
608  m_Point2DSize = oldPointSize;
609  }
610  }
611  node->GetBoolProperty("Pointset.2D.fill shape", m_FillShape, renderer);
612  node->GetFloatProperty("Pointset.2D.distance to plane", m_DistanceToPlane, renderer);
613 
615  dynamic_cast<mitk::PointSetShapeProperty *>(this->GetDataNode()->GetProperty("Pointset.2D.shape", renderer));
616  if (shape.IsNotNull())
617  {
618  m_IDShapeProperty = shape->GetPointSetShape();
619  }
620 
621  // check for color props and use it for rendering of selected/unselected points and contour
622  // due to different params in VTK (double/float) we have to convert
623 
624  float opacity = 1.0;
625 
626  GetDataNode()->GetOpacity(opacity, renderer);
627 
628  // apply color and opacity
629  if (m_ShowPoints)
630  {
631  float unselectedColor[4];
632  double selectedColor[4] = {1.0f, 0.0f, 0.0f, 1.0f}; // red
633 
634  ls->m_UnselectedActor->VisibilityOn();
635  ls->m_SelectedActor->VisibilityOn();
636 
637  // check if there is a color property
638  GetDataNode()->GetColor(unselectedColor);
639 
640  // get selected color property
641  if (dynamic_cast<mitk::ColorProperty *>(
642  this->GetDataNode()->GetPropertyList(renderer)->GetProperty("selectedcolor")) != nullptr)
643  {
644  mitk::Color tmpColor = dynamic_cast<mitk::ColorProperty *>(
645  this->GetDataNode()->GetPropertyList(renderer)->GetProperty("selectedcolor"))
646  ->GetValue();
647  selectedColor[0] = tmpColor[0];
648  selectedColor[1] = tmpColor[1];
649  selectedColor[2] = tmpColor[2];
650  selectedColor[3] = 1.0f; // alpha value
651  }
652  else if (dynamic_cast<mitk::ColorProperty *>(
653  this->GetDataNode()->GetPropertyList(nullptr)->GetProperty("selectedcolor")) != nullptr)
654  {
655  mitk::Color tmpColor =
656  dynamic_cast<mitk::ColorProperty *>(this->GetDataNode()->GetPropertyList(nullptr)->GetProperty("selectedcolor"))
657  ->GetValue();
658  selectedColor[0] = tmpColor[0];
659  selectedColor[1] = tmpColor[1];
660  selectedColor[2] = tmpColor[2];
661  selectedColor[3] = 1.0f; // alpha value
662  }
663 
664  ls->m_SelectedActor->GetProperty()->SetColor(selectedColor);
665  ls->m_SelectedActor->GetProperty()->SetOpacity(opacity);
666 
667  ls->m_UnselectedActor->GetProperty()->SetColor(unselectedColor[0], unselectedColor[1], unselectedColor[2]);
668  ls->m_UnselectedActor->GetProperty()->SetOpacity(opacity);
669  }
670  else
671  {
672  ls->m_UnselectedActor->VisibilityOff();
673  ls->m_SelectedActor->VisibilityOff();
674  }
675 
676  if (m_ShowContour)
677  {
678  double contourColor[4] = {1.0f, 0.0f, 0.0f, 1.0f}; // red
679  ls->m_ContourActor->VisibilityOn();
680 
681  // get contour color property
682  if (dynamic_cast<mitk::ColorProperty *>(
683  this->GetDataNode()->GetPropertyList(renderer)->GetProperty("contourcolor")) != nullptr)
684  {
685  mitk::Color tmpColor =
686  dynamic_cast<mitk::ColorProperty *>(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("contourcolor"))
687  ->GetValue();
688  contourColor[0] = tmpColor[0];
689  contourColor[1] = tmpColor[1];
690  contourColor[2] = tmpColor[2];
691  contourColor[3] = 1.0f;
692  }
693  else if (dynamic_cast<mitk::ColorProperty *>(
694  this->GetDataNode()->GetPropertyList(nullptr)->GetProperty("contourcolor")) != nullptr)
695  {
696  mitk::Color tmpColor =
697  dynamic_cast<mitk::ColorProperty *>(this->GetDataNode()->GetPropertyList(nullptr)->GetProperty("contourcolor"))
698  ->GetValue();
699  contourColor[0] = tmpColor[0];
700  contourColor[1] = tmpColor[1];
701  contourColor[2] = tmpColor[2];
702  contourColor[3] = 1.0f;
703  }
704 
705  ls->m_ContourActor->GetProperty()->SetColor(contourColor);
706  ls->m_ContourActor->GetProperty()->SetOpacity(opacity);
707  }
708  else
709  {
710  ls->m_ContourActor->VisibilityOff();
711  }
712 
713  if (needGenerateData)
714  {
715  // create new vtk render objects (e.g. a circle for a point)
716  this->CreateVTKRenderObjects(renderer);
717  }
718 }
719 
721 {
722  node->AddProperty("line width", mitk::IntProperty::New(2), renderer, overwrite);
723  node->AddProperty("point line width", mitk::IntProperty::New(1), renderer, overwrite);
724  node->AddProperty("point 2D size", mitk::FloatProperty::New(6), renderer, overwrite);
725  node->AddProperty("show contour", mitk::BoolProperty::New(false), renderer, overwrite);
726  node->AddProperty("close contour", mitk::BoolProperty::New(false), renderer, overwrite);
727  node->AddProperty("show points", mitk::BoolProperty::New(true), renderer, overwrite);
728  node->AddProperty("show distances", mitk::BoolProperty::New(false), renderer, overwrite);
729  node->AddProperty("distance decimal digits", mitk::IntProperty::New(2), renderer, overwrite);
730  node->AddProperty("show angles", mitk::BoolProperty::New(false), renderer, overwrite);
731  node->AddProperty("show distant lines", mitk::BoolProperty::New(false), renderer, overwrite);
732  node->AddProperty("layer", mitk::IntProperty::New(1), renderer, overwrite);
733  node->AddProperty("Pointset.2D.fill shape",
735  renderer,
736  overwrite); // fill or do not fill the glyph shape
738  node->AddProperty("Pointset.2D.shape", pointsetShapeProperty, renderer, overwrite);
739  node->AddProperty("Pointset.2D.distance to plane",
741  renderer,
742  overwrite); // show the point at a certain distance above/below the 2D imaging plane.
743 
744  Superclass::SetDefaultProperties(node, renderer, overwrite);
745 }
#define ls
Definition: MitkMCxyz.cpp:57
std::vector< vtkSmartPointer< vtkTextActor > > m_VtkTextLabelActors
mitk::BaseProperty * GetProperty(const char *propertyKey, const mitk::BaseRenderer *renderer=nullptr, bool fallBackOnDataProperties=true) const
Get the property (instance of BaseProperty) with key propertyKey from the PropertyList of the rendere...
virtual ScalarType SignedDistance(const Point3D &pt3d_mm) const
L * GetLocalStorage(mitk::BaseRenderer *forRenderer)
Retrieves a LocalStorage for a specific BaseRenderer.
static char * line
Definition: svm.cpp:2870
vtkSmartPointer< vtkPropAssembly > m_PropAssembly
bool IsGenerateDataRequired(mitk::BaseRenderer *renderer, mitk::Mapper *mapper, mitk::DataNode *dataNode) const
Definition: mitkMapper.cpp:119
virtual DataNode * GetDataNode() const
Get the DataNode containing the data to map. Method only returns valid DataNode Pointer if the mapper...
Definition: mitkMapper.cpp:31
double ScalarType
vtkLinearTransform * GetVtkTransform() const
Get the m_IndexToWorldTransform as a vtkLinearTransform.
vtkSmartPointer< vtkPolyDataMapper > m_VtkSelectedPolyDataMapper
bool GetFloatProperty(const char *propertyKey, float &floatValue, const mitk::BaseRenderer *renderer=nullptr) const
Convenience access method for float properties (instances of FloatProperty)
Organizes the rendering process.
vtkSmartPointer< vtkGlyph3D > m_UnselectedGlyph3D
DataCollection - Class to facilitate loading/accessing structured data.
virtual const PlaneGeometry * GetCurrentWorldPlaneGeometry()
Get the current 2D-worldgeometry (m_CurrentWorldPlaneGeometry) used for 2D-rendering.
vtkSmartPointer< vtkPolyData > m_VtkUnselectedPointListPolyData
vtkSmartPointer< vtkFloatArray > m_DistancesBetweenPoints
mitk::LocalStorageHandler< LocalStorage > m_LSH
The LocalStorageHandler holds all (three) LocalStorages for the three 2D render windows.
bool GetBoolProperty(const char *propertyKey, bool &boolValue, const mitk::BaseRenderer *renderer=nullptr) const
Convenience access method for bool properties (instances of BoolProperty)
bool GetOpacity(float &opacity, const mitk::BaseRenderer *renderer, const char *propertyKey="opacity") const
Convenience access method for opacity properties (instances of FloatProperty)
void WorldToDisplay(const Point3D &worldIndex, Point2D &displayPoint) const
This method converts a 3D world index to the display point using the geometry of the renderWindow...
vtkProp * GetVtkProp(mitk::BaseRenderer *renderer) override
returns the a prop assembly
bool GetIntProperty(const char *propertyKey, int &intValue, const mitk::BaseRenderer *renderer=nullptr) const
Convenience access method for int properties (instances of IntProperty)
vtkSmartPointer< vtkFloatArray > m_UnselectedScales
vtkSmartPointer< vtkPolyDataMapper > m_VtkContourPolyDataMapper
std::vector< vtkSmartPointer< vtkTextActor > > m_VtkTextAngleActors
vtkSmartPointer< vtkPolyDataMapper > m_VtkUnselectedPolyDataMapper
vtkSmartPointer< vtkFloatArray > m_SelectedScales
static Pointer New()
vtkSmartPointer< vtkPoints > m_UnselectedPoints
The ColorProperty class RGB color property.
BaseData * GetData() const
Get the data object (instance of BaseData, e.g., an Image) managed by this DataNode.
vtkSmartPointer< vtkPolyData > m_VtkSelectedPointListPolyData
void AddProperty(const char *propertyKey, BaseProperty *property, const mitk::BaseRenderer *renderer=nullptr, bool overwrite=false)
Add the property (instance of BaseProperty) if it does not exist (or always ifoverwrite istrue) with ...
Data structure which stores a set of points. Superclass of mitk::Mesh.
Definition: mitkPointSet.h:75
static void SetDefaultProperties(mitk::DataNode *node, mitk::BaseRenderer *renderer=nullptr, bool overwrite=false)
set the default properties for this mapper
bool GetColor(float rgb[3], const mitk::BaseRenderer *renderer=nullptr, const char *propertyKey="color") const
Convenience access method for color properties (instances of ColorProperty)
vtkSmartPointer< vtkPolyData > m_VtkContourPolyData
Internal class holding the mapper, actor, etc. for each of the 3 2D render windows.
bool GetVisibility(bool &visible, const mitk::BaseRenderer *renderer, const char *propertyKey="visible") const
Convenience access method for visibility properties (instances of BoolProperty with property-key "vis...
Definition: mitkDataNode.h:422
vtkSmartPointer< vtkCellArray > m_ContourLines
void vtk2itk(const Tin &in, Tout &out)
vtkSmartPointer< vtkGlyphSource2D > m_SelectedGlyphSource2D
vtkSmartPointer< vtkGlyph3D > m_SelectedGlyph3D
static T max(T x, T y)
Definition: svm.cpp:56
vtkSmartPointer< vtkTextActor > m_VtkTextActor
itk::RGBPixel< float > Color
Color Standard RGB color typedef (float)
static Pointer New()
mitk::PropertyList * GetPropertyList(const mitk::BaseRenderer *renderer=nullptr) const
Get the PropertyList of the renderer. If renderer is nullptr, the BaseRenderer-independent PropertyLi...
static bool in(Reader::Char c, Reader::Char c1, Reader::Char c2, Reader::Char c3, Reader::Char c4)
Definition: jsoncpp.cpp:244
static Pointer New()
void itk2vtk(const Tin &in, Tout &out)
vtkSmartPointer< vtkGlyphSource2D > m_UnselectedGlyphSource2D
const mitk::Vector3D GetSpacing() const
Get the spacing (size of a pixel).
void ResetMapper(BaseRenderer *renderer) override
Reset the mapper (i.e., make sure that nothing is displayed) if no valid data is present. In most cases the reimplemented function disables the according actors (toggling visibility off)
const float selectedColor[]
int GetTimestep() const
Returns the current time step as calculated from the renderer.
Definition: mitkMapper.h:147
ScalarType Distance(const Point3D &pt3d_mm) const
Distance of the point from the geometry (bounding-box not considered)
mitk::BaseProperty * GetProperty(const std::string &propertyKey) const
Get a property by its name.
virtual void CreateVTKRenderObjects(mitk::BaseRenderer *renderer)
Describes a two-dimensional, rectangular plane.
Property for strings.
std::vector< vtkSmartPointer< vtkTextActor > > m_VtkTextDistanceActors
void GenerateDataForRenderer(mitk::BaseRenderer *renderer) override
Generate the data needed for rendering into renderer.
virtual const mitk::PointSet * GetInput() const
Class for nodes of the DataTree.
Definition: mitkDataNode.h:57
static void SetDefaultProperties(DataNode *node, BaseRenderer *renderer=nullptr, bool overwrite=false)
Set default values of properties used by this mapper to node.
Definition: mitkMapper.cpp:143
static bool makePerpendicularVector2D(const mitk::Vector2D &in, mitk::Vector2D &out)