7 #include "imstkVTKSurfaceNormalRenderDelegate.h" 8 #include "imstkPointSet.h" 9 #include "imstkVisualModel.h" 10 #include "imstkGeometryUtilities.h" 11 #include "imstkRenderMaterial.h" 12 #include "imstkLogger.h" 13 #include "imstkSurfaceMesh.h" 16 #include <vtkDataArray.h> 17 #include <vtkPointData.h> 18 #include <vtkTransform.h> 19 #include <vtkArrowSource.h> 20 #include <vtkOpenGLGlyph3DMapper.h> 24 VTKSurfaceNormalRenderDelegate::VTKSurfaceNormalRenderDelegate() :
25 m_polydata(vtkSmartPointer<vtkPolyData>::New())
30 VTKSurfaceNormalRenderDelegate::init()
32 auto surfMesh = std::dynamic_pointer_cast<SurfaceMesh>(
m_visualModel->getGeometry());
33 CHECK(surfMesh !=
nullptr) <<
"VTKSurfaceNormalRenderDelegate only works with SurfaceMesh geometry";
34 m_surfMeshVertices = surfMesh->getVertexPositions();
35 m_surfMeshIndices = surfMesh->getCells();
38 m_triangleCenterVertices = computeTriangleCenters(m_surfMeshVertices, m_surfMeshIndices);
39 m_triangleNormals = computeTriangleNormals(m_surfMeshVertices, m_surfMeshIndices);
42 if (m_surfMeshVertices !=
nullptr)
45 auto points = vtkSmartPointer<vtkPoints>::New();
46 points->SetNumberOfPoints(m_triangleCenterVertices->size());
48 m_polydata->SetPoints(points);
52 m_mappedNormalsArray->SetName(
"ImageScalars");
53 m_polydata->GetPointData()->SetVectors(m_mappedNormalsArray);
56 queueConnect<Event>(surfMesh, &Geometry::modified,
57 std::static_pointer_cast<VTKSurfaceNormalRenderDelegate>(shared_from_this()),
61 queueConnect<Event>(m_surfMeshVertices, &AbstractDataArray::modified,
62 std::static_pointer_cast<VTKSurfaceNormalRenderDelegate>(shared_from_this()),
67 vtkNew<vtkArrowSource> arrowSource;
68 arrowSource->Update();
69 m_glyphPolyData = arrowSource->GetOutput();
70 vtkNew<vtkOpenGLGlyph3DMapper> mapper;
72 mapper->SetInputData(m_polydata);
73 mapper->SetSourceData(m_glyphPolyData);
74 mapper->SetOrientationArray(m_mappedNormalsArray->GetName());
76 mapper->SetScaleFactor(
m_visualModel->getRenderMaterial()->getPointSize());
78 vtkNew<vtkActor> actor;
79 actor->SetMapper(mapper);
80 actor->SetUserTransform(m_transform);
97 std::list<Command> cmds;
98 bool contains[4] = {
false,
false,
false,
false };
101 if (cmd.m_event->m_sender ==
m_visualModel.get() && !contains[0])
106 else if (cmd.m_event->m_sender == m_material.get() && !contains[1])
111 else if (cmd.m_event->m_sender == geom.get() && !contains[2])
116 else if (cmd.m_event->m_sender == vertices.get() && !contains[3])
124 for (std::list<Command>::reverse_iterator i = cmds.rbegin(); i != cmds.rend(); i++)
137 m_triangleCenterVertices = computeTriangleCenters(m_surfMeshVertices, m_surfMeshIndices);
138 m_triangleNormals = computeTriangleNormals(m_surfMeshVertices, m_surfMeshIndices);
141 m_mappedVertexArray->SetVoidArray(reinterpret_cast<double*>(m_triangleCenterVertices->getPointer()), m_triangleCenterVertices->size() * 3, 1);
144 m_mappedNormalsArray->SetNumberOfComponents(3);
145 m_mappedNormalsArray->SetVoidArray(reinterpret_cast<double*>(m_triangleNormals->getPointer()), m_triangleNormals->size() * 3, 1);
146 m_mappedNormalsArray->Modified();
167 vtkOpenGLGlyph3DMapper::SafeDownCast(m_mapper)->SetScaleFactor(
m_visualModel->getRenderMaterial()->getPointSize());
170 std::shared_ptr<VecDataArray<double, 3>>
175 auto newVerticesPtr = std::make_shared<VecDataArray<double, 3>>(indicesPtr->size());
180 const double ratio = 1.0 / 3.0;
181 for (
int i = 0; i < indices.size(); i++)
183 const Vec3d& a = vertices[indices[i][0]];
184 const Vec3d& b = vertices[indices[i][1]];
185 const Vec3d& c = vertices[indices[i][2]];
187 newVertices[i] = (a + b + c) * ratio;
189 return newVerticesPtr;
192 std::shared_ptr<VecDataArray<double, 3>>
193 VTKSurfaceNormalRenderDelegate::computeTriangleNormals(
197 auto orientationsPtr = std::make_shared<VecDataArray<double, 3>>(indicesPtr->size());
202 for (
int i = 0; i < indices.size(); i++)
204 const Vec3d& a = vertices[indices[i][0]];
205 const Vec3d& b = vertices[indices[i][1]];
206 const Vec3d& c = vertices[indices[i][2]];
208 orientations[i] = (c - a).cross(c - b).normalized();
210 return orientationsPtr;
void rforeachEvent(std::function< void(Command cmd)> func)
thread safe reverse loop over all event commands, one can implement a custom handler ...
void update()
Update render delegate.
Base class for all geometries represented by discrete points and elements The pointsets follow a pipe...
vtkSmartPointer< vtkDataArray > coupleVtkDataArray(std::shared_ptr< AbstractDataArray > imstkArray)
Coupling functions, these create vtk data objects that point to our data objects thus no copying is d...
std::shared_ptr< VisualModel > m_visualModel
imstk visual model (contains data (geometry) and render specification (render material)) ...
Base class for events which contain a type, priority, and data priority defaults to 0 and uses a grea...
void vertexDataModified(Event *e)
Callback for when vertex data changes.
void processEvents() override
Update polydata source based on the mesh geometry.
std::shared_ptr< VecDataArray< double, 3 > > computeTriangleCenters(std::shared_ptr< VecDataArray< double, 3 >> verticesPtr, std::shared_ptr< VecDataArray< int, 3 >> indicesPtr)
Computes triangle centers from the current geometry.
void updateRenderProperties() override
Updates the actor and mapper properties from the currently set VisualModel.
std::shared_ptr< VecDataArray< double, 3 > > getVertexPositions(DataType type=DataType::PostTransform) const
Returns the vector of current positions of the mesh vertices.
Represents a set of triangles & vertices via an array of Vec3d double vertices & Vec3i integer indice...
void updateRenderProperties() override
Updates the actor and mapper properties from the currently set VisualModel.
void vertexDataModified(Event *e)
Callback for when vertex values are modified.
void geometryModified(Event *e)
Callback for when geometry changes.
vtkSmartPointer< vtkDoubleArray > m_mappedVertexArray
Mapped array of vertices.
Stores everything needed to invoke an event A call may not be present, in which case invoke doesn't d...