18 #include <sofa/component/visualmodel/VisualModelImpl.h>
33 return m_Intersections;
38 for_each(
this, node, node->visualModel, &PlaneIntersectionVisitor::processVisualModel);
39 return RESULT_CONTINUE;
42 void mitk::PlaneIntersectionVisitor::processVisualModel(sofa::simulation::Node*, sofa::core::visual::VisualModel* visualModel)
44 using sofa::component::visualmodel::VisualModelImpl;
45 using sofa::core::topology::Triangle;
46 using sofa::core::topology::Quad;
47 using sofa::defaulttype::ResizableExtVector;
49 typedef VisualModelImpl::VecCoord VecCoord;
51 VisualModelImpl* visualModelImpl =
dynamic_cast<VisualModelImpl*
>(visualModel);
53 if (visualModelImpl ==
nullptr)
56 const sofa::core::loader::Material& material = visualModelImpl->material.getValue();
58 if (!material.useDiffuse)
61 const VecCoord& verts = visualModelImpl->getVertices();
62 const ResizableExtVector<Triangle>& tris = visualModelImpl->getTriangles();
63 const ResizableExtVector<Quad>& quads = visualModelImpl->getQuads();
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]) };
74 Intersection intersection;
76 const size_t numTriangles = tris.size();
78 for (
size_t i = 0; i < numTriangles; ++i)
80 t0 = verts[tris[i][0]].data();
81 t1 = verts[tris[i][1]].data();
82 t2 = verts[tris[i][2]].data();
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]);
88 if (d[0] * d[1] < 0.0f)
90 j = d[0] * d[2] < 0.0f
94 else if (d[0] * d[2] < 0.0f)
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();
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]));
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]));
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]));
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]));
119 intersection.edges.push_back(edge);
127 const size_t numQuads = quads.size();
129 for (
size_t i = 0; i < numQuads; ++i)
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();
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]);
141 if (d[0] * d[2] < 0.0f)
143 if (d[0] * d[3] < 0.0f)
145 if (d[0] * d[1] < 0.0f)
157 else if (d[0] * d[1] >= 0.0f)
163 else if (d[1] * d[3] < 0.0f)
165 if (d[1] * d[0] < 0.0f)
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]));
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]));
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]));
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]));
192 intersection.edges.push_back(edge);
195 if (!intersection.edges.empty())
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];
202 m_Intersections.push_back(intersection);
Result processNodeTopDown(sofa::simulation::Node *node) override
const std::vector< Intersection > & GetIntersections() const
PlaneIntersectionVisitor(const Point3D &point, const Vector3D &normal, const sofa::core::ExecParams *params=sofa::core::ExecParams::defaultInstance())
~PlaneIntersectionVisitor()