7 #include "visuVTKAdaptor/SSlicesCursor.hpp" 9 #include <fwCom/Slot.hpp> 10 #include <fwCom/Slot.hxx> 11 #include <fwCom/Slots.hpp> 12 #include <fwCom/Slots.hxx> 14 #include <fwCore/base.hpp> 16 #include <fwData/Float.hpp> 17 #include <fwData/Image.hpp> 18 #include <fwData/String.hpp> 20 #include <fwDataTools/fieldHelper/Image.hpp> 21 #include <fwDataTools/fieldHelper/MedicalImageHelpers.hpp> 23 #include <fwServices/macros.hpp> 25 #include <boost/assign/list_of.hpp> 28 #include <vtkCellArray.h> 29 #include <vtkCellData.h> 31 #include <vtkPolyData.h> 32 #include <vtkPolyDataMapper.h> 33 #include <vtkProperty.h> 34 #include <vtkRenderer.h> 35 #include <vtkTransform.h> 50 static const ::fwServices::IService::KeyType s_IMAGE_INOUT =
"image";
54 SSlicesCursor::SSlicesCursor() noexcept :
55 m_cursorPolyData( vtkPolyData::New() ),
56 m_cursorMapper( vtkPolyDataMapper::New() ),
57 m_cursorActor( vtkActor::New() ),
71 SSlicesCursor::~SSlicesCursor() noexcept
73 m_cursorActor->Delete();
75 m_cursorMapper->Delete();
76 m_cursorMapper = NULL;
77 m_cursorPolyData->Delete();
84 m_scale =
static_cast<float>(scale);
94 const ConfigType config = this->
getConfigTree().get_child(
"config.<xmlattr>");
96 m_scale = config.get<
float>(
"scale", 0.5f);
105 ::fwData::Image::sptr image = this->getInOut< ::fwData::Image >(s_IMAGE_INOUT);
108 this->buildPolyData();
109 this->buildColorAttribute();
111 this->updateColors();
112 m_cursorMapper->SetInputData( m_cursorPolyData );
113 m_cursorActor->SetMapper(m_cursorMapper);
114 m_cursorActor->GetProperty()->SetOpacity(0.9);
129 m_isSelected =
false;
153 void SSlicesCursor::buildPolyData()
156 vtkPoints* points = vtkPoints::New(VTK_DOUBLE);
157 points->SetNumberOfPoints(nbPoints);
159 for (i = 0; i < nbPoints; i++)
161 points->SetPoint(i, 0.0, 0.0, 0.0);
164 vtkCellArray* cells = vtkCellArray::New();
165 cells->Allocate(cells->EstimateSize(nbPoints, 2));
167 for (
int line = 0; line < 4; ++line)
169 vtkLine* lineCell = vtkLine::New();
170 lineCell->GetPointIds()->SetId(0, line );
171 lineCell->GetPointIds()->SetId(1, line+ 4 );
172 cells->InsertNextCell(lineCell);
176 m_cursorPolyData->SetPoints(points);
178 m_cursorPolyData->SetLines(cells);
185 void SSlicesCursor::barycenter(
double ptA[3],
double ptB[3],
float scale,
double result[3] )
187 for (
int i = 0; i < 3; ++i )
189 result[i] = scale*ptA[i] + (1-scale)*ptB[i];
195 void SSlicesCursor::computeCrossPoints(
double _ptA[3],
double _ptB[3],
double _ptP[3],
double _scale,
196 double _ptAprime[3],
double _ptBprime[3] )
199 double norm2PBprime = 0.0;
204 for (
int i = 0; i < 3; ++i )
206 ptPBprime[i] = ( _ptB[i] - _ptA[i] ) * (1-_scale)/2.0;
207 norm2PBprime += ptPBprime[i]*ptPBprime[i];
208 norm2AP += (_ptP[i] - _ptA[i])*(_ptP[i] - _ptA[i]);
209 norm2BP += (_ptP[i] - _ptB[i])*(_ptP[i] - _ptB[i]);
214 if ( norm2PBprime > norm2BP )
216 for (
int i = 0; i < 3; ++i )
218 _ptAprime[i] = _ptP[i] - ptPBprime[i];
219 _ptBprime[i] = _ptB[i];
222 else if ( norm2PBprime > norm2AP )
224 for (
int i = 0; i < 3; ++i )
226 _ptAprime[i] = _ptA[i];
227 _ptBprime[i] = _ptP[i] + ptPBprime[i];
232 for (
int i = 0; i < 3; ++i )
234 _ptAprime[i] = _ptP[i] - ptPBprime[i];
235 _ptBprime[i] = _ptP[i] + ptPBprime[i];
242 void SSlicesCursor::buildColorAttribute()
244 unsigned char red[3] = {255, 0, 0};
245 unsigned char green[3] = {0, 255, 0};
246 unsigned char blue[3] = {0, 0, 255};
248 typedef unsigned char* RGBColor;
249 typedef std::map< std::string, std::pair< RGBColor, RGBColor> > DicoType;
251 dict[
"colorXAxis"] = std::make_pair(green, red);
252 dict[
"colorYAxis"] = std::make_pair(red, blue);
253 dict[
"colorZAxis"] = std::make_pair(blue, green );
255 for ( DicoType::iterator i = dict.begin(); i != dict.end(); ++i )
257 vtkUnsignedCharArray* colors = vtkUnsignedCharArray::New();
258 colors->SetNumberOfComponents(3);
259 colors->SetName( i->first.c_str() );
262 #if (VTK_MAJOR_VERSION == 7 && VTK_MINOR_VERSION >= 1) || VTK_MAJOR_VERSION > 7 263 colors->InsertNextTypedTuple( i->second.first );
264 colors->InsertNextTypedTuple( i->second.second );
265 colors->InsertNextTypedTuple( i->second.first );
266 colors->InsertNextTypedTuple( i->second.second );
268 colors->InsertNextTupleValue( i->second.first );
269 colors->InsertNextTupleValue( i->second.second );
270 colors->InsertNextTupleValue( i->second.first );
271 colors->InsertNextTupleValue( i->second.second );
273 m_cursorPolyData->GetCellData()->AddArray(colors);
276 m_cursorMapper->SetScalarModeToUseCellFieldData();
282 void SSlicesCursor::updateColors()
286 case 0: m_cursorMapper->SelectColorArray(
"colorXAxis");
break;
287 case 1: m_cursorMapper->SelectColorArray(
"colorYAxis");
break;
288 case 2: m_cursorMapper->SelectColorArray(
"colorZAxis");
break;
298 ::fwData::Image::sptr image = this->getInOut< ::fwData::Image >(s_IMAGE_INOUT);
305 this->updateImageSliceIndex(image);
306 this->updateColors();
313 void SSlicesCursor::updateImageSliceIndex( ::fwData::Image::sptr image )
315 float scale = m_isSelected ? 1.0 : m_scale;
318 m_cursorActor->VisibilityOff();
322 m_cursorActor->VisibilityOn();
330 const ::fwData::Image::SpacingType spacing = image->getSpacing();
331 const ::fwData::Image::OriginType origin = image->getOrigin();
332 const ::fwData::Image::SizeType size = image->getSize();
333 double sliceWorld[3];
334 for (
unsigned int dim = 0; dim < 3; ++dim )
336 sliceWorld[dim] = pos[dim] * spacing[dim] + origin.at(dim);
339 double cursorPoints[8][3];
340 for (
unsigned int p = 0; p < 2; ++p )
342 for (
unsigned int dim = 0; dim < 3; ++dim )
346 cursorPoints[p][dim] = origin.at(dim);
347 cursorPoints[p+2][dim] = (size[dim]-1) * spacing[dim] + origin.at(dim);
351 cursorPoints[p][dim] = sliceWorld[dim];
352 cursorPoints[p+2][dim] = sliceWorld[dim];
358 computeCrossPoints( cursorPoints[0], cursorPoints[2], sliceWorld, scale, cursorPoints[4], cursorPoints[6] );
360 computeCrossPoints( cursorPoints[1], cursorPoints[3], sliceWorld, scale, cursorPoints[5], cursorPoints[7] );
362 vtkPoints* points = m_cursorPolyData->GetPoints();
364 for (
int i = 0; i < 8; ++i)
366 points->SetPoint(i, cursorPoints[i]);
369 m_cursorPolyData->Modified();
375 void SSlicesCursor::updateSliceIndex(
int axial,
int frontal,
int sagittal)
381 ::fwData::Image::sptr image = this->getInOut< ::fwData::Image >(s_IMAGE_INOUT);
383 this->updateImageSliceIndex(image);
388 void SSlicesCursor::showFullCross()
395 void SSlicesCursor::showNormalCross()
397 m_isSelected =
false;
402 void SSlicesCursor::updateSliceType(
int from,
int to)
417 void SSlicesCursor::updateImage()
419 ::fwData::Image::sptr image = this->getInOut< ::fwData::Image >(s_IMAGE_INOUT);
void setCrossScale(double scale)
Slot: set the scale for the cross : 1. means full cross, 0.5 half cross, 0. no cross.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_SLICE_INDEX_MODIFIED_SIG
Type of signal when image's buffer is added.
This class is a helper to define the connections of a service and its data.
FWRENDERVTK_API void addToRenderer(vtkProp *prop)
Adds the vtkProp to the renderer.
The namespace visuVTKAdaptor contains the list of adaptors available for the generic scene...
static const ::fwCom::Slots::SlotKeyType s_SHOW_FULL_CROSS_SLOT
Slot: update image slice index.
FWRENDERVTK_API void configureParams()
Parse the xml configuration for renderer, picker and transform.
FWRENDERVTK_API void requestRender()
notify a render request iff vtkPipeline is modified
FWRENDERVTK_API void setVtkPipelineModified()
End-user have to call this method when a vtk structure has been modified, thus a render request will ...
FWRENDERVTK_API void removeAllPropFromRenderer()
Removes all the vtkProp from the renderer.
FWRENDERVTK_API vtkTransform * getTransform()
Returns the transform used by this adaptor.
static const ::fwCom::Slots::SlotKeyType s_UPDATE_SLICE_INDEX_SLOT
Slot: update image slice index.
VISUVTKADAPTOR_API void configuring() override
Configure the service before starting. Apply the configuration to service.
#define SLM_ASSERT(message, cond)
work like 'assert' from 'cassert', with in addition a message logged by spylog (with FATAL loglevel) ...
FWRENDERVTK_API SRender::VtkObjectIdType getTransformId() const
Returns the identifier of the transform used by this adaptor.
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_BUFFER_MODIFIED_SIG
Type of signal when image's buffer is added.
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_MODIFIED_SIG
Key in m_signals map of signal m_sigModified.
VISUVTKADAPTOR_API void starting() override
Initialize the service activity.
FWRENDERVTK_API void initialize()
Initialize the adaptor with the associated render service. (must be call in starting).
static const ::fwCom::Slots::SlotKeyType s_SET_CROSS_SCALE_SLOT
Slot: update image slice index.
VISUVTKADAPTOR_API void stopping() override
Uninitialize the service activity. The stop() method is always invoked before destroying a service...
static const ::fwCom::Slots::SlotKeyType s_SHOW_NORMAL_CROSS_SLOT
Slot: update image slice index.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_SLICE_TYPE_MODIFIED_SIG
Type of signal when image's buffer is added.
static const ::fwCom::Slots::SlotKeyType s_UPDATE_SLICE_TYPE_SLOT
Slot: update image slice index.
static const ::fwCom::Slots::SlotKeyType s_UPDATE_IMAGE_SLOT
Slot: update image slice index.
Base class for VTK adaptors.
FWSERVICES_API ConfigType getConfigTree() const
Return the configuration, in an boost property tree.