7 #include "visuVTKAdaptor/SLandmarks.hpp" 9 #include <fwCom/Signal.hpp> 10 #include <fwCom/Signal.hxx> 11 #include <fwCom/Signals.hpp> 12 #include <fwCom/Slot.hpp> 13 #include <fwCom/Slot.hxx> 14 #include <fwCom/Slots.hpp> 15 #include <fwCom/Slots.hxx> 17 #include <fwData/Boolean.hpp> 18 #include <fwData/Image.hpp> 19 #include <fwData/Landmarks.hpp> 20 #include <fwData/Material.hpp> 21 #include <fwData/Point.hpp> 22 #include <fwData/PointList.hpp> 24 #include <fwDataTools/fieldHelper/Image.hpp> 26 #include <fwRenderVTK/vtk/fwHandleRepresentation3D.hpp> 27 #include <fwRenderVTK/vtk/Helpers.hpp> 28 #include <fwRenderVTK/vtk/MarkedSphereHandleRepresentation.hpp> 30 #include <fwServices/macros.hpp> 31 #include <fwServices/op/Add.hpp> 34 #include <vtkAssemblyNode.h> 35 #include <vtkAssemblyPath.h> 36 #include <vtkCellPicker.h> 37 #include <vtkCommand.h> 38 #include <vtkCubeSource.h> 39 #include <vtkPolyDataMapper.h> 40 #include <vtkProperty.h> 41 #include <vtkRenderer.h> 42 #include <vtkRenderWindowInteractor.h> 43 #include <vtkTextActor.h> 44 #include <vtkTextMapper.h> 45 #include <vtkTextProperty.h> 54 static const ::fwCom::Slots::SlotKeyType s_ADD_POINT_SLOT =
"addPoint";
55 static const ::fwCom::Slots::SlotKeyType s_INSERT_POINT_SLOT =
"insertPoint";
56 static const ::fwCom::Slots::SlotKeyType s_REMOVE_POINT_SLOT =
"removePoint";
57 static const ::fwCom::Slots::SlotKeyType s_ADD_GROUP_SLOT =
"addGroup";
58 static const ::fwCom::Slots::SlotKeyType s_REMOVE_GROUP_SLOT =
"removeGroup";
59 static const ::fwCom::Slots::SlotKeyType s_MODIFY_GROUP_SLOT =
"modifyGroup";
60 static const ::fwCom::Slots::SlotKeyType s_MODIFY_POINT_SLOT =
"modifyPoint";
61 static const ::fwCom::Slots::SlotKeyType s_RENAME_GROUP_SLOT =
"renameGroup";
62 static const ::fwCom::Slots::SlotKeyType s_SELECT_POINT_SLOT =
"selectPoint";
63 static const ::fwCom::Slots::SlotKeyType s_DESELECT_POINT_SLOT =
"deselectPoint";
64 static const ::fwCom::Slots::SlotKeyType s_SHOW_SLOT =
"show";
66 const ::fwServices::IService::KeyType s_LANDMARKS_INOUT =
"landmarks";
78 const ::fwCom::SlotBase::sptr& pointModifiedSlot,
79 const std::string& groupName,
81 vtkAbstractPropPicker* picker,
82 vtkRenderer* renderer,
83 vtkActor2D* labelActor)
92 const ::fwCom::SlotBase::sptr& pointModifiedSlot,
93 const std::string& groupName,
95 vtkAbstractPropPicker* picker,
96 vtkRenderer* renderer,
97 vtkActor2D* labelActor) :
98 m_landmarks(landmarks),
99 m_pointModifiedSlot(pointModifiedSlot),
100 m_groupName(groupName),
101 m_pointIndex(pointIndex),
103 m_renderer(renderer),
104 m_labelActor(labelActor)
110 void updateInfo(
const std::string& groupName,
size_t pointIndex)
112 m_groupName = groupName;
113 m_pointIndex = pointIndex;
118 virtual void Execute( vtkObject* caller,
unsigned long eventId,
void*)
120 vtkHandleWidget* handler = vtkHandleWidget::SafeDownCast(caller);
126 if ( eventId == vtkCommand::StartInteractionEvent)
128 handler->AddObserver(vtkCommand::EndInteractionEvent,
this );
129 handler->AddObserver(vtkCommand::InteractionEvent,
this );
132 else if ( eventId == vtkCommand::EndInteractionEvent )
134 handler->RemoveObservers(vtkCommand::EndInteractionEvent,
this );
135 handler->RemoveObservers(vtkCommand::InteractionEvent,
this );
138 vtkHandleRepresentation* representation = handler->GetHandleRepresentation();
140 double* world = representation->GetWorldPosition();
142 if ( eventId == vtkCommand::InteractionEvent)
146 handler->GetInteractor()->GetLastEventPosition(x, y);
151 if ( m_picker && m_picker->Pick( display, m_renderer ) )
153 ::fwRenderVTK::vtk::getNearestPickedPosition(m_picker, m_renderer, world);
156 auto&
point = m_landmarks->getPoint(m_groupName, m_pointIndex);
157 std::copy( world, world+3,
point.begin() );
159 representation->SetWorldPosition(world);
160 m_labelActor->GetPositionCoordinate()->SetValue(world);
166 sig->asyncEmit(m_groupName, m_pointIndex);
169 else if (eventId == vtkCommand::StartInteractionEvent)
173 sig->asyncEmit(m_groupName, m_pointIndex);
179 ::fwData::Landmarks::sptr m_landmarks;
181 const ::fwCom::SlotBase::sptr m_pointModifiedSlot;
183 std::string m_groupName;
187 vtkAbstractPropPicker* m_picker;
189 vtkRenderer* m_renderer;
191 vtkActor2D* m_labelActor;
216 void setAdaptor(
const SLandmarks::sptr& adaptor)
223 virtual void Execute( vtkObject* ,
unsigned long ,
void*)
225 m_adaptor->deselect();
230 SLandmarks::sptr m_adaptor;
235 SLandmarks::SLandmarks() noexcept :
236 m_noSelectionCommand(
nullptr),
240 this->newSlot(s_ADD_POINT_SLOT, &SLandmarks::addPoint,
this);
241 this->newSlot(s_INSERT_POINT_SLOT, &SLandmarks::insertPoint,
this);
242 this->newSlot(s_REMOVE_POINT_SLOT, &SLandmarks::removePoint,
this);
243 this->newSlot(s_MODIFY_POINT_SLOT, &SLandmarks::modifyPoint,
this);
244 this->newSlot(s_ADD_GROUP_SLOT, &SLandmarks::addGroup,
this);
245 this->newSlot(s_REMOVE_GROUP_SLOT, &SLandmarks::removeGroup,
this);
246 this->newSlot(s_MODIFY_GROUP_SLOT, &SLandmarks::modifyGroup,
this);
247 this->newSlot(s_RENAME_GROUP_SLOT, &SLandmarks::renameGroup,
this);
248 this->newSlot(s_SELECT_POINT_SLOT, &SLandmarks::selectPoint,
this);
249 this->newSlot(s_DESELECT_POINT_SLOT, &SLandmarks::deselectPoint,
this);
250 this->newSlot(s_SHOW_SLOT, &SLandmarks::show,
this);
255 SLandmarks::~SLandmarks() noexcept
263 this->configureParams();
265 const ConfigType config = this->getConfigTree().get_child(
"config.<xmlattr>");
267 const std::string interaction = config.get<std::string>(
"interaction",
"on");
269 SLM_FATAL_IF(
"value for 'interaction' must be 'on' or 'off', actual: " + interaction,
270 interaction !=
"on" && interaction !=
"off");
272 m_interaction = (interaction ==
"on");
282 callback->setAdaptor(this->getSptr());
283 m_noSelectionCommand = callback;
284 this->getInteractor()->AddObserver(vtkCommand::RightButtonPressEvent, m_noSelectionCommand);
285 this->getInteractor()->AddObserver(vtkCommand::RightButtonReleaseEvent, m_noSelectionCommand);
294 this->clearLandmarks();
296 ::fwData::Landmarks::csptr landmarks = this->getInOut< ::fwData::Landmarks >(s_LANDMARKS_INOUT);
297 SLM_ASSERT(
"'landmarks' inout is not defined", landmarks);
299 ::fwData::Landmarks::GroupNameContainer groupNames = landmarks->getGroupNames();
301 for(
auto& name : groupNames)
303 this->addGroup(name);
306 this->getRenderer()->ResetCameraClippingRange();
307 this->setVtkPipelineModified();
308 this->requestRender();
315 this->clearLandmarks();
316 if (m_noSelectionCommand)
318 this->getInteractor()->RemoveObserver(m_noSelectionCommand);
319 m_noSelectionCommand->Delete();
320 m_noSelectionCommand =
nullptr;
322 this->requestRender();
327 void SLandmarks::addPoint(std::string groupName)
329 ::fwData::Landmarks::sptr landmarks = this->getInOut< ::fwData::Landmarks >(s_LANDMARKS_INOUT);
330 SLM_ASSERT(
"'landmarks' inout is not defined", landmarks);
332 for(
size_t i = m_handles[groupName].size(); i < landmarks->getNumberOfPoints(groupName); ++i)
334 auto handle = this->newHandle(landmarks, groupName, i);
335 m_handles[groupName].push_back(handle);
338 this->getRenderer()->ResetCameraClippingRange();
339 this->setVtkPipelineModified();
340 this->requestRender();
345 void SLandmarks::insertPoint(std::string groupName,
size_t index)
347 ::fwData::Landmarks::sptr landmarks = this->getInOut< ::fwData::Landmarks >(s_LANDMARKS_INOUT);
348 SLM_ASSERT(
"'landmarks' inout is not defined", landmarks);
350 auto handle = this->newHandle(landmarks, groupName, index);
352 LandmarksWidgetContainerType& landmarkHandleGroup = m_handles[groupName];
353 landmarkHandleGroup.insert(
354 landmarkHandleGroup.begin() +
static_cast<GroupWidgetsMapType::difference_type
>(index), handle);
356 this->getRenderer()->ResetCameraClippingRange();
357 this->setVtkPipelineModified();
358 this->requestRender();
363 void SLandmarks::removePoint(std::string groupName,
size_t index)
365 if (m_timer && m_selectedPoint.first == groupName && m_selectedPoint.second == index)
370 LandmarksWidgetContainerType& landmarkHandleGroup = m_handles[groupName];
372 auto& handleToRemove = landmarkHandleGroup[index];
374 vtkActor2D* label = m_labels[handleToRemove];
375 this->getRenderer()->RemoveViewProp(label);
378 vtkCommand* command = m_commands[handleToRemove];
379 handleToRemove->RemoveObserver(command);
382 handleToRemove->Off();
383 handleToRemove->SetInteractor(
nullptr);
385 this->m_propCollection->RemoveItem(handleToRemove->GetRepresentation());
387 m_commands.erase(handleToRemove);
388 m_labels.erase(handleToRemove);
389 landmarkHandleGroup.erase(landmarkHandleGroup.begin() +
static_cast<GroupWidgetsMapType::difference_type
>(index));
391 for(
size_t i = index; i < landmarkHandleGroup.size(); ++i)
393 auto& handle = landmarkHandleGroup.at(i);
395 commandToUpdate->updateInfo(groupName, i);
397 vtkActor2D* labelToUpdate = m_labels[handle];
398 vtkSmartPointer<vtkTextMapper> textMapper = vtkTextMapper::SafeDownCast(labelToUpdate->GetMapper());
399 const std::string label = groupName +
"_" + std::to_string(i);
400 textMapper->SetInput(label.c_str());
403 this->setVtkPipelineModified();
404 this->requestRender();
409 void SLandmarks::modifyGroup(std::string groupName)
411 ::fwData::Landmarks::csptr landmarks = this->getInOut< ::fwData::Landmarks >(s_LANDMARKS_INOUT);
412 SLM_ASSERT(
"'landmarks' inout is not defined", landmarks);
414 const ::fwData::Landmarks::LandmarksGroup& group = landmarks->getGroup(groupName);
416 LandmarksWidgetContainerType& landmarkHandleGroup = m_handles[groupName];
418 for(
auto& handle : landmarkHandleGroup)
420 const ::fwData::Landmarks::ColorType& color = group.m_color;
422 vtkSmartPointer< ::fwRenderVTK::vtk::fwHandleRepresentation3D> rep =
423 ::fwRenderVTK::vtk::fwHandleRepresentation3D::SafeDownCast(handle->GetHandleRepresentation());
425 if (group.m_shape == ::fwData::Landmarks::Shape::CUBE)
427 rep->SetShapeRepresentation(::fwRenderVTK::vtk::fwHandleRepresentation3D::CUBE);
431 rep->SetShapeRepresentation(::fwRenderVTK::vtk::fwHandleRepresentation3D::SPHERE);
434 rep->GetSelectedProperty()->SetOpacity(color[3]);
435 rep->GetMarkerProperty()->SetOpacity(color[3]);
436 rep->GetProperty()->SetColor(color[0], color[1], color[2]);
437 rep->GetProperty()->SetOpacity(color[3]);
438 rep->SetHandleSize(group.m_size);
439 rep->SetVisibility(group.m_visibility);
441 vtkActor2D* textActor = m_labels[handle];
442 vtkSmartPointer<vtkTextMapper> textMapper = vtkTextMapper::SafeDownCast(textActor->GetMapper());
443 textMapper->GetTextProperty()->SetColor(color[0], color[1], color[2]);
444 textActor->SetVisibility(group.m_visibility);
447 this->getRenderer()->ResetCameraClippingRange();
448 this->setVtkPipelineModified();
449 this->requestRender();
454 void SLandmarks::removeGroup(std::string groupName)
456 const size_t nbPoints = m_handles[groupName].size();
460 for(
size_t i = nbPoints; i > 0; --i)
462 this->removePoint(groupName, i - 1);
465 m_handles.erase(groupName);
467 this->setVtkPipelineModified();
468 this->requestRender();
473 void SLandmarks::addGroup(std::string groupName)
475 ::fwData::Landmarks::sptr landmarks = this->getInOut< ::fwData::Landmarks >(s_LANDMARKS_INOUT);
476 SLM_ASSERT(
"'landmarks' inout is not defined", landmarks);
478 const size_t ptNumber = landmarks->getNumberOfPoints(groupName);
480 for(
size_t index = 0; index < ptNumber; ++index)
482 auto handle = this->newHandle(landmarks, groupName, index);
483 m_handles[groupName].push_back(handle);
486 this->getRenderer()->ResetCameraClippingRange();
487 this->setVtkPipelineModified();
488 this->requestRender();
493 void SLandmarks::modifyPoint(std::string groupName,
size_t index)
495 ::fwData::Landmarks::sptr landmarks = this->getInOut< ::fwData::Landmarks >(s_LANDMARKS_INOUT);
496 SLM_ASSERT(
"'landmarks' inout is not defined", landmarks);
498 ::fwData::Landmarks::PointType&
point = landmarks->getPoint(groupName, index);
501 vtkHandleRepresentation* handleRep = vtkHandleRepresentation::SafeDownCast(widget->GetRepresentation());
502 handleRep->SetWorldPosition(point.data());
504 vtkActor2D* textActor = m_labels[widget];
505 textActor->GetPositionCoordinate()->SetValue(point.data());
507 this->getRenderer()->ResetCameraClippingRange();
508 this->setVtkPipelineModified();
509 this->requestRender();
514 void SLandmarks::renameGroup(std::string oldName, std::string newName)
516 LandmarksWidgetContainerType& landmarkHandleGroup = m_handles[oldName];
517 m_handles.insert(std::make_pair(newName, landmarkHandleGroup));
520 for(
auto& handle : landmarkHandleGroup)
522 vtkActor2D* textActor = m_labels[handle];
524 vtkCommand* command = m_commands[handle];
526 SLM_ASSERT(
"Missing landmark command", updateCallback);
527 updateCallback->updateInfo(newName, count);
529 vtkSmartPointer<vtkTextMapper> textMapper = vtkTextMapper::SafeDownCast(textActor->GetMapper());
530 const std::string label = newName +
"_" + std::to_string(count);
531 textMapper->SetInput(label.c_str());
535 m_handles.erase(oldName);
537 this->setVtkPipelineModified();
538 this->requestRender();
543 void SLandmarks::selectPoint(std::string groupName,
size_t index)
548 this->deselectPoint(m_selectedPoint.first, m_selectedPoint.second);
551 m_selectedPoint.first = groupName;
552 m_selectedPoint.second = index;
555 m_handles.at(groupName).at(index);
557 vtkSmartPointer< ::fwRenderVTK::vtk::fwHandleRepresentation3D> rep =
558 ::fwRenderVTK::vtk::fwHandleRepresentation3D::SafeDownCast(widget->GetHandleRepresentation());
560 const double* color = rep->GetProperty()->GetColor();
562 m_timer = m_associatedWorker->createTimer();
564 ::fwThread::Timer::TimeDurationType duration = std::chrono::milliseconds(500);
566 const std::array<double, 3> color1 = {{color[0], color[1], color[2]}};
567 const std::array<double, 3> color2 = {{0., 1., 0.}};
570 m_timer->setFunction(std::bind(&SLandmarks::changeColor,
this, rep, color1, color2));
571 m_timer->setDuration(duration);
574 this->setVtkPipelineModified();
575 this->requestRender();
580 void SLandmarks::deselectPoint(std::string groupName,
size_t index)
588 ::fwData::Landmarks::sptr landmarks = this->getInOut< ::fwData::Landmarks >(s_LANDMARKS_INOUT);
589 SLM_ASSERT(
"'landmarks' inout is not defined", landmarks);
593 vtkSmartPointer< ::fwRenderVTK::vtk::fwHandleRepresentation3D> rep =
594 ::fwRenderVTK::vtk::fwHandleRepresentation3D::SafeDownCast(widget->GetHandleRepresentation());
596 ::fwData::Landmarks::ColorType& color = landmarks->getGroup(groupName).m_color;
598 double castedColour[3] = {
static_cast< double >(color[0]),
599 static_cast< double >(color[1]),
600 static_cast< double >(color[2]) };
602 rep->GetProperty()->SetColor(castedColour);
603 this->setVtkPipelineModified();
604 this->requestRender();
613 ::fwData::Landmarks::sptr landmarks = this->getInOut< ::fwData::Landmarks >(s_LANDMARKS_INOUT);
614 SLM_ASSERT(
"'landmarks' inout is not defined", landmarks);
616 this->deselectPoint(m_selectedPoint.first, m_selectedPoint.second);
620 sig->asyncEmit(m_selectedPoint.first, m_selectedPoint.second);
626 void SLandmarks::changeColor(
const vtkSmartPointer< ::fwRenderVTK::vtk::fwHandleRepresentation3D >& rep,
627 const std::array<double, 3>& color1,
const std::array<double, 3>& color2)
629 std::array<double, 3> color;
639 rep->GetProperty()->SetColor(color.data());
642 this->setVtkPipelineModified();
643 this->requestRender();
648 void SLandmarks::clearLandmarks()
650 while (!m_handles.empty())
652 const std::string name = m_handles.begin()->first;
653 this->removeGroup(name);
659 vtkSmartPointer< vtkHandleWidget > SLandmarks::newHandle(const ::fwData::Landmarks::sptr& landmarks,
660 const std::string& groupName,
663 const ::fwData::Landmarks::LandmarksGroup& group = landmarks->getGroup(groupName);
664 ::fwData::Landmarks::PointType&
point = landmarks->getPoint(groupName, pointIndex);
666 vtkSmartPointer< vtkHandleWidget > handle = vtkSmartPointer<vtkHandleWidget>::New();
668 const ::fwData::Landmarks::ColorType& color = group.m_color;
672 ::fwRenderVTK::vtk::fwHandleRepresentation3D::New();
674 if (group.m_shape == ::fwData::Landmarks::Shape::SPHERE)
677 pointRep->SetShapeRepresentation(::fwRenderVTK::vtk::fwHandleRepresentation3D::SPHERE);
681 pointRep->SetShapeRepresentation(::fwRenderVTK::vtk::fwHandleRepresentation3D::CUBE);
683 pointRep->GetSelectedProperty()->SetOpacity(color[3]);
684 pointRep->GetMarkerProperty()->SetOpacity(color[3]);
685 pointRep->GetProperty()->SetColor(color[0], color[1], color[2]);
686 pointRep->GetProperty()->SetOpacity(color[3]);
687 pointRep->SetHandleSize(group.m_size);
688 pointRep->SetVisibility(group.m_visibility);
690 pointRep->SetWorldPosition(point.data());
692 handle->SetRepresentation(pointRep);
693 handle->SetPriority(0.8f);
695 handle->SetInteractor( this->getInteractor() );
696 handle->KeyPressActivationOff();
700 handle->ProcessEventsOff();
701 handle->ManagesCursorOff();
707 this->registerProp(pointRep);
710 const std::string label = groupName +
"_" + std::to_string(pointIndex);
712 vtkActor2D* textActor = vtkActor2D::New();
713 vtkSmartPointer<vtkTextMapper> textMapper = vtkSmartPointer< vtkTextMapper>::New();
714 textMapper->GetTextProperty()->SetFontFamilyToCourier();
715 textMapper->GetTextProperty()->ShadowOn();
716 textMapper->GetTextProperty()->BoldOn();
717 textMapper->GetTextProperty()->SetFontSize(15);
718 textMapper->GetTextProperty()->SetColor(color[0], color[1], color[2]);
719 textMapper->SetInput(label.c_str());
721 textActor->SetMapper(textMapper);
722 textActor->GetPositionCoordinate()->SetCoordinateSystemToWorld();
723 textActor->GetPosition2Coordinate()->SetCoordinateSystemToWorld();
724 textActor->GetPositionCoordinate()->SetValue(point.data());
726 m_labels.insert(std::make_pair(handle, textActor));
728 this->addToRenderer(textActor);
730 const auto& slot = this->slot(s_MODIFY_POINT_SLOT);
733 updateCallback = vtkLandmarkUpdateCallBack::New(landmarks, slot, groupName, pointIndex, this->getPicker(),
734 this->getRenderer(), textActor);
736 m_commands.insert(std::make_pair(handle, updateCallback));
738 handle->AddObserver(vtkCommand::StartInteractionEvent, updateCallback);
745 void SLandmarks::show(
bool b)
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_POINT_INSERTED_SIG
Type of signal when a group is added.
This class is a helper to define the connections of a service and its data.
This class defines a list of 3D points inside groups.
VISUVTKADAPTOR_API void starting() override
Initialize the service activity.
Class allowing to block a Connection.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_POINT_DESELECTED_SIG
Type of signal when a group is added.
The namespace visuVTKAdaptor contains the list of adaptors available for the generic scene...
virtual VISUVTKADAPTOR_API KeyConnectionsMap getAutoConnections() const override
Returns proposals to connect service slots to associated object signals, this method is used for obj/...
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_GROUP_ADDED_SIG
Type of signal when a group is added.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_GROUP_REMOVED_SIG
Type of signal when a group is added.
VISUVTKADAPTOR_API void stopping() override
Uninitialize the service activity. The stop() method is always invoked before destroying a service...
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_POINT_SELECTED_SIG
Type of signal when a group is added.
3D Representation to be used with vtkHandleWidget (represents a cube or a sphere).
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_POINT_ADDED_SIG
Type of signal when a group is added.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_GROUP_RENAMED_SIG
Type of signal when a group is added.
#define SLM_ASSERT(message, cond)
work like 'assert' from 'cassert', with in addition a message logged by spylog (with FATAL loglevel) ...
#define SLM_FATAL_IF(message, cond)
void deselect()
Deselect the current point and emit the corresponding Landmarks signal.
VISUVTKADAPTOR_API void configuring() override
Configure the service before starting. Apply the configuration to service.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_MODIFIED_SIG
Key in m_signals map of signal m_sigModified.
vtkSmartPointer< vtkHandleWidget > LandmarkWidgetType
Widget used to display and interact with landmarks.
VISUVTKADAPTOR_API void updating() override
Perform some computations according to object (this service is attached to) attribute values and its ...
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_POINT_MODIFIED_SIG
Type of signal when a group is added.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_GROUP_MODIFIED_SIG
Type of signal when a group is added.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_POINT_REMOVED_SIG
Type of signal when a group is added.
Adaptor for landmarks in the field of an image.
Base class for VTK adaptors.