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
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.