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
mitkPlaneIntersectionVisitor.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 
18 #include <sofa/component/visualmodel/VisualModelImpl.h>
19 
20 mitk::PlaneIntersectionVisitor::PlaneIntersectionVisitor(const Point3D& point, const Vector3D& normal, const sofa::core::ExecParams* params)
21  : Visitor(params),
22  m_Point(point),
23  m_Normal(normal)
24 {
25 }
26 
28 {
29 }
30 
31 const std::vector<mitk::PlaneIntersectionVisitor::Intersection>& mitk::PlaneIntersectionVisitor::GetIntersections() const
32 {
33  return m_Intersections;
34 }
35 
36 sofa::simulation::Visitor::Result mitk::PlaneIntersectionVisitor::processNodeTopDown(sofa::simulation::Node* node)
37 {
38  for_each(this, node, node->visualModel, &PlaneIntersectionVisitor::processVisualModel);
39  return RESULT_CONTINUE;
40 }
41 
42 void mitk::PlaneIntersectionVisitor::processVisualModel(sofa::simulation::Node*, sofa::core::visual::VisualModel* visualModel)
43 {
44  using sofa::component::visualmodel::VisualModelImpl;
45  using sofa::core::topology::Triangle;
46  using sofa::core::topology::Quad;
47  using sofa::defaulttype::ResizableExtVector;
48 
49  typedef VisualModelImpl::VecCoord VecCoord;
50 
51  VisualModelImpl* visualModelImpl = dynamic_cast<VisualModelImpl*>(visualModel);
52 
53  if (visualModelImpl == nullptr)
54  return;
55 
56  const sofa::core::loader::Material& material = visualModelImpl->material.getValue();
57 
58  if (!material.useDiffuse)
59  return;
60 
61  const VecCoord& verts = visualModelImpl->getVertices();
62  const ResizableExtVector<Triangle>& tris = visualModelImpl->getTriangles();
63  const ResizableExtVector<Quad>& quads = visualModelImpl->getQuads();
64 
65  float n[3] = { static_cast<float>(m_Normal[0]), static_cast<float>(m_Normal[1]), static_cast<float>(m_Normal[2]) };
66  float p[3] = { static_cast<float>(m_Point[0]), static_cast<float>(m_Point[1]), static_cast<float>(m_Point[2]) };
67  float d[4];
68  int j;
69  const float* t0;
70  const float* t1;
71  const float* t2;
72  float s;
73  Edge edge;
74  Intersection intersection;
75 
76  const size_t numTriangles = tris.size();
77 
78  for (size_t i = 0; i < numTriangles; ++i)
79  {
80  t0 = verts[tris[i][0]].data();
81  t1 = verts[tris[i][1]].data();
82  t2 = verts[tris[i][2]].data();
83 
84  d[0] = n[0] * (p[0] - t0[0]) + n[1] * (p[1] - t0[1]) + n[2] * (p[2] - t0[2]);
85  d[1] = n[0] * (p[0] - t1[0]) + n[1] * (p[1] - t1[1]) + n[2] * (p[2] - t1[2]);
86  d[2] = n[0] * (p[0] - t2[0]) + n[1] * (p[1] - t2[1]) + n[2] * (p[2] - t2[2]);
87 
88  if (d[0] * d[1] < 0.0f)
89  {
90  j = d[0] * d[2] < 0.0f
91  ? 0
92  : 1;
93  }
94  else if (d[0] * d[2] < 0.0f)
95  {
96  j = 2;
97  }
98  else
99  {
100  continue;
101  }
102 
103  t0 = verts[tris[i][j]].data();
104  t1 = verts[tris[i][(j + 1) % 3]].data();
105  t2 = verts[tris[i][(j + 2) % 3]].data();
106 
107  s = (n[0] * (p[0] - t0[0]) + n[1] * (p[1] - t0[1]) + n[2] * (p[2] - t0[2])) / (n[0] * (t1[0] - t0[0]) + n[1] * (t1[1] - t0[1]) + n[2] * (t1[2] - t0[2]));
108 
109  edge.v0[0] = static_cast<ScalarType>(t0[0] + s * (t1[0] - t0[0]));
110  edge.v0[1] = static_cast<ScalarType>(t0[1] + s * (t1[1] - t0[1]));
111  edge.v0[2] = static_cast<ScalarType>(t0[2] + s * (t1[2] - t0[2]));
112 
113  s = (n[0] * (p[0] - t0[0]) + n[1] * (p[1] - t0[1]) + n[2] * (p[2] - t0[2])) / (n[0] * (t2[0] - t0[0]) + n[1] * (t2[1] - t0[1]) + n[2] * (t2[2] - t0[2]));
114 
115  edge.v1[0] = static_cast<ScalarType>(t0[0] + s * (t2[0] - t0[0]));
116  edge.v1[1] = static_cast<ScalarType>(t0[1] + s * (t2[1] - t0[1]));
117  edge.v1[2] = static_cast<ScalarType>(t0[2] + s * (t2[2] - t0[2]));
118 
119  intersection.edges.push_back(edge);
120  }
121 
122  const float* q0;
123  const float* q1;
124  const float* q2;
125  const float* q3;
126 
127  const size_t numQuads = quads.size();
128 
129  for (size_t i = 0; i < numQuads; ++i)
130  {
131  q0 = verts[quads[i][0]].data();
132  q1 = verts[quads[i][1]].data();
133  q2 = verts[quads[i][2]].data();
134  q3 = verts[quads[i][3]].data();
135 
136  d[0] = n[0] * (p[0] - q0[0]) + n[1] * (p[1] - q0[1]) + n[2] * (p[2] - q0[2]);
137  d[1] = n[0] * (p[0] - q1[0]) + n[1] * (p[1] - q1[1]) + n[2] * (p[2] - q1[2]);
138  d[2] = n[0] * (p[0] - q2[0]) + n[1] * (p[1] - q2[1]) + n[2] * (p[2] - q2[2]);
139  d[3] = n[0] * (p[0] - q3[0]) + n[1] * (p[1] - q3[1]) + n[2] * (p[2] - q3[2]);
140 
141  if (d[0] * d[2] < 0.0f)
142  {
143  if (d[0] * d[3] < 0.0f)
144  {
145  if (d[0] * d[1] < 0.0f)
146  {
147  q2 = q0;
148  }
149  else
150  {
151  const float* q = q0;
152  q0 = q1;
153  q1 = q2;
154  q2 = q;
155  }
156  }
157  else if (d[0] * d[1] >= 0.0f)
158  {
159  q0 = q1;
160  q1 = q2;
161  }
162  }
163  else if (d[1] * d[3] < 0.0f)
164  {
165  if (d[1] * d[0] < 0.0f)
166  {
167  q3 = q2;
168  q2 = q1;
169  }
170  else
171  {
172  q1 = q3;
173  }
174  }
175  else
176  {
177  continue;
178  }
179 
180  s = (n[0] * (p[0] - q0[0]) + n[1] * (p[1] - q0[1]) + n[2] * (p[2] - q0[2])) / (n[0] * (q1[0] - q0[0]) + n[1] * (q1[1] - q0[1]) + n[2] * (q1[2] - q0[2]));
181 
182  edge.v0[0] = static_cast<ScalarType>(q0[0] + s * (q1[0] - q0[0]));
183  edge.v0[1] = static_cast<ScalarType>(q0[1] + s * (q1[1] - q0[1]));
184  edge.v0[2] = static_cast<ScalarType>(q0[2] + s * (q1[2] - q0[2]));
185 
186  s = (n[0] * (p[0] - q2[0]) + n[1] * (p[1] - q2[1]) + n[2] * (p[2] - q2[2])) / (n[0] * (q3[0] - q2[0]) + n[1] * (q3[1] - q2[1]) + n[2] * (q3[2] - q2[2]));
187 
188  edge.v1[0] = static_cast<ScalarType>(q2[0] + s * (q3[0] - q2[0]));
189  edge.v1[1] = static_cast<ScalarType>(q2[1] + s * (q3[1] - q2[1]));
190  edge.v1[2] = static_cast<ScalarType>(q2[2] + s * (q3[2] - q2[2]));
191 
192  intersection.edges.push_back(edge);
193  }
194 
195  if (!intersection.edges.empty())
196  {
197  intersection.color[0] = material.diffuse[0];
198  intersection.color[1] = material.diffuse[1];
199  intersection.color[2] = material.diffuse[2];
200  intersection.color[3] = material.diffuse[3];
201 
202  m_Intersections.push_back(intersection);
203  }
204 }
Result processNodeTopDown(sofa::simulation::Node *node) override
double ScalarType
const std::vector< Intersection > & GetIntersections() const
PlaneIntersectionVisitor(const Point3D &point, const Vector3D &normal, const sofa::core::ExecParams *params=sofa::core::ExecParams::defaultInstance())