7 #include "vtkSimpleMesh/SRenderer.hpp" 9 #include <fwCom/Signal.hxx> 10 #include <fwCom/Signals.hpp> 11 #include <fwCom/Slots.hpp> 12 #include <fwCom/Slots.hxx> 14 #include <fwCore/HiResTimer.hpp> 16 #include <fwData/Mesh.hpp> 17 #include <fwData/mt/ObjectReadLock.hpp> 19 #include <fwServices/macros.hpp> 20 #include <fwServices/registry/ActiveWorkers.hpp> 22 #include <fwVtkIO/helper/Mesh.hpp> 23 #include <fwVtkIO/vtk.hpp> 25 #include <vtkCamera.h> 26 #include <vtkCommand.h> 28 #include <vtkInteractorStyleTrackballCamera.h> 30 #include <vtkInteractorStyleMultiTouchCamera.h> 32 #include <vtkMatrix4x4.h> 33 #include <vtkPolyData.h> 34 #include <vtkPolyDataMapper.h> 35 #include <vtkPolyDataNormals.h> 36 #include <vtkProperty.h> 37 #include <vtkRenderWindow.h> 38 #include <vtkRenderer.h> 39 #include <vtkTransform.h> 48 const ::fwCom::Slots::SlotKeyType SRenderer::s_UPDATE_CAM_POSITION_SLOT =
"updateCamPosition";
49 const ::fwCom::Slots::SlotKeyType SRenderer::s_UPDATE_PIPELINE_SLOT =
"updatePipeline";
50 const ::fwCom::Slots::SlotKeyType SRenderer::s_INIT_PIPELINE_SLOT =
"initPipeline";
51 const ::fwCom::Signals::SignalKeyType SRenderer::s_CAM_UPDATED_SIG =
"camUpdated";
53 static const std::string s_MESH_KEY =
"mesh";
65 this->m_isMousePressed =
false;
69 void Execute(vtkObject* _caller,
unsigned long _event,
void* _obj)
71 if (_event == vtkCommand::StartInteractionEvent )
73 this->m_isMousePressed =
true;
75 else if (_event == vtkCommand::EndInteractionEvent )
77 this->m_isMousePressed =
false;
79 else if ( (_event == vtkCommand::ModifiedEvent && this->m_isMousePressed)
80 || _event == vtkCommand::MouseWheelBackwardEvent || _event == vtkCommand::MouseWheelForwardEvent)
83 ::fwThread::Worker::sptr worker = m_service->
getWorker();
84 worker->processTasks();
89 bool m_isMousePressed;
96 m_bPipelineIsInit(false)
98 newSlot(s_UPDATE_CAM_POSITION_SLOT, &SRenderer::updateCamPosition,
this);
99 newSlot(s_UPDATE_PIPELINE_SLOT, &SRenderer::updatePipeline,
this);
100 newSlot(s_INIT_PIPELINE_SLOT, &SRenderer::initPipeline,
this);
102 m_sigCamUpdated = newSignal<CamUpdatedSignalType>(s_CAM_UPDATED_SIG);
117 m_interactorManager = ::fwRenderVTK::IVtkRenderWindowInteractorManager::createManager();
119 m_interactorManager->installInteractor( this->getContainer() );
121 m_bPipelineIsInit =
false;
124 m_render = vtkRenderer::New();
125 m_interactorManager->getInteractor()->GetRenderWindow()->AddRenderer(m_render);
129 ::fwData::Mesh::csptr mesh = this->getInput< ::fwData::Mesh >(s_MESH_KEY);
130 SLM_ASSERT(
"'" + s_MESH_KEY +
"' key not found", mesh);
132 meshIsLoaded = mesh->getNumberOfPoints() > 0;
137 this->initVTKPipeline();
138 m_bPipelineIsInit =
true;
158 m_interactorManager->getInteractor()->RemoveObserver(m_loc);
160 m_interactorManager->uninstallInteractor();
161 m_interactorManager.reset();
163 SLM_ASSERT(
"m_render not instanced", m_render);
174 m_interactorManager->getInteractor()->Render();
179 void SRenderer::initVTKPipeline()
181 ::fwData::Mesh::csptr mesh = this->getInput< ::fwData::Mesh >(s_MESH_KEY);
182 SLM_ASSERT(
"'" + s_MESH_KEY +
"' key not found", mesh);
183 m_vtkPolyData = vtkSmartPointer<vtkPolyData>::New();
190 m_mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
191 m_mapper->SetInputData(m_vtkPolyData);
193 auto actor = vtkSmartPointer<vtkActor>::New();
194 actor->SetMapper(m_mapper);
197 m_render->AddActor( actor);
199 m_interactorManager->getInteractor()->SetInteractorStyle(vtkInteractorStyleTrackballCamera::New());
201 m_interactorManager->getInteractor()->SetInteractorStyle(vtkInteractorStyleMultiTouchCamera::New());
205 m_interactorManager->getInteractor()->AddObserver(vtkCommand::AnyEvent, m_loc);
208 m_render->ResetCamera();
213 void SRenderer::updateVTKPipeline(
bool resetCamera)
215 ::fwData::Mesh::csptr mesh = this->getInput< ::fwData::Mesh >(s_MESH_KEY);
216 SLM_ASSERT(
"'" + s_MESH_KEY +
"' key not found", mesh);
228 m_render->ResetCamera();
237 vtkCamera* camera = m_render->GetActiveCamera();
239 SharedArray position = SharedArray(
new double[3]);
240 SharedArray focal = SharedArray(
new double[3]);
241 SharedArray viewUp = SharedArray(
new double[3]);
243 std::copy(camera->GetPosition(), camera->GetPosition()+3, position.get());
244 std::copy(camera->GetFocalPoint(), camera->GetFocalPoint()+3, focal.get());
245 std::copy(camera->GetViewUp(), camera->GetViewUp()+3, viewUp.get());
249 m_sigCamUpdated->asyncEmit(position, focal, viewUp);
255 void SRenderer::updateCamPosition(SharedArray positionValue, SharedArray focalValue, SharedArray viewUpValue)
257 vtkCamera* camera = m_render->GetActiveCamera();
259 camera->SetPosition(positionValue.get());
260 camera->SetFocalPoint(focalValue.get());
261 camera->SetViewUp(viewUpValue.get());
262 camera->SetClippingRange(0.1, 1000000);
264 m_interactorManager->getInteractor()->Render();
269 void SRenderer::initPipeline()
271 if(!m_bPipelineIsInit)
273 this->initVTKPipeline();
274 m_bPipelineIsInit =
true;
278 m_vtkPolyData = vtkSmartPointer<vtkPolyData>::New();
279 ::fwData::Mesh::csptr mesh = this->getInput< ::fwData::Mesh >(s_MESH_KEY);
280 SLM_ASSERT(
"'" + s_MESH_KEY +
"' key not found", mesh);
285 m_mapper->SetInputData(m_vtkPolyData);
287 m_interactorManager->getInteractor()->Render();
292 void SRenderer::updatePipeline()
294 m_hiResTimer.reset();
295 m_hiResTimer.start();
296 this->updateVTKPipeline(
false);
298 OSLM_INFO(
"Vertex updating time (milli sec) = " << m_hiResTimer.getElapsedTimeInMilliSec());
300 m_hiResTimer.reset();
301 m_hiResTimer.start();
302 m_interactorManager->getInteractor()->Render();
304 OSLM_INFO(
"Render time (milli sec) = " << m_hiResTimer.getElapsedTimeInMilliSec());
static FWVTKIO_API void updatePolyDataPointColor(vtkSmartPointer< vtkPolyData > polyDataDst, const ::fwData::Mesh::csptr &meshSrc)
Update a vtkPolyData with point color of fwData::Mesh.
Service rendering a fwData::Mesh using VTK.
This class is a helper to define the connections of a service and its data.
void notifyCamPositionUpdated()
This method is used to notify that the VTK camera position is updated.
virtual VTKSIMPLEMESH_API void updating() override
Updating method.
Class allowing to block a Connection.
static FWVTKIO_API void toVTKMesh(const ::fwData::Mesh::csptr &_mesh, vtkSmartPointer< vtkPolyData > _polyData)
Convert a ::fwData::Mesh::csptr to a vtkPolyData.
virtual VTKSIMPLEMESH_API ~SRenderer() noexcept
Destructor.
A helper to lock object on read mode.
static FWVTKIO_API void updatePolyDataPoints(vtkSmartPointer< vtkPolyData > polyDataDst, const ::fwData::Mesh::csptr &meshSrc)
Update a vtkPolyData with ::fwData::Mesh::sptr points.
#define OSLM_INFO(message)
virtual VTKSIMPLEMESH_API void configuring() override
This method is used to configure the service. Initialize the qt container.
Defines the service interface managing the rendering service for object.
virtual VTKSIMPLEMESH_API void stopping() override
Stopping method.
#define SLM_ASSERT(message, cond)
work like 'assert' from 'cassert', with in addition a message logged by spylog (with FATAL loglevel) ...
static FWVTKIO_API void updatePolyDataCellNormals(vtkSmartPointer< vtkPolyData > polyDataDst, const ::fwData::Mesh::csptr &meshSrc)
Update a vtkPolyData with cell normals of fwData::Mesh.
The namespace vtkSimpleMesh contains a service which renders one mesh (fwData::Mesh).
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_VERTEX_MODIFIED_SIG
Key in m_signals map of signal m_sigVertexModified.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_MODIFIED_SIG
Key in m_signals map of signal m_sigModified.
virtual VTKSIMPLEMESH_API void starting() override
Starting method.
static FWVTKIO_API void updatePolyDataPointNormals(vtkSmartPointer< vtkPolyData > polyDataDst, const ::fwData::Mesh::csptr &meshSrc)
Update a vtkPolyData with point normals of fwData::Mesh.
VTKSIMPLEMESH_API SRenderer() noexcept
Constructor.
Data holding a geometric structure composed of points, lines, triangles, quads or polygons...
virtual VTKSIMPLEMESH_API KeyConnectionsMap getAutoConnections() const override
Returns proposals to connect service slots to associated object signals, this method is used for obj/...
FWSERVICES_API std::shared_ptr< ::fwThread::Worker > getWorker() const
Returns associate worker.