7 #include "imstkVTKLineMeshRenderDelegate.h" 8 #include "imstkLineMesh.h" 9 #include "imstkVisualModel.h" 10 #include "imstkRenderMaterial.h" 11 #include "imstkGeometryUtilities.h" 14 #include <vtkCellData.h> 15 #include <vtkDoubleArray.h> 16 #include <vtkLineSource.h> 17 #include <vtkOpenGLPolyDataMapper.h> 18 #include <vtkOpenGLVertexBufferObject.h> 19 #include <vtkPointData.h> 20 #include <vtkTransform.h> 24 VTKLineMeshRenderDelegate::VTKLineMeshRenderDelegate() :
25 m_polydata(vtkSmartPointer<vtkPolyData>::New()),
26 m_mappedVertexArray(vtkSmartPointer<vtkDoubleArray>::New())
31 VTKLineMeshRenderDelegate::init()
33 m_geometry = std::dynamic_pointer_cast<LineMesh>(
m_visualModel->getGeometry());
34 CHECK(m_geometry !=
nullptr) <<
"VTKLineMeshRenderDelegate only works with LineMesh geometry";
37 m_vertices = m_geometry->getVertexPositions();
38 m_indices = m_geometry->getCells();
41 if (m_vertices !=
nullptr)
44 auto points = vtkSmartPointer<vtkPoints>::New();
45 points->SetNumberOfPoints(m_geometry->getNumVertices());
46 points->SetData(m_mappedVertexArray);
47 m_polydata->SetPoints(points);
51 if (m_indices !=
nullptr)
53 m_cellArray = vtkSmartPointer<vtkCellArray>::New();
55 for (
const auto& t : *m_indices)
57 for (
size_t i = 0; i < 2; i++)
61 m_cellArray->InsertNextCell(2, cell);
63 m_polydata->SetLines(m_cellArray);
67 if (m_geometry->getVertexScalars() !=
nullptr)
69 setVertexScalarBuffer(m_geometry->getVertexScalars());
73 if (m_geometry->getCellScalars() !=
nullptr)
75 setCellScalarBuffer(m_geometry->getCellScalars());
79 queueConnect<Event>(m_geometry, &Geometry::modified,
80 std::static_pointer_cast<VTKLineMeshRenderDelegate>(shared_from_this()),
84 queueConnect<Event>(m_geometry->getVertexPositions(), &VecDataArray<double, 3>::modified,
85 std::static_pointer_cast<VTKLineMeshRenderDelegate>(shared_from_this()),
89 queueConnect<Event>(m_geometry->getCells(), &VecDataArray<int, 2>::modified,
90 std::static_pointer_cast<VTKLineMeshRenderDelegate>(shared_from_this()),
91 &VTKLineMeshRenderDelegate::indexDataModified);
95 vtkNew<vtkPolyDataMapper> mapper;
96 mapper->SetInputData(m_polydata);
97 vtkNew<vtkActor> actor;
98 actor->SetMapper(mapper);
99 actor->SetUserTransform(m_transform);
102 if (
auto glMapper = vtkOpenGLPolyDataMapper::SafeDownCast(m_mapper.GetPointer()))
104 glMapper->SetVBOShiftScaleMethod(vtkOpenGLVertexBufferObject::DISABLE_SHIFT_SCALE);
116 std::shared_ptr<VecDataArray<double, 3>> verticesPtr = m_geometry->getVertexPositions();
117 std::shared_ptr<VecDataArray<int, 2>> indicesPtr = m_geometry->getCells();
118 std::shared_ptr<AbstractDataArray> cellScalarsPtr = m_geometry->getCellScalars();
119 std::shared_ptr<AbstractDataArray> vertexScalarsPtr = m_geometry->getVertexScalars();
122 std::array<Command, 7> cmds;
123 std::array<bool, 7> contains = {
false,
false,
false,
false,
false,
false,
false };
126 if (cmd.m_event->m_sender ==
m_visualModel.get() && !contains[0])
131 else if (cmd.m_event->m_sender == m_material.get() && !contains[1])
136 else if (cmd.m_event->m_sender == m_geometry.get() && !contains[2])
141 else if (cmd.m_event->m_sender == verticesPtr.get() && !contains[3])
146 else if (cmd.m_event->m_sender == cellScalarsPtr.get() && !contains[4])
151 else if (cmd.m_event->m_sender == vertexScalarsPtr.get() && !contains[5])
156 else if (cmd.m_event->m_sender == indicesPtr.get() && !contains[6])
176 setVertexBuffer(m_geometry->getVertexPositions());
180 VTKLineMeshRenderDelegate::indexDataModified(
Event* imstkNotUsed(e))
182 setIndexBuffer(m_geometry->getCells());
186 VTKLineMeshRenderDelegate::vertexScalarsModified(
Event* imstkNotUsed(e))
188 setVertexScalarBuffer(m_geometry->getVertexScalars());
192 VTKLineMeshRenderDelegate::cellScalarsModified(
Event* imstkNotUsed(e))
194 setCellScalarBuffer(m_geometry->getCellScalars());
201 if (m_vertices != m_geometry->getVertexPositions())
203 setVertexBuffer(m_geometry->getVertexPositions());
207 m_mappedVertexArray->Modified();
210 if (m_indices != m_geometry->getCells())
212 setIndexBuffer(m_geometry->getCells());
214 if (m_vertexScalars != m_geometry->getVertexScalars())
216 setVertexScalarBuffer(m_geometry->getVertexScalars());
218 if (m_cellScalars != m_geometry->getCellScalars())
220 setCellScalarBuffer(m_geometry->getCellScalars());
228 if (m_vertices != vertices)
231 if (m_vertices !=
nullptr)
235 std::static_pointer_cast<VTKLineMeshRenderDelegate>(shared_from_this()),
239 m_vertices = vertices;
246 m_mappedVertexArray->SetNumberOfComponents(3);
247 m_mappedVertexArray->SetArray(reinterpret_cast<double*>(m_vertices->getPointer()), m_vertices->size() * 3, 1);
248 m_mappedVertexArray->Modified();
249 m_polydata->GetPoints()->SetNumberOfPoints(m_vertices->size());
256 if (m_indices != indices)
259 if (m_indices !=
nullptr)
263 std::static_pointer_cast<VTKLineMeshRenderDelegate>(shared_from_this()),
270 &VTKLineMeshRenderDelegate::indexDataModified);
275 m_cellArray->Reset();
277 for (
const auto& t : *m_indices)
279 for (
size_t i = 0; i < 2; i++)
283 m_cellArray->InsertNextCell(2, cell);
285 m_cellArray->Modified();
289 VTKLineMeshRenderDelegate::setVertexScalarBuffer(std::shared_ptr<AbstractDataArray> scalars)
292 if (m_vertexScalars != scalars)
295 if (m_vertexScalars !=
nullptr)
299 std::static_pointer_cast<VTKLineMeshRenderDelegate>(shared_from_this()),
300 &AbstractDataArray::modified);
303 m_vertexScalars = scalars;
304 queueConnect<Event>(m_vertexScalars, &AbstractDataArray::modified,
306 &VTKLineMeshRenderDelegate::vertexScalarsModified);
308 m_polydata->GetPointData()->SetScalars(m_mappedVertexScalarArray);
310 m_mappedVertexScalarArray->SetNumberOfComponents(m_vertexScalars->getNumberOfComponents());
311 m_mappedVertexScalarArray->SetVoidArray(m_vertexScalars->getVoidPointer(),
312 static_cast<vtkIdType
>(m_vertexScalars->size()), 1);
313 m_mappedVertexScalarArray->Modified();
317 VTKLineMeshRenderDelegate::setCellScalarBuffer(std::shared_ptr<AbstractDataArray> scalars)
320 if (m_cellScalars != scalars)
323 if (m_cellScalars !=
nullptr)
327 std::static_pointer_cast<VTKLineMeshRenderDelegate>(shared_from_this()),
328 &AbstractDataArray::modified);
331 m_cellScalars = scalars;
332 queueConnect<Event>(m_cellScalars, &AbstractDataArray::modified,
334 &VTKLineMeshRenderDelegate::cellScalarsModified);
336 m_polydata->GetCellData()->SetScalars(m_mappedCellScalarArray);
339 m_mappedCellScalarArray->SetNumberOfComponents(m_cellScalars->getNumberOfComponents());
340 m_mappedCellScalarArray->SetVoidArray(m_cellScalars->getVoidPointer(),
341 static_cast<vtkIdType
>(m_cellScalars->size()), 1);
342 m_mappedCellScalarArray->Modified();
Delegates rendering of LineMesh to VTK from VisualModel.
void rforeachEvent(std::function< void(Command cmd)> func)
thread safe reverse loop over all event commands, one can implement a custom handler ...
void geometryModified(Event *e)
Callback when geometry changes.
void update()
Update render delegate.
friend void disconnect(std::shared_ptr< EventObject >, std::shared_ptr< EventObject >, std::string(*)())
Remove an observer from the sender.
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 processEvents() override
Event handler.
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.
Stores everything needed to invoke an event A call may not be present, in which case invoke doesn't d...