9 #include "visuVTKAdaptor/SMeshesBoxWidget.hpp" 11 #include <fwCom/Slot.hpp> 12 #include <fwCom/Slot.hxx> 13 #include <fwCom/Slots.hpp> 14 #include <fwCom/Slots.hxx> 16 #include <fwData/Mesh.hpp> 18 #include <fwServices/macros.hpp> 20 #include <fwVtkIO/helper/Mesh.hpp> 21 #include <fwVtkIO/vtk.hpp> 24 #include <vtkAssembly.h> 25 #include <vtkBoxRepresentation.h> 26 #include <vtkBoxWidget2.h> 27 #include <vtkCommand.h> 28 #include <vtkPolyData.h> 29 #include <vtkPolyDataMapper.h> 30 #include <vtkProp3DCollection.h> 31 #include <vtkTransform.h> 44 cb->m_adaptor = adaptor;
58 virtual void Execute( ::vtkObject* pCaller,
unsigned long,
void* )
70 static const ::fwServices::IService::KeyType s_COMPOSITE_INPUT =
"composite";
75 static const ::fwCom::Slots::SlotKeyType s_UPDATE_MATRICES_SLOT =
"updateMatrices";
76 static const ::fwCom::Slots::SlotKeyType s_ADD_OBJECTS_SLOT =
"addObject";
77 static const ::fwCom::Slots::SlotKeyType s_CHANGE_OBJECTS_SLOT =
"changeObject";
78 static const ::fwCom::Slots::SlotKeyType s_REMOVE_OBJECTS_SLOT =
"removeObjects";
82 SMeshesBoxWidget::SMeshesBoxWidget() noexcept :
84 m_boxWidgetCommand(MeshesBoxClallback::New(
this)),
85 m_vtkBoxWidget(
nullptr)
87 newSlot(s_UPDATE_MATRICES_SLOT, &SMeshesBoxWidget::updateMatrices,
this);
88 newSlot(s_ADD_OBJECTS_SLOT, &SMeshesBoxWidget::addObjects,
this);
89 newSlot(s_CHANGE_OBJECTS_SLOT, &SMeshesBoxWidget::changeObjects,
this);
90 newSlot(s_REMOVE_OBJECTS_SLOT, &SMeshesBoxWidget::removeObjects,
this);
95 SMeshesBoxWidget::~SMeshesBoxWidget() noexcept
101 void SMeshesBoxWidget::configuring()
103 this->configureParams();
108 void SMeshesBoxWidget::starting()
112 ::fwData::Composite::csptr composite = this->getInput< ::fwData::Composite >(s_COMPOSITE_INPUT);
115 m_assembly = vtkAssembly::New();
117 vtkBoxRepresentation* boxRep = vtkBoxRepresentation::New();
118 boxRep->SetPlaceFactor(1.0);
120 m_vtkBoxWidget = vtkBoxWidget2::New();
121 m_vtkBoxWidget->SetInteractor( this->getInteractor() );
122 m_vtkBoxWidget->SetRepresentation( boxRep );
124 m_vtkBoxWidget->AddObserver( ::vtkCommand::InteractionEvent, m_boxWidgetCommand );
126 this->updateMeshMapFromComposite(composite->getContainer());
132 void SMeshesBoxWidget::updating()
134 m_assembly->GetParts()->RemoveAllItems();
135 if (!m_meshMap.empty())
137 for(MeshMapType::value_type elt : m_meshMap)
139 m_assembly->AddPart( elt.second );
141 vtkBoxRepresentation* boxRep = vtkBoxRepresentation::SafeDownCast( m_vtkBoxWidget->GetRepresentation() );
142 boxRep->PlaceWidget(m_assembly->GetBounds());
143 m_vtkBoxWidget->On();
147 m_vtkBoxWidget->Off();
149 this->setVtkPipelineModified();
150 this->requestRender();
155 void SMeshesBoxWidget::stopping()
157 ::fwData::Composite::csptr composite = this->getInput< ::fwData::Composite >(s_COMPOSITE_INPUT);
162 ::fwData::Mesh::sptr mesh = ::fwData::Mesh::dynamicCast(elt.second);
163 ::fwData::TransformationMatrix3D::sptr fieldTransform;
165 m_connections[elt.first].disconnect();
166 m_connections.erase(elt.first);
170 m_assembly->Delete();
171 m_assembly =
nullptr;
173 m_vtkBoxWidget->Off();
174 m_vtkBoxWidget->RemoveObserver( m_boxWidgetCommand );
175 m_vtkBoxWidget->Delete();
176 m_vtkBoxWidget =
nullptr;
177 this->requestRender();
182 void SMeshesBoxWidget::updateFromVtk()
184 m_vtkBoxWidget->RemoveObserver( m_boxWidgetCommand );
186 ::fwData::Composite::csptr composite = this->getInput< ::fwData::Composite >(s_COMPOSITE_INPUT);
189 vtkBoxRepresentation* boxRep = vtkBoxRepresentation::SafeDownCast( m_vtkBoxWidget->GetRepresentation() );
190 vtkTransform* boxTransform = vtkTransform::New();
191 boxRep->GetTransform(boxTransform);
193 for(const ::fwData::Composite::value_type& elt : composite->getContainer())
195 ::fwData::Mesh::sptr mesh = ::fwData::Mesh::dynamicCast(elt.second);
196 ::fwData::TransformationMatrix3D::sptr fieldTransform;
197 SLM_ASSERT(
"Mesh must have a TransformMatrix field", mesh->getField(
"TransformMatrix"));
200 vtkTransform* transform = vtkTransform::New();
201 vtkLinearTransform* meshTransform = m_meshMap[elt.first]->GetUserTransform();
202 transform->Concatenate(boxTransform);
203 transform->Concatenate(meshTransform);
205 vtkMatrix4x4* mat = transform->GetMatrix();
206 for(
int lt = 0; lt < 4; lt++)
208 for(
int ct = 0; ct < 4; ct++)
210 fieldTransform->setCoefficient(static_cast<size_t>(lt), static_cast<size_t>(ct),
211 mat->GetElement(lt, ct));
221 m_vtkBoxWidget->AddObserver( ::vtkCommand::InteractionEvent, m_boxWidgetCommand );
222 boxTransform->Delete();
227 void SMeshesBoxWidget::updateMeshMapFromComposite(::fwData::Composite::ContainerType objects)
229 for(const ::fwData::Composite::value_type& elt : objects)
231 ::fwData::Mesh::sptr mesh = ::fwData::Mesh::dynamicCast(elt.second);
232 SLM_ASSERT(
"Composite must only contain meshes", mesh);
234 vtkSmartPointer<vtkPolyData> vtkMesh = vtkSmartPointer<vtkPolyData>::New();
237 ::fwData::TransformationMatrix3D::sptr fieldTransform;
238 fieldTransform = mesh->setDefaultField(
"TransformMatrix", ::fwData::TransformationMatrix3D::New());
240 vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
241 transform->Identity();
243 vtkSmartPointer<vtkMatrix4x4> matrix = vtkSmartPointer<vtkMatrix4x4>::New();
245 for(
int lt = 0; lt < 4; lt++)
247 for(
int ct = 0; ct < 4; ct++)
249 matrix->SetElement(lt, ct,
250 fieldTransform->getCoefficient(static_cast<size_t>(lt), static_cast<size_t>(ct)));
254 transform->SetMatrix(matrix);
255 vtkSmartPointer<vtkPolyDataMapper> meshMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
256 meshMapper->SetInputData(vtkMesh);
258 vtkActor* meshActor = vtkActor::New();
259 meshActor->SetMapper(meshMapper);
260 meshActor->SetUserTransform(transform);
262 if (m_meshMap.find(elt.first) == m_meshMap.end())
265 connect(this->slot(s_UPDATE_MATRICES_SLOT));
266 m_connections[elt.first] = connection;
269 m_meshMap[elt.first] = meshActor;
275 void SMeshesBoxWidget::updateMeshTransform()
277 ::fwData::Composite::csptr composite = this->getInput< ::fwData::Composite >(s_COMPOSITE_INPUT);
280 for(const ::fwData::Composite::value_type& elt : composite->getContainer())
282 ::fwData::Mesh::sptr mesh = ::fwData::Mesh::dynamicCast(elt.second);
284 ::fwData::TransformationMatrix3D::sptr fieldTransform;
285 SLM_ASSERT(
"Triangular mesh must have a TransformMatrix field", mesh->getField(
"TransformMatrix"));
288 vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
289 transform->Identity();
291 vtkSmartPointer<vtkMatrix4x4> matrix = vtkSmartPointer<vtkMatrix4x4>::New();
293 for(
int lt = 0; lt < 4; lt++)
295 for(
int ct = 0; ct < 4; ct++)
297 matrix->SetElement(lt, ct,
298 fieldTransform->getCoefficient(static_cast<size_t>(lt), static_cast<size_t>(ct)));
302 transform->SetMatrix(matrix);
303 vtkActor* meshActor = m_meshMap[elt.first];
304 meshActor->SetUserTransform(transform);
310 void SMeshesBoxWidget::updateMatrices()
312 this->updateMeshTransform();
318 void SMeshesBoxWidget::addObjects(::fwData::Composite::ContainerType objects)
320 this->updateMeshMapFromComposite(objects);
321 this->updateMeshTransform();
327 void SMeshesBoxWidget::changeObjects(::fwData::Composite::ContainerType newObjects,
328 ::fwData::Composite::ContainerType )
330 this->updateMeshMapFromComposite(newObjects);
331 this->updateMeshTransform();
337 void SMeshesBoxWidget::removeObjects(::fwData::Composite::ContainerType objects)
339 for(const ::fwData::Composite::value_type& elt : objects)
341 ::fwData::Mesh::sptr mesh = ::fwData::Mesh::dynamicCast(elt.second);
342 m_meshMap[elt.first]->Delete();
343 m_meshMap.erase(elt.first);
345 ::fwData::TransformationMatrix3D::sptr fieldTransform;
347 m_connections[elt.first].disconnect();
348 m_connections.erase(elt.first);
351 this->updateMeshTransform();
This class is a helper to define the connections of a service and its data.
The namespace visuVTKAdaptor contains the list of adaptors available for the generic scene...
static FWVTKIO_API void toVTKMesh(const ::fwData::Mesh::csptr &_mesh, vtkSmartPointer< vtkPolyData > _polyData)
Convert a ::fwData::Mesh::csptr to a vtkPolyData.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_CHANGED_OBJECTS_SIG
Type of signal when objects are added.
ContainerType::value_type value_type
Class managing Signal-Slot connections.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_REMOVED_OBJECTS_SIG
Type of signal when objects are added.
#define SLM_ASSERT(message, cond)
work like 'assert' from 'cassert', with in addition a message logged by spylog (with FATAL loglevel) ...
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_ADDED_OBJECTS_SIG
Type of signal when objects are added.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_MODIFIED_SIG
Key in m_signals map of signal m_sigModified.
Base class for VTK adaptors.