fw4spl
Helpers.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2009-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 "fwRenderVTK/vtk/Helpers.hpp"
8 
9 #include <fwCore/base.hpp>
10 
11 #include <vtkAssemblyNode.h>
12 #include <vtkAssemblyPath.h>
13 #include <vtkCamera.h>
14 #include <vtkMath.h>
15 #include <vtkOpenGLRenderWindow.h>
16 #include <vtkPicker.h>
17 #include <vtkPoints.h>
18 #include <vtkProp3DCollection.h>
19 #include <vtkRenderer.h>
20 
21 namespace fwRenderVTK
22 {
23 
24 namespace vtk
25 {
26 
27 //------------------------------------------------------------------------------
28 
29 vtkIdType getNearestPointId(vtkPoints* pts, vtkRenderer* renderer)
30 {
31  vtkIdType id = -1;
32  double camPosition[3];
33  double distance = VTK_DOUBLE_MAX;
34  renderer->GetActiveCamera()->GetPosition(camPosition);
35 
36  for(vtkIdType i = 0; i < pts->GetNumberOfPoints(); i++)
37  {
38  double* point = pts->GetPoint(i);
39  double distancePtCam = vtkMath::Distance2BetweenPoints(point, camPosition);
40 
41  if(distancePtCam < distance)
42  {
43  id = i;
44  distance = distancePtCam;
45  }
46  }
47 
48  return id;
49 }
50 
51 //------------------------------------------------------------------------------
52 
53 vtkProp* getNearestPickedProp(vtkAbstractPropPicker* picker, vtkRenderer* renderer)
54 {
55  vtkProp* res = NULL;
56  vtkPicker* vtkpicker = vtkPicker::SafeDownCast(picker);
57 
58  SLM_ASSERT("getNearestPickedProp *need* a picker.", picker);
59  SLM_ASSERT("getNearestPickedProp *need* a renderer.", renderer);
60 
61  if (vtkpicker)
62  {
63  vtkIdType id = getNearestPointId(vtkpicker->GetPickedPositions(), renderer);
64 
65  if (id > -1 && vtkpicker->GetProp3Ds()->GetNumberOfItems() > id)
66  {
67  res = vtkProp::SafeDownCast(vtkpicker->GetProp3Ds()->GetItemAsObject(static_cast<int>(id)));
68  }
69  }
70  else
71  {
72  res = picker->GetProp3D();
73  }
74  return res;
75 }
76 
77 //------------------------------------------------------------------------------
78 
79 bool getNearestPickedPosition(vtkAbstractPropPicker* picker, vtkRenderer* renderer, double position[3])
80 {
81  bool res = false;
82  vtkPicker* vtkpicker = vtkPicker::SafeDownCast(picker);
83 
84  SLM_ASSERT("getNearestPickedProp *need* a picker.", picker);
85  SLM_ASSERT("getNearestPickedProp *need* a renderer.", renderer);
86 
87  double* point = NULL;
88  if (vtkpicker)
89  {
90  vtkPoints* pts = vtkpicker->GetPickedPositions();
91  vtkIdType id = getNearestPointId(pts, renderer);
92 
93  if (id > -1)
94  {
95  point = pts->GetPoint(id);
96  }
97  else
98  {
99  point = vtkpicker->GetPickPosition();
100  }
101  }
102  else
103  {
104  point = picker->GetPickPosition();
105  }
106 
107  if(point)
108  {
109  std::copy(point, point + 3, position);
110  res = true;
111  }
112  return res;
113 }
114 
115 //------------------------------------------------------------------------------
116 
117 #ifndef ANDROID
118 
119 #if VTK_MAJOR_VERSION >= 7
120 vtkSmartPointer<vtkShaderProgram>
121 #else
122 vtkSmartPointer<vtkShaderProgram2>
123 #endif
124 //------------------------------------------------------------------------------
125 
126 buildShader( vtkOpenGLRenderWindow* pWindow,
127  const char* pcVertexShader,
128  const char* pcFragmentShader )
129 {
130  SLM_ASSERT( "NULL parameter", pWindow && pcVertexShader && pcFragmentShader );
131 
132  vtkOpenGLRenderWindow* pOpenGLWindow = vtkOpenGLRenderWindow::SafeDownCast(pWindow);
133  if(!pOpenGLWindow)
134  {
135  SLM_ERROR("Shader only supported using OpenGL.");
136  return NULL;
137  }
138 
139 #if VTK_MAJOR_VERSION >= 7
140  vtkSmartPointer<vtkShaderProgram> pProgram = vtkSmartPointer<vtkShaderProgram>::New();
141  {
142  // The vertex shader
143  vtkShader* shader = vtkShader::New();
144  shader->SetType(vtkShader::Vertex);
145  shader->SetSource(pcVertexShader);
146  pProgram->SetVertexShader(shader);
147  shader->Delete();
148  }
149  {
150  // The fragment shader
151  vtkShader* shader = vtkShader::New();
152  shader->SetType(vtkShader::Fragment);
153  shader->SetSource(pcFragmentShader);
154  pProgram->SetFragmentShader(shader);
155  shader->Delete();
156  }
157 #else
158  vtkSmartPointer<vtkShaderProgram2> pProgram = vtkSmartPointer<vtkShaderProgram2>::New();
159  {
160  vtkShader2* shader = vtkShader2::New();
161  shader->SetType(VTK_SHADER_TYPE_VERTEX);
162  shader->SetSourceCode(pcVertexShader);
163  shader->SetContext(pProgram->GetContext());
164  pProgram->GetShaders()->AddItem(shader);
165  shader->Delete();
166  }
167  {
168  // The fragment shader
169  vtkShader2* shader = vtkShader2::New();
170  shader->SetType(VTK_SHADER_TYPE_FRAGMENT);
171  shader->SetSourceCode(pcFragmentShader);
172  shader->SetContext(pProgram->GetContext());
173  pProgram->GetShaders()->AddItem(shader);
174  shader->Delete();
175  }
176 #endif // VTK_MAJOR_VERSION >= 7
177 
178  return pProgram;
179 }
180 
181 //------------------------------------------------------------------------------
182 
183 void openShader(const char* _pcName, std::string& _strShader)
184 {
185  // Read data.txt
186  std::string line;
187  std::ifstream myfile(_pcName);
188  if ( myfile.is_open() )
189  {
190  while ( myfile.good() )
191  {
192  getline( myfile, line );
193  _strShader += line + "\n";
194  }
195  myfile.close();
196  }
197  else
198  {
199  SLM_ERROR("Unable to open file : " + std::string(_pcName));
200  }
201 }
202 
203 //------------------------------------------------------------------------------
204 
205 #if VTK_MAJOR_VERSION >= 7
206 vtkSmartPointer<vtkShaderProgram>
207 #else
208 vtkSmartPointer<vtkShaderProgram2>
209 #endif
210 //------------------------------------------------------------------------------
211 
212 buildShaderFromFile( vtkRenderWindow* pWindow,
213  const char* pcVertexName,
214  const char* pcFragmentName )
215 {
216  SLM_ASSERT( "NULL parameter", pWindow && pcVertexName && pcFragmentName );
217 
218  vtkOpenGLRenderWindow* pOpenGLWindow = vtkOpenGLRenderWindow::SafeDownCast(pWindow);
219  if(!pOpenGLWindow)
220  {
221  SLM_ERROR("Shader only supported using OpenGL.");
222  return NULL;
223  }
224 
225 #if VTK_MAJOR_VERSION >= 7
226  vtkSmartPointer<vtkShaderProgram> pProgram = vtkSmartPointer<vtkShaderProgram>::New();
227  {
228  // The vertex shader
229  std::string strShader("");
230  openShader(pcVertexName, strShader);
231 
232  vtkShader* shader = vtkShader::New();
233  shader->SetType(vtkShader::Vertex);
234  shader->SetSource(strShader.c_str());
235  pProgram->SetVertexShader(shader);
236  shader->Delete();
237  }
238  {
239  // The fragment shader
240  std::string strShader("");
241  openShader(pcFragmentName, strShader);
242 
243  vtkShader* shader = vtkShader::New();
244  shader->SetType(vtkShader::Fragment);
245  shader->SetSource(strShader.c_str());
246  pProgram->SetFragmentShader(shader);
247  shader->Delete();
248  }
249 #else
250  vtkSmartPointer<vtkShaderProgram2> pProgram = vtkSmartPointer<vtkShaderProgram2>::New();
251  {
252  // The vertex shader
253  std::string strShader("");
254  openShader(pcVertexName, strShader);
255 
256  vtkShader2* shader = vtkShader2::New();
257  shader->SetType(VTK_SHADER_TYPE_VERTEX);
258  shader->SetSourceCode(strShader.c_str());
259  shader->SetContext(pProgram->GetContext());
260  pProgram->GetShaders()->AddItem(shader);
261  shader->Delete();
262  }
263  {
264  // The fragment shader
265  std::string strShader("");
266  openShader(pcFragmentName, strShader);
267 
268  vtkShader2* shader = vtkShader2::New();
269  shader->SetType(VTK_SHADER_TYPE_FRAGMENT);
270  shader->SetSourceCode(strShader.c_str());
271  shader->SetContext(pProgram->GetContext());
272  pProgram->GetShaders()->AddItem(shader);
273  shader->Delete();
274  }
275 #endif
276 
277  return pProgram;
278 }
279 #endif
280 
281 } //vtk
282 
283 } //fwRenderVTK
284 
#define SLM_ERROR(message)
Definition: spyLog.hpp:272
#define SLM_ASSERT(message, cond)
work like &#39;assert&#39; from &#39;cassert&#39;, with in addition a message logged by spylog (with FATAL loglevel) ...
Definition: spyLog.hpp:308
The namespace fwRenderVTK contains classes for rendering with VTK.