Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkContourModelMapper3D.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 ===================================================================*/
17 
18 #include <vtkCellArray.h>
19 #include <vtkPoints.h>
20 #include <vtkProperty.h>
21 
23 {
24 }
25 
27 {
28 }
29 
31 {
32  // convient way to get the data from the dataNode
33  return static_cast<const mitk::ContourModel *>(GetDataNode()->GetData());
34 }
35 
37 {
38  // return the actor corresponding to the renderer
39  return m_LSH.GetLocalStorage(renderer)->m_Actor;
40 }
41 
43 {
44  /* First convert the contourModel to vtkPolyData, then tube filter it and
45  * set it input for our mapper
46  */
47 
48  LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
49 
50  mitk::ContourModel *inputContour = static_cast<mitk::ContourModel *>(GetDataNode()->GetData());
51 
52  localStorage->m_OutlinePolyData = this->CreateVtkPolyDataFromContour(inputContour);
53 
54  this->ApplyContourProperties(renderer);
55 
56  // tube filter the polyData
57  localStorage->m_TubeFilter->SetInputData(localStorage->m_OutlinePolyData);
58 
59  float lineWidth(1.0);
60  if (this->GetDataNode()->GetFloatProperty("contour.3D.width", lineWidth, renderer))
61  {
62  localStorage->m_TubeFilter->SetRadius(lineWidth);
63  }
64  else
65  {
66  localStorage->m_TubeFilter->SetRadius(0.5);
67  }
68  localStorage->m_TubeFilter->CappingOn();
69  localStorage->m_TubeFilter->SetNumberOfSides(10);
70  localStorage->m_TubeFilter->Update();
71  localStorage->m_Mapper->SetInputConnection(localStorage->m_TubeFilter->GetOutputPort());
72 }
73 
75 {
76  bool visible = true;
77  GetDataNode()->GetVisibility(visible, renderer, "visible");
78 
79  mitk::ContourModel *data = static_cast<mitk::ContourModel *>(GetDataNode()->GetData());
80  if (data == NULL)
81  {
82  return;
83  }
84 
85  // Calculate time step of the input data for the specified renderer (integer value)
86  this->CalculateTimeStep(renderer);
87 
88  LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
89  // Check if time step is valid
90  const TimeGeometry *dataTimeGeometry = data->GetTimeGeometry();
91  if ((dataTimeGeometry == NULL) || (dataTimeGeometry->CountTimeSteps() == 0) ||
92  (!dataTimeGeometry->IsValidTimeStep(renderer->GetTimeStep())) || (this->GetTimestep() == -1))
93  {
94  // clear the rendered polydata
95  localStorage->m_Mapper->SetInputData(vtkSmartPointer<vtkPolyData>::New());
96  return;
97  }
98 
99  const DataNode *node = this->GetDataNode();
100  data->UpdateOutputInformation();
101 
102  // check if something important has changed and we need to rerender
103  if ((localStorage->m_LastUpdateTime < node->GetMTime()) // was the node modified?
104  ||
105  (localStorage->m_LastUpdateTime < data->GetPipelineMTime()) // Was the data modified?
106  ||
107  (localStorage->m_LastUpdateTime <
108  renderer->GetCurrentWorldPlaneGeometryUpdateTime()) // was the geometry modified?
109  ||
110  (localStorage->m_LastUpdateTime < renderer->GetCurrentWorldPlaneGeometry()->GetMTime()) ||
111  (localStorage->m_LastUpdateTime < node->GetPropertyList()->GetMTime()) // was a property modified?
112  ||
113  (localStorage->m_LastUpdateTime < node->GetPropertyList(renderer)->GetMTime()))
114  {
115  this->GenerateDataForRenderer(renderer);
116  }
117 
118  // since we have checked that nothing important has changed, we can set
119  // m_LastUpdateTime to the current time
120  localStorage->m_LastUpdateTime.Modified();
121 }
122 
124 {
125  unsigned int timestep = this->GetTimestep();
126 
127  // the points to draw
128  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
129  // the lines to connect the points
130  vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
131  // Create a polydata to store everything in
132  vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
133 
134  // iterate over the control points
135  mitk::ContourModel::VertexIterator current = inputContour->IteratorBegin(timestep);
136  mitk::ContourModel::VertexIterator next = inputContour->IteratorBegin(timestep);
137  if (next != inputContour->IteratorEnd(timestep))
138  {
139  next++;
140 
141  mitk::ContourModel::VertexIterator end = inputContour->IteratorEnd(timestep);
142 
143  while (next != end)
144  {
145  mitk::ContourModel::VertexType *currentControlPoint = *current;
146  mitk::ContourModel::VertexType *nextControlPoint = *next;
147 
148  if (!(currentControlPoint->Coordinates[0] == nextControlPoint->Coordinates[0] &&
149  currentControlPoint->Coordinates[1] == nextControlPoint->Coordinates[1] &&
150  currentControlPoint->Coordinates[2] == nextControlPoint->Coordinates[2]))
151  {
152  vtkIdType p1 = points->InsertNextPoint(currentControlPoint->Coordinates[0],
153  currentControlPoint->Coordinates[1],
154  currentControlPoint->Coordinates[2]);
155  vtkIdType p2 = points->InsertNextPoint(
156  nextControlPoint->Coordinates[0], nextControlPoint->Coordinates[1], nextControlPoint->Coordinates[2]);
157  // add the line between both contorlPoints
158  lines->InsertNextCell(2);
159  lines->InsertCellPoint(p1);
160  lines->InsertCellPoint(p2);
161  }
162  current++;
163  next++;
164  }
165 
166  if (inputContour->IsClosed(timestep))
167  {
168  // If the contour is closed add a line from the last to the first control point
169  mitk::ContourModel::VertexType *firstControlPoint = *(inputContour->IteratorBegin(timestep));
170  mitk::ContourModel::VertexType *lastControlPoint = *(--(inputContour->IteratorEnd(timestep)));
171  if (lastControlPoint->Coordinates[0] != firstControlPoint->Coordinates[0] ||
172  lastControlPoint->Coordinates[1] != firstControlPoint->Coordinates[1] ||
173  lastControlPoint->Coordinates[2] != firstControlPoint->Coordinates[2])
174  {
175  vtkIdType p2 = points->InsertNextPoint(
176  lastControlPoint->Coordinates[0], lastControlPoint->Coordinates[1], lastControlPoint->Coordinates[2]);
177  vtkIdType p1 = points->InsertNextPoint(
178  firstControlPoint->Coordinates[0], firstControlPoint->Coordinates[1], firstControlPoint->Coordinates[2]);
179 
180  // add the line to the cellArray
181  lines->InsertNextCell(2);
182  lines->InsertCellPoint(p1);
183  lines->InsertCellPoint(p2);
184  }
185  }
186 
187  // Add the points to the dataset
188  polyData->SetPoints(points);
189  // Add the lines to the dataset
190  polyData->SetLines(lines);
191  }
192  return polyData;
193 }
194 
196 {
197  LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
198 
199  mitk::ColorProperty::Pointer colorprop =
200  dynamic_cast<mitk::ColorProperty *>(GetDataNode()->GetProperty("contour.color", renderer));
201  if (colorprop)
202  {
203  // set the color of the contour
204  double red = colorprop->GetColor().GetRed();
205  double green = colorprop->GetColor().GetGreen();
206  double blue = colorprop->GetColor().GetBlue();
207  localStorage->m_Actor->GetProperty()->SetColor(red, green, blue);
208  }
209 }
210 
211 /*+++++++++++++++++++ LocalStorage part +++++++++++++++++++++++++*/
212 
214 {
215  return m_LSH.GetLocalStorage(renderer);
216 }
217 
219 {
221  m_Actor = vtkSmartPointer<vtkActor>::New();
222  m_OutlinePolyData = vtkSmartPointer<vtkPolyData>::New();
223  m_TubeFilter = vtkSmartPointer<vtkTubeFilter>::New();
224 
225  // set the mapper for the actor
226  m_Actor->SetMapper(m_Mapper);
227 }
228 
230  mitk::BaseRenderer *renderer,
231  bool overwrite)
232 {
233  node->AddProperty("color", ColorProperty::New(1.0, 0.0, 0.0), renderer, overwrite);
234  node->AddProperty("contour.3D.width", mitk::FloatProperty::New(0.5), renderer, overwrite);
235 
236  Superclass::SetDefaultProperties(node, renderer, overwrite);
237 }
mitk::PropertyList * GetPropertyList(const mitk::BaseRenderer *renderer=nullptr) const
Get the PropertyList of the renderer. If renderer is NULL, the BaseRenderer-independent PropertyList ...
LocalStorage()
Default constructor of the local storage.
ContourModel is a structure of linked vertices defining a contour in 3D space. The vertices are store...
virtual void UpdateOutputInformation() override
Update the OutputInformation of a ContourModel object.
mitk::Point3D Coordinates
Coordinates in 3D space.
virtual unsigned long GetMTime() const override
Get the timestamp of the last change of the map or the last change of one of the properties store in ...
static Pointer New()
Organizes the rendering process.
mitk::ContourElement::VertexIterator VertexIterator
vtkSmartPointer< vtkTubeFilter > m_TubeFilter
virtual const PlaneGeometry * GetCurrentWorldPlaneGeometry()
Get the current 2D-worldgeometry (m_CurrentWorldPlaneGeometry) used for 2D-rendering.
const mitk::TimeGeometry * GetTimeGeometry() const
Return the TimeGeometry of the data as const pointer.
Definition: mitkBaseData.h:52
virtual void ApplyContourProperties(mitk::BaseRenderer *renderer)
vtkSmartPointer< vtkPolyDataMapper > m_Mapper
Mapper of a 2D render window.
VertexIterator IteratorBegin(int timestep=0) const
Returns a const VertexIterator at the start element of the contour.
virtual unsigned long GetMTime() const override
Get the timestamp of the last change of the contents of this node or the referenced BaseData...
virtual void Update(mitk::BaseRenderer *renderer) override
Checks whether this mapper needs to update itself and generate data.
virtual vtkSmartPointer< vtkPolyData > CreateVtkPolyDataFromContour(mitk::ContourModel *inputContour)
The ColorProperty class RGB color property.
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 ...
LocalStorage * GetLocalStorage(mitk::BaseRenderer *renderer)
Get the LocalStorage corresponding to the current renderer.
virtual unsigned int GetTimeStep() const
static Pointer New()
vtkSmartPointer< vtkPolyData > m_OutlinePolyData
bool IsClosed(int timestep=0) const
Return if the contour is closed or not.
const mitk::ContourModel * GetInput(void)
virtual vtkProp * GetVtkProp(mitk::BaseRenderer *renderer) override
itk::TimeStamp m_LastUpdateTime
Timestamp of last update of stored data.
unsigned long GetCurrentWorldPlaneGeometryUpdateTime()
Get timestamp of last call of SetCurrentWorldPlaneGeometry.
VertexIterator IteratorEnd(int timestep=0) const
Returns a const VertexIterator at the end element of the contour.
static void SetDefaultProperties(mitk::DataNode *node, mitk::BaseRenderer *renderer=NULL, bool overwrite=false)
Set the default properties for general image rendering.
Represents a single vertex of contour.
vtkSmartPointer< vtkActor > m_Actor
Actor of a 2D render window.
virtual bool IsValidTimeStep(TimeStepType timeStep) const =0
Test for the given time step if a geometry is availible.
void GenerateDataForRenderer(mitk::BaseRenderer *renderer) override
Generate the data needed for rendering into renderer.
Class for nodes of the DataTree.
Definition: mitkDataNode.h:66
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.