Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkExportMitkVisitor.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 "mitkExportMitkVisitor.h"
19 #include <mitkSimulation.h>
20 #include <mitkSurface.h>
21 #include <sofa/component/visualmodel/VisualModelImpl.h>
22 #include <vtkCellArray.h>
23 #include <vtkFloatArray.h>
24 #include <vtkPointData.h>
25 #include <vtkPolyData.h>
26 #include <vtkSmartPointer.h>
27 
28 void ApplyMaterial(mitk::DataNode::Pointer dataNode, const sofa::core::loader::Material& material)
29 {
30  using sofa::defaulttype::Vec4f;
31 
32  if (dataNode.IsNull() || dynamic_cast<mitk::Surface*>(dataNode->GetData()) == nullptr)
33  return;
34 
35  if (material.useDiffuse)
36  dataNode->SetFloatProperty("opacity", material.diffuse[3]);
37 
38  Vec4f ambient = material.useAmbient ? material.ambient : Vec4f();
39  Vec4f diffuse = material.useDiffuse ? material.diffuse : Vec4f();
40  Vec4f specular = material.useSpecular ? material.specular : Vec4f();
41  float shininess = material.useShininess ? std::min(material.shininess, 128.0f) : 45.0f;
42 
43  if (shininess == 0.0f)
44  {
45  specular.clear();
46  shininess = 1.0f;
47  }
48 
49  dataNode->SetFloatProperty("material.ambientCoefficient", 1.0f);
50  dataNode->SetProperty("material.ambientColor", mitk::ColorProperty::New(ambient.elems));
51 
52  dataNode->SetFloatProperty("material.diffuseCoefficient", 1.0f);
53  dataNode->SetProperty("color", mitk::ColorProperty::New(diffuse.elems));
54 
55  dataNode->SetFloatProperty("material.specularCoefficient", 1.0f);
56  dataNode->SetProperty("material.specularColor", mitk::ColorProperty::New(specular.elems));
57  dataNode->SetFloatProperty("material.specularPower", shininess);
58 }
59 
60 static mitk::DataNode::Pointer GetSimulationDataNode(mitk::DataStorage::Pointer dataStorage, sofa::core::objectmodel::BaseNode::SPtr rootNode)
61 {
62  if (dataStorage.IsNull())
63  return nullptr;
64 
65  if (!rootNode)
66  return nullptr;
67 
69  mitk::DataStorage::SetOfObjects::ConstPointer subset = dataStorage->GetSubset(predicate);
70 
71  for (mitk::DataStorage::SetOfObjects::ConstIterator it = subset->Begin(); it != subset->End(); ++it)
72  {
73  mitk::DataNode::Pointer dataNode = it.Value();
74  mitk::Simulation::Pointer simulation = static_cast<mitk::Simulation*>(dataNode->GetData());
75 
76  if (simulation->GetRootNode() == rootNode)
77  return dataNode;
78  }
79 
80  return nullptr;
81 }
82 
83 
84 mitk::ExportMitkVisitor::ExportMitkVisitor(DataStorage::Pointer dataStorage, const sofa::core::ExecParams* params)
85  : Visitor(params),
86  m_DataStorage(dataStorage)
87 {
88 }
89 
90 mitk::ExportMitkVisitor::ExportMitkVisitor(DataStorage::Pointer dataStorage, const std::string& visualModelName, const sofa::core::ExecParams* params)
91  : Visitor(params),
92  m_DataStorage(dataStorage),
93  m_VisualModelName(visualModelName)
94 {
95 }
96 
98 {
99 }
100 
101 sofa::simulation::Visitor::Result mitk::ExportMitkVisitor::processNodeTopDown(sofa::simulation::Node* node)
102 {
103  if (m_DataStorage.IsNotNull())
104  {
105  for_each(this, node, node->visualModel, &ExportMitkVisitor::processVisualModel);
106  return RESULT_CONTINUE;
107  }
108 
109  return RESULT_PRUNE;
110 }
111 
112 void mitk::ExportMitkVisitor::processVisualModel(sofa::simulation::Node* node, sofa::core::visual::VisualModel* visualModel)
113 {
114  using sofa::defaulttype::ResizableExtVector;
115  typedef sofa::component::visualmodel::VisualModelImpl::VecCoord VecCoord;
116  typedef sofa::component::visualmodel::VisualModelImpl::Triangle Triangle;
117  typedef sofa::component::visualmodel::VisualModelImpl::Quad Quad;
118  typedef sofa::component::visualmodel::VisualModelImpl::Deriv Deriv;
119  typedef sofa::component::visualmodel::VisualModelImpl::VecTexCoord VecTexCoord;
120 
121  sofa::component::visualmodel::VisualModelImpl* visualModelImpl = dynamic_cast<sofa::component::visualmodel::VisualModelImpl*>(visualModel);
122 
123  if (visualModelImpl == nullptr)
124  return;
125 
126  if (!m_VisualModelName.empty() && m_VisualModelName != visualModelImpl->name.getValue())
127  return;
128 
129  vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
130  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
131 
132  const VecCoord& vertices = visualModelImpl->m_vertices2.getValue().empty()
133  ? visualModelImpl->m_positions.getValue()
134  : visualModelImpl->m_vertices2.getValue();
135 
136  size_t numPoints = vertices.size();
137 
138  points->SetNumberOfPoints(numPoints);
139 
140  for (size_t i = 0; i < numPoints; ++i)
141  points->SetPoint(i, vertices[i].elems);
142 
143  polyData->SetPoints(points);
144 
145  vtkSmartPointer<vtkCellArray> polys = vtkSmartPointer<vtkCellArray>::New();
146  const ResizableExtVector<Triangle>& triangles = visualModelImpl->m_triangles.getValue();
147 
148  if (!triangles.empty())
149  {
150  ResizableExtVector<Triangle>::const_iterator trianglesEnd = triangles.end();
151 
152  for (ResizableExtVector<Triangle>::const_iterator it = triangles.begin(); it != trianglesEnd; ++it)
153  {
154  const Triangle& triangle = *it;
155 
156  polys->InsertNextCell(3);
157  polys->InsertCellPoint(triangle[0]);
158  polys->InsertCellPoint(triangle[1]);
159  polys->InsertCellPoint(triangle[2]);
160  }
161  }
162 
163  const ResizableExtVector<Quad>& quads = visualModelImpl->m_quads.getValue();
164 
165  if (!quads.empty())
166  {
167  ResizableExtVector<Quad>::const_iterator quadsEnd = quads.end();
168 
169  for (ResizableExtVector<Quad>::const_iterator it = quads.begin(); it != quadsEnd; ++it)
170  {
171  const Quad& quad = *it;
172 
173  polys->InsertNextCell(4);
174  polys->InsertCellPoint(quad[0]);
175  polys->InsertCellPoint(quad[1]);
176  polys->InsertCellPoint(quad[2]);
177  polys->InsertCellPoint(quad[3]);
178  }
179  }
180 
181  polyData->SetPolys(polys);
182 
183  const ResizableExtVector<Deriv>& normals = visualModelImpl->m_vnormals.getValue();
184 
185  if (!normals.empty())
186  {
187  size_t numNormals = normals.size();
188 
189  vtkSmartPointer<vtkFloatArray> vtkNormals = vtkSmartPointer<vtkFloatArray>::New();
190  vtkNormals->SetNumberOfComponents(3);
191  vtkNormals->SetNumberOfTuples(numNormals);
192 
193  for (size_t i = 0; i < numNormals; ++i)
194  vtkNormals->SetTuple(i, normals[i].elems);
195 
196  polyData->GetPointData()->SetNormals(vtkNormals);
197  }
198 
199  const VecTexCoord& texCoords = visualModelImpl->m_vtexcoords.getValue();
200 
201  if (!texCoords.empty())
202  {
203  size_t numTexCoords = texCoords.size();
204 
205  vtkSmartPointer<vtkFloatArray> vtkTexCoords = vtkSmartPointer<vtkFloatArray>::New();
206  vtkTexCoords->SetNumberOfComponents(2);
207  vtkTexCoords->SetNumberOfTuples(numTexCoords);
208 
209  for (size_t i = 0; i < numTexCoords; ++i)
210  vtkTexCoords->SetTuple(i, texCoords[i].elems);
211 
212  polyData->GetPointData()->SetTCoords(vtkTexCoords);
213  }
214 
215  Surface::Pointer surface = Surface::New();
216  surface->SetVtkPolyData(polyData);
217 
218  DataNode::Pointer dataNode = DataNode::New();
219  dataNode->SetName(visualModelImpl->name.getValue());
220  dataNode->SetData(surface);
221 
222  ApplyMaterial(dataNode, visualModelImpl->material.getValue());
223 
224  DataNode::Pointer parentDataNode = GetSimulationDataNode(m_DataStorage, node->getRoot());
225 
226  if (parentDataNode.IsNotNull())
227  surface->SetGeometry(parentDataNode->GetData()->GetGeometry());
228 
229  m_DataStorage->Add(dataNode, parentDataNode);
230 }
Class for storing surfaces (vtkPolyData).
Definition: mitkSurface.h:32
static Pointer New()
itk::SmartPointer< Self > Pointer
Definition: mitkSurface.h:37
itk::SmartPointer< const Self > ConstPointer
ExportMitkVisitor(DataStorage::Pointer dataStorage, const sofa::core::ExecParams *params=sofa::core::ExecParams::defaultInstance())
itk::SmartPointer< Self > Pointer
Definition: mitkDataNode.h:81
Result processNodeTopDown(sofa::simulation::Node *node) override
void ApplyMaterial(mitk::DataNode::Pointer dataNode, const sofa::core::loader::Material &material)
mitk::DataStorage::Pointer m_DataStorage
static Pointer New()
static T min(T x, T y)
Definition: svm.cpp:67
static mitk::DataNode::Pointer GetSimulationDataNode(mitk::DataStorage::Pointer dataStorage, sofa::core::objectmodel::BaseNode::SPtr rootNode)
static Pointer New()
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.