fw4spl
visuVTKAdaptor/src/visuVTKAdaptor/SLine.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2017.
3  * Distributed under the terms of the GNU Lesser General Public License (LGPL) as
4  * published by the Free Software Foundation.
5  * ****** END LICENSE BLOCK ****** */
6 
7 #include "visuVTKAdaptor/SLine.hpp"
8 
9 #include <fwCom/Slots.hxx>
10 
11 #include <fwServices/macros.hpp>
12 
13 #include <boost/lexical_cast.hpp>
14 
15 #include <vtkActor.h>
16 #include <vtkFloatArray.h>
17 #include <vtkImageData.h>
18 #include <vtkPointData.h>
19 #include <vtkProperty.h>
20 #include <vtkRenderer.h>
21 #include <vtkTexture.h>
22 #include <vtkTransform.h>
23 
24 fwServicesRegisterMacro( ::fwRenderVTK::IAdaptor, ::visuVTKAdaptor::SLine);
25 
26 namespace visuVTKAdaptor
27 {
28 //------------------------------------------------------------------------------
29 
30 const ::fwCom::Slots::SlotKeyType SLine::s_UPDATE_VISIBILITY_SLOT = "updateVisibility";
31 const ::fwCom::Slots::SlotKeyType SLine::s_UPDATE_LENGTH_SLOT = "updateLength";
32 
33 //------------------------------------------------------------------------------
34 
35 SLine::SLine() noexcept :
36  m_lineActor(vtkSmartPointer<vtkActor>::New()),
37  m_vtkLine(vtkSmartPointer<vtkLineSource>::New()),
38  m_mapper(vtkSmartPointer<vtkPolyDataMapper>::New()),
39  m_length(1.f),
40  m_width(1.f),
41  m_transformLine(vtkSmartPointer<vtkTransform>::New()),
42  m_dotLine(false)
43 {
46 }
47 
48 //------------------------------------------------------------------------------
49 
50 SLine::~SLine() noexcept
51 {
52  m_lineActor = 0;
53 }
54 
55 //------------------------------------------------------------------------------
56 
58 {
59  this->initialize();
60 
61  this->buildPipeline();
62  this->addToRenderer( m_lineActor );
63  this->requestRender();
64 }
65 
66 //------------------------------------------------------------------------------
67 
69 {
71  this->getRenderer()->RemoveActor(m_lineActor);
72  this->requestRender();
73 }
74 
75 //------------------------------------------------------------------------------
76 
78 {
79 }
80 
81 //------------------------------------------------------------------------------
82 
84 {
85  this->configureParams();
86 
87  const ConfigType config = this->getConfigTree().get_child("config.<xmlattr>");
88 
89  m_length = config.get("length", 1.f);
90  m_width = config.get("width", 1.f);
91 
92  const std::string strColor = config.get("color", "#FFFFFF");
93 
94  m_color = ::fwData::Color::New();
95  m_color->setRGBA(strColor);
96 
97  const std::string strLineOptions = config.get("dotted", "false");
98  if(strLineOptions == "true" || strLineOptions == "yes" || strLineOptions == "on" || strLineOptions == "1")
99  {
100  m_dotLine = true;
101  }
102 }
103 
104 //------------------------------------------------------------------------------
105 
106 void SLine::updateVisibility(bool _isVisible)
107 {
108  m_lineActor->SetVisibility(_isVisible);
109 
110  this->setVtkPipelineModified();
111  this->requestRender();
112 }
113 
114 //------------------------------------------------------------------------------
115 
116 void SLine::updateLine()
117 {
118  m_vtkLine->SetPoint2(0.0, 0.0, m_length);
119  m_vtkLine->Update();
120 
121  // create texture coordinates
122  vtkSmartPointer<vtkPolyData> line = m_vtkLine->GetOutput();
123  vtkSmartPointer<vtkFloatArray> textureCoordinates = vtkSmartPointer<vtkFloatArray>::New();
124  textureCoordinates->SetNumberOfComponents(2);
125  textureCoordinates->SetName("TextureCoordinates");
126 
127  float tuple[2] = {0.0f, 0.0f};
128  textureCoordinates->InsertNextTuple(tuple);
129  tuple[0] = m_length / 8.0f;
130  tuple[1] = 0.0f;
131  textureCoordinates->InsertNextTuple(tuple);
132 
133  line->GetPointData()->SetTCoords(textureCoordinates);
134 
135  m_mapper->SetInputData(line);
136 }
137 
138 //------------------------------------------------------------------------------
139 
140 void SLine::buildPipeline()
141 {
142  vtkTransform* transform = m_renderService.lock()->getOrAddVtkTransform(m_transformId);
143 
144  // create a line using vtkLineSource
145  m_vtkLine->SetPoint1(0.0, 0.0, 0.0);
146  m_vtkLine->SetPoint2(0.0, 0.0, m_length);
147  m_vtkLine->Update();
148  vtkSmartPointer<vtkPolyData> line = m_vtkLine->GetOutput();
149 
150  // create texture coordinates
151  vtkSmartPointer<vtkFloatArray> textureCoordinates = vtkSmartPointer<vtkFloatArray>::New();
152  textureCoordinates->SetNumberOfComponents(2);
153  textureCoordinates->SetName("TextureCoordinates");
154 
155  float tuple[2] = {0.0f, 0.0f};
156  textureCoordinates->InsertNextTuple(tuple);
157  tuple[0] = m_length / 8.0f;
158  tuple[1] = 0.0f;
159  textureCoordinates->InsertNextTuple(tuple);
160 
161  line->GetPointData()->SetTCoords(textureCoordinates);
162 
163  m_mapper->SetInputData(line);
164 
165  m_lineActor->SetMapper(m_mapper);
166 
167  if(m_dotLine)
168  {
169  // create an image of two pixels for the dot effect
170  vtkSmartPointer<vtkImageData> stippleImage = vtkSmartPointer<vtkImageData>::New();
171  stippleImage->SetExtent( 0, 1, 0, 0, 0, 0 );
172  stippleImage->SetOrigin( 0.0, 0.0, 0.0 );
173  stippleImage->SetSpacing( 1.0, 1.0, 1.0 );
174  stippleImage->AllocateScalars(VTK_UNSIGNED_CHAR, 4);
175 
176  // fill the image
177  unsigned char* iptr = static_cast<unsigned char*>(stippleImage->GetScalarPointer( 0, 0, 0 ));
178 
179  std::memset(iptr, 0, 8 );
180  iptr[0] = static_cast<unsigned char>(m_color->red() * 255.0f);
181  iptr[1] = static_cast<unsigned char>(m_color->green() * 255.0f);
182  iptr[2] = static_cast<unsigned char>(m_color->blue() * 255.0f);
183  iptr[3] = 255;
184 
185  // create a texture from the image
186  vtkSmartPointer<vtkTexture> vtkTex = vtkSmartPointer< vtkTexture >::New();
187  vtkTex->SetInputData(stippleImage);
188  vtkTex->SetRepeat(1);
189  m_lineActor->GetProperty()->SetTexture("stipple", vtkTex);
190  }
191  else
192  {
193  m_lineActor->GetProperty()->SetColor(m_color->red(), m_color->green(), m_color->blue());
194  }
195 
196  m_lineActor->GetProperty()->SetLineWidth(m_width);
197  m_lineActor->SetUserTransform(transform);
198  this->setVtkPipelineModified();
199 }
200 //------------------------------------------------------------------------------
201 
202 void SLine::updateLength(float length)
203 {
204  m_length = length;
205  this->updateLine();
206  this->setVtkPipelineModified();
207  this->requestRender();
208 }
209 
210 //------------------------------------------------------------------------------
211 } // namespace visuVTKAdaptor
VISUVTKADAPTOR_API void updateVisibility(bool isVisible)
Slot: update axes visibility (true = visible)
VISUVTKADAPTOR_API void starting() override
Initialize the service activity.
FWRENDERVTK_API void addToRenderer(vtkProp *prop)
Adds the vtkProp to the renderer.
static VISUVTKADAPTOR_APIconst::fwCom::Slots::SlotKeyType s_UPDATE_VISIBILITY_SLOT
Slot: update axes visibility (true = visible)
FWRENDERVTK_API vtkRenderer * getRenderer()
Returns the renderer.
The namespace visuVTKAdaptor contains the list of adaptors available for the generic scene...
VISUVTKADAPTOR_API void configuring() override
Configure the service before starting. Apply the configuration to service.
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 ...
VISUVTKADAPTOR_API void updateLength(float length)
Slot: update length of the line.
FWRENDERVTK_API void removeAllPropFromRenderer()
Removes all the vtkProp from the renderer.
VISUVTKADAPTOR_API void updating() override
Perform some computations according to object (this service is attached to) attribute values and its ...
FWRENDERVTK_API void initialize()
Initialize the adaptor with the associated render service. (must be call in starting).
VISUVTKADAPTOR_API void stopping() override
Uninitialize the service activity. The stop() method is always invoked before destroying a service...
static VISUVTKADAPTOR_APIconst::fwCom::Slots::SlotKeyType s_UPDATE_LENGTH_SLOT
Slot: update axes visibility (true = visible)
FWSERVICES_API ConfigType getConfigTree() const
Return the configuration, in an boost property tree.
Definition: IService.cpp:247