Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
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())