Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
mitkPlaneGeometryDataMapper2D.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"
18 #include <mitkDataNode.h>
19 #include <mitkLine.h>
20 #include <mitkPlaneGeometry.h>
22 #include <mitkPointSet.h>
23 #include <mitkProperties.h>
25 #include <mitkSlicedGeometry3D.h>
26 
27 // vtk includes
28 #include <mitkIPropertyAliases.h>
29 #include <vtkActor2D.h>
30 #include <vtkCellArray.h>
31 #include <vtkCellData.h>
32 #include <vtkLine.h>
33 #include <vtkPoints.h>
34 #include <vtkPolyData.h>
35 #include <vtkPolyDataMapper2D.h>
36 #include <vtkProperty2D.h>
37 #include <vtkTriangle.h>
38 
40 #include <algorithm>
41 #include <array>
42 #include <cassert>
43 #include <set>
44 
45 namespace
46 {
48  template <typename T>
49  class SimpleInterval
50  {
51  public:
52  SimpleInterval(T start = T(), T end = T())
53  : m_LowerBoundary(std::min(start, end)), m_UpperBoundary(std::max(start, end))
54  {
55  }
56 
57  T GetLowerBoundary() const { return m_LowerBoundary; }
58  T GetUpperBoundary() const { return m_UpperBoundary; }
59  bool empty() const { return m_LowerBoundary == m_UpperBoundary; }
60  bool operator<(const SimpleInterval &otherInterval) const
61  {
62  return this->m_UpperBoundary < otherInterval.GetLowerBoundary();
63  }
64 
65  private:
66  T m_LowerBoundary;
67  T m_UpperBoundary;
68  };
69 
70  template <typename T>
71  class IntervalSet
72  {
73  public:
74  typedef SimpleInterval<T> IntervalType;
75 
76  IntervalSet(IntervalType startingInterval) { m_IntervalsContainer.insert(std::move(startingInterval)); }
77  void operator-=(const IntervalType &interval)
78  {
79  // equal_range will find all the intervals in the interval set which intersect with the input interval
80  // due to the nature of operator< of SimpleInterval
81  auto range = m_IntervalsContainer.equal_range(interval);
82 
83  for (auto iter = range.first; iter != range.second;)
84  {
85  auto subtractionResult = SubtractIntervals(*iter, interval);
86 
87  // Remove the old interval from the set
88  iter = m_IntervalsContainer.erase(iter);
89  for (auto &&interval : subtractionResult)
90  {
91  if (!interval.empty())
92  {
93  // Add the new interval to the set
94  // emplace_hint adds the element at the closest valid place before the hint iterator,
95  // which is exactly where the new interval should be
96  iter = m_IntervalsContainer.insert(iter, std::move(interval));
97  ++iter;
98  }
99  }
100  }
101  }
102 
103  IntervalSet operator-(const IntervalType &interval)
104  {
105  IntervalSet result = *this;
106  result -= interval;
107  return result;
108  }
109 
110  typedef std::set<IntervalType> IntervalsContainer;
111 
112  const IntervalsContainer &getIntervals() const { return m_IntervalsContainer; }
113  private:
114  IntervalsContainer m_IntervalsContainer;
115 
116  std::array<IntervalType, 2> SubtractIntervals(const IntervalType &firstInterval, const IntervalType &secondInterval)
117  {
118  assert(secondInterval.GetUpperBoundary() >= firstInterval.GetLowerBoundary() &&
119  firstInterval.GetUpperBoundary() >=
120  secondInterval.GetLowerBoundary()); // Non-intersecting intervals should never reach here
121 
122  if (secondInterval.GetLowerBoundary() < firstInterval.GetLowerBoundary())
123  {
124  if (firstInterval.GetUpperBoundary() < secondInterval.GetUpperBoundary())
125  {
126  std::array<IntervalType, 2> result = {{IntervalType(), IntervalType()}};
127  return result; // firstInterval completely enclosed
128  }
129  std::array<IntervalType, 2> result = {
130  {IntervalType(firstInterval.GetUpperBoundary(), secondInterval.GetUpperBoundary()), IntervalType()}};
131  return result; // secondInterval removes the beginning of firstInterval
132  }
133 
134  if (firstInterval.GetUpperBoundary() < secondInterval.GetUpperBoundary())
135  {
136  std::array<IntervalType, 2> result = {
137  {IntervalType(firstInterval.GetLowerBoundary(), secondInterval.GetLowerBoundary()), IntervalType()}};
138  return result; // secondInterval removes the end of firstInterval
139  }
140  std::array<IntervalType, 2> result = {
141  {IntervalType(firstInterval.GetLowerBoundary(), secondInterval.GetLowerBoundary()),
142  IntervalType(secondInterval.GetUpperBoundary(), firstInterval.GetUpperBoundary())}};
143  return result; // secondInterval is completely enclosed in firstInterval and removes the middle
144  }
145  };
146 }
147 
149 
150 // input for this mapper ( = PlaneGeometryData)
152 {
153  return static_cast<PlaneGeometryData *>(GetDataNode()->GetData());
154 }
155 
157  : m_RenderOrientationArrows(false), m_ArrowOrientationPositive(true), m_DepthValue(1.0f)
158 {
159  s_AllInstances.insert(this);
160 }
161 
163 {
164  s_AllInstances.erase(this);
165 }
166 
168 {
169  LocalStorage *ls = m_LSH.GetLocalStorage(renderer);
170  return ls->m_CrosshairAssembly;
171 }
172 
174 {
176 
177  // The PlaneGeometryDataMapper2D mapper is special in that the rendering of
178  // OTHER PlaneGeometryDatas affects how we render THIS PlaneGeometryData
179  // (for the gap at the point where they intersect). A change in any of the
180  // other PlaneGeometryData nodes could mean that we render ourself
181  // differently, so we check for that here.
182  for (auto it = s_AllInstances.begin(); it != s_AllInstances.end(); ++it)
183  {
184  bool generateDataRequired = ls->IsGenerateDataRequired(renderer, this, (*it)->GetDataNode());
185  if (generateDataRequired)
186  break;
187  }
188 
190 
191  // Collect all other PlaneGeometryDatas that are being mapped by this mapper
192  m_OtherPlaneGeometries.clear();
193 
194  for (auto it = s_AllInstances.begin(); it != s_AllInstances.end(); ++it)
195  {
196  Self *otherInstance = *it;
197 
198  // Skip ourself
199  if (otherInstance == this)
200  continue;
201 
202  mitk::DataNode *otherNode = otherInstance->GetDataNode();
203  if (!otherNode)
204  continue;
205 
206  // Skip other PlaneGeometryData nodes that are not visible on this renderer
207  if (!otherNode->IsVisible(renderer))
208  continue;
209 
210  auto *otherData = dynamic_cast<PlaneGeometryData *>(otherNode->GetData());
211  if (!otherData)
212  continue;
213 
214  auto *otherGeometry = dynamic_cast<PlaneGeometry *>(otherData->GetPlaneGeometry());
215  if (otherGeometry && !dynamic_cast<AbstractTransformGeometry *>(otherData->GetPlaneGeometry()))
216  {
217  m_OtherPlaneGeometries.push_back(otherNode);
218  }
219  }
220 
221  CreateVtkCrosshair(renderer);
222 
223  ApplyAllProperties(renderer);
224 }
225 
227 {
228  bool visible = true;
229  LocalStorage *ls = m_LSH.GetLocalStorage(renderer);
230  ls->m_CrosshairActor->SetVisibility(0);
231  ls->m_ArrowActor->SetVisibility(0);
232  ls->m_CrosshairHelperLineActor->SetVisibility(0);
233 
234  GetDataNode()->GetVisibility(visible, renderer, "visible");
235 
236  if (!visible)
237  {
238  return;
239  }
240 
242  mitk::DataNode *geometryDataNode = renderer->GetCurrentWorldPlaneGeometryNode();
243  const PlaneGeometryData *rendererWorldPlaneGeometryData =
244  dynamic_cast<PlaneGeometryData *>(geometryDataNode->GetData());
245 
246  // intersecting with ourself?
247  if (input.IsNull() || input.GetPointer() == rendererWorldPlaneGeometryData)
248  {
249  return; // nothing to do in this case
250  }
251 
252  const auto *inputPlaneGeometry = dynamic_cast<const PlaneGeometry *>(input->GetPlaneGeometry());
253 
254  const auto *worldPlaneGeometry =
255  dynamic_cast<const PlaneGeometry *>(rendererWorldPlaneGeometryData->GetPlaneGeometry());
256 
257  if (worldPlaneGeometry && dynamic_cast<const AbstractTransformGeometry *>(worldPlaneGeometry) == nullptr &&
258  inputPlaneGeometry && dynamic_cast<const AbstractTransformGeometry *>(input->GetPlaneGeometry()) == nullptr)
259  {
260  const BaseGeometry *referenceGeometry = inputPlaneGeometry->GetReferenceGeometry();
261 
262  // calculate intersection of the plane data with the border of the
263  // world geometry rectangle
264  Point3D point1, point2;
265 
266  Line3D crossLine;
267 
268  // Calculate the intersection line of the input plane with the world plane
269  if (worldPlaneGeometry->IntersectionLine(inputPlaneGeometry, crossLine))
270  {
271  bool hasIntersection = referenceGeometry ? CutCrossLineWithReferenceGeometry(referenceGeometry, crossLine) :
272  CutCrossLineWithPlaneGeometry(inputPlaneGeometry, crossLine);
273 
274  if (!hasIntersection)
275  {
276  return;
277  }
278 
279  point1 = crossLine.GetPoint1();
280  point2 = crossLine.GetPoint2();
281 
282  vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
283  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
284  vtkSmartPointer<vtkPolyData> linesPolyData = vtkSmartPointer<vtkPolyData>::New();
285 
286  // Now iterate through all other lines displayed in this window and
287  // calculate the positions of intersection with the line to be
288  // rendered; these positions will be stored in lineParams to form a
289  // gap afterwards.
290  auto otherPlanesIt = m_OtherPlaneGeometries.begin();
291  auto otherPlanesEnd = m_OtherPlaneGeometries.end();
292 
293  int gapSize = 32;
294  this->GetDataNode()->GetPropertyValue("Crosshair.Gap Size", gapSize, nullptr);
295 
296  auto intervals = IntervalSet<double>(SimpleInterval<double>(0, 1));
297 
298  ScalarType lineLength = point1.EuclideanDistanceTo(point2);
299  ScalarType gapInMM = gapSize * renderer->GetScaleFactorMMPerDisplayUnit();
300  float gapSizeParam = gapInMM / lineLength;
301 
302  if (gapSize != 0)
303  {
304  while (otherPlanesIt != otherPlanesEnd)
305  {
306  bool ignorePlane = false;
307  (*otherPlanesIt)->GetPropertyValue("Crosshair.Ignore", ignorePlane);
308  if (ignorePlane)
309  {
310  ++otherPlanesIt;
311  continue;
312  }
313 
314  auto *otherPlaneGeometry = static_cast<PlaneGeometry *>(
315  static_cast<PlaneGeometryData *>((*otherPlanesIt)->GetData())->GetPlaneGeometry());
316 
317  if (otherPlaneGeometry != inputPlaneGeometry && otherPlaneGeometry != worldPlaneGeometry)
318  {
319  double intersectionParam;
320  if (otherPlaneGeometry->IntersectionPointParam(crossLine, intersectionParam) && intersectionParam > 0 &&
321  intersectionParam < 1)
322  {
323  Point3D point = crossLine.GetPoint() + intersectionParam * crossLine.GetDirection();
324 
325  bool intersectionPointInsideOtherPlane =
326  otherPlaneGeometry->HasReferenceGeometry() ?
327  TestPointInReferenceGeometry(otherPlaneGeometry->GetReferenceGeometry(), point) :
328  TestPointInPlaneGeometry(otherPlaneGeometry, point);
329 
330  if (intersectionPointInsideOtherPlane)
331  {
332  intervals -= SimpleInterval<double>(intersectionParam - gapSizeParam, intersectionParam + gapSizeParam);
333  }
334  }
335  }
336  ++otherPlanesIt;
337  }
338  }
339 
340  for (const auto &interval : intervals.getIntervals())
341  {
342  this->DrawLine(crossLine.GetPoint(interval.GetLowerBoundary()),
343  crossLine.GetPoint(interval.GetUpperBoundary()),
344  lines,
345  points);
346  }
347 
348  // Add the points to the dataset
349  linesPolyData->SetPoints(points);
350  // Add the lines to the dataset
351  linesPolyData->SetLines(lines);
352 
353  Vector3D orthogonalVector;
354  orthogonalVector = inputPlaneGeometry->GetNormal();
355  worldPlaneGeometry->Project(orthogonalVector, orthogonalVector);
356  orthogonalVector.Normalize();
357 
358  // Visualize
359  ls->m_Mapper->SetInputData(linesPolyData);
360  ls->m_CrosshairActor->SetMapper(ls->m_Mapper);
361 
362  // Determine if we should draw the area covered by the thick slicing, default is false.
363  // This will also show the area of slices that do not have thick slice mode enabled
364  bool showAreaOfThickSlicing = false;
365  GetDataNode()->GetBoolProperty("reslice.thickslices.showarea", showAreaOfThickSlicing);
366 
367  // determine the pixelSpacing in that direction
368  double thickSliceDistance = SlicedGeometry3D::CalculateSpacing(
369  referenceGeometry ? referenceGeometry->GetSpacing() : inputPlaneGeometry->GetSpacing(), orthogonalVector);
370 
371  IntProperty *intProperty = nullptr;
372  if (GetDataNode()->GetProperty(intProperty, "reslice.thickslices.num") && intProperty)
373  thickSliceDistance *= intProperty->GetValue() + 0.5;
374  else
375  showAreaOfThickSlicing = false;
376 
377  // not the nicest place to do it, but we have the width of the visible bloc in MM here
378  // so we store it in this fancy property
379  GetDataNode()->SetFloatProperty("reslice.thickslices.sizeinmm", thickSliceDistance * 2);
380 
381  ls->m_CrosshairActor->SetVisibility(1);
382 
383  vtkSmartPointer<vtkPolyData> arrowPolyData = vtkSmartPointer<vtkPolyData>::New();
384  ls->m_Arrowmapper->SetInputData(arrowPolyData);
385  if (this->m_RenderOrientationArrows)
386  {
387  ScalarType triangleSizeMM = 7.0 * renderer->GetScaleFactorMMPerDisplayUnit();
388 
389  vtkSmartPointer<vtkCellArray> triangles = vtkSmartPointer<vtkCellArray>::New();
390  vtkSmartPointer<vtkPoints> triPoints = vtkSmartPointer<vtkPoints>::New();
391 
392  DrawOrientationArrow(triangles, triPoints, triangleSizeMM, orthogonalVector, point1, point2);
393  DrawOrientationArrow(triangles, triPoints, triangleSizeMM, orthogonalVector, point2, point1);
394  arrowPolyData->SetPoints(triPoints);
395  arrowPolyData->SetPolys(triangles);
396  ls->m_ArrowActor->SetVisibility(1);
397  }
398 
399  // Visualize
400  vtkSmartPointer<vtkPolyData> helperlinesPolyData = vtkSmartPointer<vtkPolyData>::New();
401  ls->m_HelperLinesmapper->SetInputData(helperlinesPolyData);
402  if (showAreaOfThickSlicing)
403  {
404  vtkSmartPointer<vtkCellArray> helperlines = vtkSmartPointer<vtkCellArray>::New();
405  // vectorToHelperLine defines how to reach the helperLine from the mainLine
406  // got the right direction, so we multiply the width
407  Vector3D vecToHelperLine = orthogonalVector * thickSliceDistance;
408 
409  this->DrawLine(point1 - vecToHelperLine, point2 - vecToHelperLine, helperlines, points);
410  this->DrawLine(point1 + vecToHelperLine, point2 + vecToHelperLine, helperlines, points);
411 
412  // Add the points to the dataset
413  helperlinesPolyData->SetPoints(points);
414 
415  // Add the lines to the dataset
416  helperlinesPolyData->SetLines(helperlines);
417 
418  ls->m_CrosshairActor->GetProperty()->SetLineStipplePattern(0xf0f0);
419  ls->m_CrosshairActor->GetProperty()->SetLineStippleRepeatFactor(1);
420  ls->m_CrosshairHelperLineActor->SetVisibility(1);
421  }
422  }
423  }
424 }
425 
427 {
428  Point2D mappedPoint;
429  planeGeometry->Map(point, mappedPoint);
430  planeGeometry->WorldToIndex(mappedPoint, mappedPoint);
431 
432  return (planeGeometry->GetBounds()[0] < mappedPoint[0] && mappedPoint[0] < planeGeometry->GetBounds()[1] &&
433  planeGeometry->GetBounds()[2] < mappedPoint[1] && mappedPoint[1] < planeGeometry->GetBounds()[3]);
434 }
435 
437  const Point3D &point)
438 {
439  return referenceGeometry->IsInside(point);
440 }
441 
443  Line3D &crossLine)
444 {
445  Point2D indexLinePoint;
446  Vector2D indexLineDirection;
447 
448  planeGeometry->Map(crossLine.GetPoint(), indexLinePoint);
449  planeGeometry->Map(crossLine.GetPoint(), crossLine.GetDirection(), indexLineDirection);
450 
451  planeGeometry->WorldToIndex(indexLinePoint, indexLinePoint);
452  planeGeometry->WorldToIndex(indexLineDirection, indexLineDirection);
453 
454  mitk::Point2D intersectionPoints[2];
455 
456  // Then, clip this line with the (transformed) bounding box of the
457  // reference geometry.
458  int nIntersections = Line3D::RectangleLineIntersection(planeGeometry->GetBounds()[0],
459  planeGeometry->GetBounds()[2],
460  planeGeometry->GetBounds()[1],
461  planeGeometry->GetBounds()[3],
462  indexLinePoint,
463  indexLineDirection,
464  intersectionPoints[0],
465  intersectionPoints[1]);
466 
467  if (nIntersections < 2)
468  {
469  return false;
470  }
471 
472  planeGeometry->IndexToWorld(intersectionPoints[0], intersectionPoints[0]);
473  planeGeometry->IndexToWorld(intersectionPoints[1], intersectionPoints[1]);
474 
475  Point3D point1, point2;
476 
477  planeGeometry->Map(intersectionPoints[0], point1);
478  planeGeometry->Map(intersectionPoints[1], point2);
479  crossLine.SetPoints(point1, point2);
480 
481  return true;
482 }
483 
485  Line3D &crossLine)
486 {
487  Point3D boundingBoxMin, boundingBoxMax;
488  boundingBoxMin = referenceGeometry->GetCornerPoint(0);
489  boundingBoxMax = referenceGeometry->GetCornerPoint(7);
490 
491  Point3D indexLinePoint;
492  Vector3D indexLineDirection;
493 
494  referenceGeometry->WorldToIndex(crossLine.GetPoint(), indexLinePoint);
495  referenceGeometry->WorldToIndex(crossLine.GetDirection(), indexLineDirection);
496 
497  referenceGeometry->WorldToIndex(boundingBoxMin, boundingBoxMin);
498  referenceGeometry->WorldToIndex(boundingBoxMax, boundingBoxMax);
499 
500  Point3D point1, point2;
501 
502  // Then, clip this line with the (transformed) bounding box of the
503  // reference geometry.
504  int nIntersections = Line3D::BoxLineIntersection(boundingBoxMin[0],
505  boundingBoxMin[1],
506  boundingBoxMin[2],
507  boundingBoxMax[0],
508  boundingBoxMax[1],
509  boundingBoxMax[2],
510  indexLinePoint,
511  indexLineDirection,
512  point1,
513  point2);
514 
515  if (nIntersections < 2)
516  {
517  return false;
518  }
519 
520  referenceGeometry->IndexToWorld(point1, point1);
521  referenceGeometry->IndexToWorld(point2, point2);
522  crossLine.SetPoints(point1, point2);
523 
524  return true;
525 }
526 
528  mitk::Point3D p1,
529  vtkCellArray *lines,
530  vtkPoints *points)
531 {
532  vtkIdType pidStart = points->InsertNextPoint(p0[0], p0[1], p0[2]);
533  vtkIdType pidEnd = points->InsertNextPoint(p1[0], p1[1], p1[2]);
534 
535  vtkSmartPointer<vtkLine> lineVtk = vtkSmartPointer<vtkLine>::New();
536  lineVtk->GetPointIds()->SetId(0, pidStart);
537  lineVtk->GetPointIds()->SetId(1, pidEnd);
538 
539  lines->InsertNextCell(lineVtk);
540 }
541 
542 void mitk::PlaneGeometryDataMapper2D::DrawOrientationArrow(vtkSmartPointer<vtkCellArray> triangles,
543  vtkSmartPointer<vtkPoints> triPoints,
544  double triangleSizeMM,
545  Vector3D &orthogonalVector,
546  Point3D &point1,
547  Point3D &point2)
548 {
549  // Draw arrows to indicate plane orientation
550  // Vector along line
551  Vector3D v1 = point2 - point1;
552  v1.Normalize();
553  v1 *= triangleSizeMM;
554 
555  // Orthogonal vector
556  Vector3D v2 = orthogonalVector;
557  v2 *= triangleSizeMM;
558  if (!this->m_ArrowOrientationPositive)
559  v2 *= -1.0;
560 
561  // Initialize remaining triangle coordinates accordingly
562  Point3D p1 = point1 + v1 * 2.0;
563  Point3D p2 = point1 + v1 + v2;
564 
565  vtkIdType t0 = triPoints->InsertNextPoint(point1[0], point1[1], point1[2]); // start of the line
566  vtkIdType t1 = triPoints->InsertNextPoint(p1[0], p1[1], p1[2]); // point on line
567  vtkIdType t2 = triPoints->InsertNextPoint(p2[0], p2[1], p2[2]); // direction point
568 
569  vtkSmartPointer<vtkTriangle> triangle = vtkSmartPointer<vtkTriangle>::New();
570  triangle->GetPointIds()->SetId(0, t0);
571  triangle->GetPointIds()->SetId(1, t1);
572  triangle->GetPointIds()->SetId(2, t2);
573 
574  triangles->InsertNextCell(triangle);
575 }
576 
578 {
579  int thickSlicesMode = 0;
580  // determine the state and the extend of the thick-slice mode
581  mitk::ResliceMethodProperty *resliceMethodEnumProperty = nullptr;
582  if (dn->GetProperty(resliceMethodEnumProperty, "reslice.thickslices") && resliceMethodEnumProperty)
583  thickSlicesMode = resliceMethodEnumProperty->GetValueAsId();
584 
585  IntProperty *intProperty = nullptr;
586  if (dn->GetProperty(intProperty, "reslice.thickslices.num") && intProperty)
587  {
588  thickSlicesNum = intProperty->GetValue();
589  if (thickSlicesNum < 1)
590  thickSlicesNum = 0;
591  if (thickSlicesNum > 10)
592  thickSlicesNum = 10;
593  }
594 
595  if (thickSlicesMode == 0)
596  thickSlicesNum = 0;
597 
598  return thickSlicesMode;
599 }
600 
602 {
603  LocalStorage *ls = m_LSH.GetLocalStorage(renderer);
607 
608  float thickness;
609  this->GetDataNode()->GetFloatProperty("Line width", thickness, renderer);
610  ls->m_CrosshairActor->GetProperty()->SetLineWidth(thickness);
611  ls->m_CrosshairHelperLineActor->GetProperty()->SetLineWidth(thickness);
612 
613  PlaneOrientationProperty *decorationProperty;
614  this->GetDataNode()->GetProperty(decorationProperty, "decoration", renderer);
615  if (decorationProperty != nullptr)
616  {
618  {
621  }
622  else if (decorationProperty->GetPlaneDecoration() ==
624  {
627  }
628  else
629  {
631  }
632  }
633 }
634 
636 {
637  float rgba[4] = {1.0f, 1.0f, 1.0f, 1.0f};
638  DataNode *node = GetDataNode();
639 
640  // check for color prop and use it for rendering if it exists
641  node->GetColor(rgba, renderer, "color");
642  // check for opacity prop and use it for rendering if it exists
643  node->GetOpacity(rgba[3], renderer, "opacity");
644 
645  double drgba[4] = {rgba[0], rgba[1], rgba[2], rgba[3]};
646  actor->GetProperty()->SetColor(drgba);
647  actor->GetProperty()->SetOpacity(drgba[3]);
648 }
649 
651  mitk::BaseRenderer *renderer,
652  bool overwrite)
653 {
655  node->AddProperty("Line width", mitk::FloatProperty::New(1), renderer, overwrite);
656  aliases->AddAlias("line width", "Crosshair.Line Width", "");
657  node->AddProperty("Crosshair.Gap Size", mitk::IntProperty::New(32), renderer, overwrite);
658  node->AddProperty("decoration",
660  renderer,
661  overwrite);
662  aliases->AddAlias("decoration", "Crosshair.Orientation Decoration", "");
663 
664  Superclass::SetDefaultProperties(node, renderer, overwrite);
665 }
666 
668 {
669 }
670 
672 {
673  m_CrosshairAssembly = vtkSmartPointer<vtkPropAssembly>::New();
674 
675  m_CrosshairActor = vtkSmartPointer<vtkActor2D>::New();
676  m_ArrowActor = vtkSmartPointer<vtkActor2D>::New();
677  m_CrosshairHelperLineActor = vtkSmartPointer<vtkActor2D>::New();
678 
679  m_HelperLinesmapper = vtkSmartPointer<vtkPolyDataMapper2D>::New();
680  m_Mapper = vtkSmartPointer<vtkPolyDataMapper2D>::New();
681  m_Arrowmapper = vtkSmartPointer<vtkPolyDataMapper2D>::New();
682 
683  m_CrosshairActor->SetMapper(m_Mapper);
684  m_ArrowActor->SetMapper(m_Arrowmapper);
685  m_CrosshairHelperLineActor->SetMapper(m_HelperLinesmapper);
686 
687  m_CrosshairActor->SetVisibility(0);
688  m_ArrowActor->SetVisibility(0);
689  m_CrosshairHelperLineActor->SetVisibility(0);
690 
691  m_CrosshairAssembly->AddPart(m_CrosshairActor);
692  m_CrosshairAssembly->AddPart(m_ArrowActor);
693  m_CrosshairAssembly->AddPart(m_CrosshairHelperLineActor);
694 
695  vtkCoordinate *tcoord = vtkCoordinate::New();
696  tcoord->SetCoordinateSystemToWorld();
697  m_HelperLinesmapper->SetTransformCoordinate(tcoord);
698  m_Mapper->SetTransformCoordinate(tcoord);
699  // tcoord->SetCoordinateSystemToNormalizedDisplay();
700  m_Arrowmapper->SetTransformCoordinate(tcoord);
701  tcoord->Delete();
702 }
703 
705 {
706 }
#define ls
Definition: MitkMCxyz.cpp:57
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 IdType GetValueAsId() const
vtkProp * GetVtkProp(mitk::BaseRenderer *renderer) override
returns the a prop assembly
Interface of property aliases service.
virtual DataNode * GetCurrentWorldPlaneGeometryNode()
Get a DataNode pointing to a data object containing the current 2D-worldgeometry. ...
L * GetLocalStorage(mitk::BaseRenderer *forRenderer)
Retrieves a LocalStorage for a specific BaseRenderer.
Descibes a line.
Definition: mitkLine.h:28
void IndexToWorld(const mitk::Vector3D &vec_units, mitk::Vector3D &vec_mm) const
Convert (continuous or discrete) index coordinates of a vector vec_units to world coordinates (in mm)...
Base class for mapper specific rendering ressources.
Definition: mitkMapper.h:193
vtkSmartPointer< vtkPolyDataMapper2D > m_Arrowmapper
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
void DrawOrientationArrow(vtkSmartPointer< vtkCellArray > triangles, vtkSmartPointer< vtkPoints > triPoints, double triangleSizeMM, Vector3D &orthogonalVector, Point3D &point1, Point3D &point2)
bool IsInside(const mitk::Point3D &p) const
Test whether the point p (world coordinates in mm) is inside the bounding box.
Internal class holding the mapper, actor, etc. for each of the 3 2D render windows.
bool GetFloatProperty(const char *propertyKey, float &floatValue, const mitk::BaseRenderer *renderer=nullptr) const
Convenience access method for float properties (instances of FloatProperty)
bool operator<(const StaticParameterMap::ValueType &a, const StaticParameterMap::ValueType &b)
Compares two var lists and returns true if the first list&#39;s first item is lower than the second one&#39;s...
Organizes the rendering process.
double GetScaleFactorMMPerDisplayUnit() const
STL namespace.
Point3D GetCornerPoint(int id) const
Get the position of the corner number id (in world coordinates)
virtual bool AddAlias(const std::string &propertyName, const std::string &alias, const std::string &className="")=0
Add an alias for a specific property.
bool GetPropertyValue(const char *propertyKey, T &value, const mitk::BaseRenderer *renderer=nullptr) const
Convenience access method for GenericProperty<T> properties (T being the type of the second parameter...
Definition: mitkDataNode.h:278
static void SetDefaultProperties(mitk::DataNode *node, mitk::BaseRenderer *renderer=nullptr, bool overwrite=false)
set the default properties for this mapper
static int BoxLineIntersection(TCoordRep x1, TCoordRep y1, TCoordRep z1, TCoordRep x2, TCoordRep y2, TCoordRep z2, itk::Point< TCoordRep, 3 > p, itk::Vector< TCoordRep, 3 > d, itk::Point< TCoordRep, 3 > &s1, itk::Point< TCoordRep, 3 > &s2)
Calculates the intersection points of a straight line in 3D with a box.
Definition: mitkLine.h:346
virtual bool Map(const mitk::Point3D &pt3d_mm, mitk::Point2D &pt2d_mm) const
Project a 3D point given in mm (pt3d_mm) onto the 2D geometry. The result is a 2D point in mm (pt2d_m...
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)
Base class of all mappers, Vtk as well as OpenGL mappers.
Definition: mitkMapper.h:49
mitk::LocalStorageHandler< LocalStorage > m_LSH
The LocalStorageHandler holds all (three) LocalStorages for the three 2D render windows.
virtual void IndexToWorld(const Point2D &pt_units, Point2D &pt_mm) const
int DetermineThickSliceMode(DataNode *dn, int &thickSlicesNum)
Returns the thick slice mode for the given datanode.
const itk::Point< TCoordRep, NPointDimension > & GetPoint() const
Get start point of the line.
Definition: mitkLine.h:49
virtual T GetValue() const
const itk::Point< TCoordRep, NPointDimension > & GetPoint1() const
Get start point of the line.
Definition: mitkLine.h:111
const itk::Vector< TCoordRep, NPointDimension > & GetDirection() const
Get the direction vector of the line.
Definition: mitkLine.h:70
void ApplyColorAndOpacityProperties2D(BaseRenderer *renderer, vtkActor2D *actor)
void SetFloatProperty(const char *propertyKey, float floatValue, const mitk::BaseRenderer *renderer=nullptr)
Convenience method for setting float properties (instances of FloatProperty)
BaseData * GetData() const
Get the data object (instance of BaseData, e.g., an Image) managed by this DataNode.
static bool CutCrossLineWithReferenceGeometry(const BaseGeometry *referenceGeometry, Line3D &crossLine)
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 ...
bool IsVisible(const mitk::BaseRenderer *renderer, const char *propertyKey="visible", bool defaultIsOn=true) const
Convenience access method for visibility properties (instances of BoolProperty). Return value is the ...
Definition: mitkDataNode.h:462
bool GetColor(float rgb[3], const mitk::BaseRenderer *renderer=nullptr, const char *propertyKey="color") const
Convenience access method for color properties (instances of ColorProperty)
virtual void WorldToIndex(const Point2D &pt_mm, Point2D &pt_units) const
static bool TestPointInPlaneGeometry(const PlaneGeometry *planeGeometry, const Point3D &point)
void UpdateVtkTransform(mitk::BaseRenderer *renderer) override
Set the vtkTransform of the m_Prop3D for the current time step of renderer.
bool t2(false)
void SetPoints(const itk::Point< TCoordRep, NPointDimension > &point1, const itk::Point< TCoordRep, NPointDimension > &point2)
Define line by two points.
Definition: mitkLine.h:90
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
Describes a geometry defined by an vtkAbstractTransform and a plane.
Data class containing PlaneGeometry objects.
static bool CutCrossLineWithPlaneGeometry(const PlaneGeometry *planeGeometry, Line3D &crossLine)
static AllInstancesContainer s_AllInstances
static T max(T x, T y)
Definition: svm.cpp:56
void CreateVtkCrosshair(BaseRenderer *renderer)
void WorldToIndex(const mitk::Point3D &pt_mm, mitk::Point3D &pt_units) const
Convert world coordinates (in mm) of a point to (continuous!) index coordinates.
static Pointer New()
vtkSmartPointer< vtkPolyDataMapper2D > m_HelperLinesmapper
static T min(T x, T y)
Definition: svm.cpp:53
static bool TestPointInReferenceGeometry(const BaseGeometry *referenceGeometry, const Point3D &point)
virtual const mitk::PlaneGeometryData * GetInput() const
static Pointer New()
virtual void ApplyAllProperties(BaseRenderer *renderer)
itk::Point< TCoordRep, NPointDimension > GetPoint2() const
Get end point of the line.
Definition: mitkLine.h:117
void GenerateDataForRenderer(mitk::BaseRenderer *renderer) override
Generate the data needed for rendering into renderer.
const mitk::Vector3D GetSpacing() const
Get the spacing (size of a pixel).
static double CalculateSpacing(const mitk::Vector3D &spacing, const mitk::Vector3D &d)
static int RectangleLineIntersection(TCoordRep x1, TCoordRep y1, TCoordRep x2, TCoordRep y2, itk::Point< TCoordRep, 2 > p, itk::Vector< TCoordRep, 2 > d, itk::Point< TCoordRep, 2 > &s1, itk::Point< TCoordRep, 2 > &s2)
Calculates the intersection points of a straight line in 2D with a rectangle.
Definition: mitkLine.h:260
Describes a two-dimensional, rectangular plane.
virtual mitk::PlaneGeometry * GetPlaneGeometry() const
Get the reference to the PlaneGeometry that is stored by the object.
static IPropertyAliases * GetPropertyAliases(us::ModuleContext *context=us::GetModuleContext())
Get an IPropertyAliases instance.
const BoundsArrayType GetBounds() const
BaseGeometry Describes the geometry of a data object.
Class for nodes of the DataTree.
Definition: mitkDataNode.h:57
void DrawLine(Point3D p0, Point3D p1, vtkCellArray *lines, vtkPoints *points)
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