Developer documentation | Axl-2.5.1

axlActorVolumeDiscrete.cpp
Go to the documentation of this file.
1 /* axlActorVolumeDiscrete.cpp ---
2  *
3  * Author: Thibaud Kloczko
4  * Copyright (C) 2008 - Thibaud Kloczko, >Inria.
5  * Created: Fri Feb 4 21:35:45 2011 (+0100)
6  * Version: $Id$
7  * Last-Updated: Wed Oct 9 19:46:14 2013 (+0200)
8  * By: Julien Wintz
9  * Update #: 383
10  */
11 
12 /* Commentary:
13  *
14  */
15 
16 /* Change log:
17  *
18  */
19 
20 #include "axlVolumeDiscrete.h"
21 #include "axlActorVolumeDiscrete.h"
22 
23 #include <vtkAbstractVolumeMapper.h>
24 #include <vtkActor.h>
25 #include <vtkProperty.h>
26 #include <vtkColorTransferFunction.h>
27 #include <vtkConfigure.h>
28 #include <vtkDoubleArray.h>
29 #include <vtkGPUVolumeRayCastMapper.h>
30 #include <vtkObjectFactory.h>
31 #include <vtkOpenGLGPUVolumeRayCastMapper.h>
32 #include <vtkOutlineCornerFilter.h>
33 #include <vtkOutlineFilter.h>
34 #include <vtkImageData.h>
35 //#include <vtkImageResize.h>
36 #include <vtkPiecewiseFunction.h>
37 #include <vtkPointData.h>
38 #include <vtkPolyData.h>
39 #include <vtkPolyDataMapper.h>
40 #include <vtkProp3DCollection.h>
41 #include <vtkSmartPointer.h>
42 #include <vtkSmartVolumeMapper.h>
43 //#include <vtkVolumeTextureMapper3D.h>
44 #include <vtkVolume.h>
45 #include <vtkVolumeProperty.h>
46 
47 #include <vtkCommand.h>
48 
49 #include <vtkVersion.h>
50 
51 
52 
53 
54 class axlActorVolumeDiscreteObserver : public vtkCommand
55 {
56 public:
58  {
60  }
61 
62  virtual void Execute(vtkObject *caller, unsigned long event, void *)
63  {
64 // vtkRenderWindowInteractor *interactor = observerDataAssembly->getInteractor(); //interactor->Render();
65 
66 
67 // if(event == vtkCommand::InteractionEvent)
68 // {
69 // if(lineWidget && pointWidget)
70 // {// NOTICE : We can improve this code...
71 // axlPoint p1(lineWidget->GetPoint1()[0], lineWidget->GetPoint1()[1], lineWidget->GetPoint1()[2]);
72 // axlPoint p2(lineWidget->GetPoint2()[0], lineWidget->GetPoint2()[1], lineWidget->GetPoint2()[2]);
73 // if(!(axlPoint::distance(&p1, observerData_cylinder->firstPoint())< 0.0001 && axlPoint::distance(&p2, observerData_cylinder->secondPoint())<0.0001))
74 // {// There we move the line widget
75 // observerData_cylinderSource->Update();
76 // observerData_cylinderSource->Modified();
77 // observerData_cylinder->modifyFirstPoint(lineWidget->GetPoint1());
78 // observerData_cylinder->modifySecondPoint(lineWidget->GetPoint2());
79 // observerDataAssembly->onUpdateGeometry();
80 // }
81 // else
82 // {// There we move the point widget
83 
84 // axlPoint center = (*(observerData_cylinder->firstPoint())+(*(observerData_cylinder->secondPoint()))) / 2.0;
85 // axlPoint p3(pointWidget->GetPosition()[0], pointWidget->GetPosition()[1], pointWidget->GetPosition()[2]);
86 // axlPoint mp3 = p3 - center;
87 // axlPoint p1p2 = (*(observerData_cylinder->secondPoint())-(*(observerData_cylinder->firstPoint())));
88 // double pv = (mp3.x() * p1p2.x() + mp3.y() * p1p2.y() + mp3.z() * p1p2.z());
89 
90 // axlPoint ps = p1p2 * pv;
91 // double norm = observerData_cylinder->length();
92 
93 // axlPoint c = p3 - (ps /= (norm*norm));
94 
95 // pointWidget->SetPosition(c.coordinates());
96 // double r = axlPoint::distance(&c, &center);
97 
98 // observerData_cylinder->setRadius(0.9 * r);
99 // observerData_cylinderSource->SetRadius(0.9 * r);
100 // if(!observerData_cylinder->fields().isEmpty())
101 // observerData_cylinder->runFieldUpdated();
102 // }
103 // }
104 // }
105 
106  // if(event == vtkCommand::MouseMoveEvent)
107  // {
108  // if(observerData_cylinder)
109  // {
110  // // we need the matrix transform of this actor
111 
112  // vtkAssemblyPath *path;
113  // vtkRenderWindow *renderWindow = interactor->GetRenderWindow();
114  // vtkRendererCollection * rendererCollection = renderWindow->GetRenderers();
115  // vtkRenderer *render = rendererCollection->GetFirstRenderer();
116  // axlInteractorStyle = dynamic_cast<axlInteractorStyleSwitch *>(interactor->GetInteractorStyle());
117 
118  // int X = observerDataAssembly->getInteractor()->GetEventPosition()[0];
119  // int Y = observerDataAssembly->getInteractor()->GetEventPosition()[1];
120 
121  // if (!render || !render->IsInViewport(X, Y))
122  // {
123  // //qDebug()<<" No renderer or bad cursor coordonates";
124  // }
125 
126  // axlCylinderPicker->Pick(X,Y,0.0,render);
127  // path = axlCylinderPicker->GetPath();
128 
129  // if ( path != NULL)
130  // {
131  // double *position = observerDataAssembly->GetPosition();
132  // (void)position;
133 
134  // for(int j=0;j<3;j++)
135  // {
136  // //qDebug()<<"axlActorCylinderObserver :: Execute "<<position[j];
137  // //observerData_line->coordinates()[j] = position[j];
138  // }
139 
140  // }
141 
142  // }
143  // }
144  }
145 
146  // axlInteractorStyleSwitch *axlInteractorStyle;
147  vtkCellPicker *axlVolumePicker;
150 
151 
152 };
153 
154 
155 // /////////////////////////////////////////////////////////////////
156 // axlActorVolumeDiscretePrivate
157 // /////////////////////////////////////////////////////////////////
158 
159 class axlActorVolumeDiscretePrivate
160 {
161 public:
162  axlVolumeDiscrete *volume;
163 
164 public:
165  vtkSmartPointer<vtkVolume> vol;
166  vtkSmartPointer<vtkVolumeProperty> volProperty;
167  vtkSmartPointer<vtkColorTransferFunction> colorFunction;
168  vtkSmartPointer<vtkPiecewiseFunction> opacityTransferFunction;
169  vtkSmartPointer<vtkSmartVolumeMapper> mapper;
170 
171 public:
172  vtkSmartPointer<vtkOutlineCornerFilter> outline_corner;
173  vtkSmartPointer<vtkOutlineFilter> outline_box;
174  vtkSmartPointer<vtkOutlineFilter> outline_contour;
175 
176  vtkSmartPointer<vtkPolyDataMapper> outline_corner_mapper;
177  vtkSmartPointer<vtkPolyDataMapper> outline_box_mapper;
178  vtkSmartPointer<vtkPolyDataMapper> outline_contour_mapper;
179 
180  vtkSmartPointer<vtkActor> outline_corner_actor;
181  vtkSmartPointer<vtkActor> outline_box_actor;
182  vtkSmartPointer<vtkActor> outline_contour_actor;
183 
184 public:
185  vtkImageData * image;
186 #if(VTK_VERSION_MINOR >= 10)
187  vtkImageResize *filter;
188 #endif
189 };
190 
191 // /////////////////////////////////////////////////////////////////
192 // axlActorVolumeDiscrete
193 // /////////////////////////////////////////////////////////////////
194 #if (VTK_MAJOR_VERSION <= 5)
195 vtkCxxRevisionMacro(axlActorVolumeDiscrete, "$Revision: 0.0.1 $");
196 #endif
197 
199 
200 void axlActorVolumeDiscrete::setData(dtkAbstractData *volume)
201 {
202  if (!dynamic_cast<axlVolumeDiscrete *>(volume)) {
203  dtkWarn() << "No volume, can't set volume!";
204  return;
205  }
206 
207  d->volume = dynamic_cast<axlVolumeDiscrete *>(volume);
208  vtkSmartVolumeMapper *mapper = d->mapper;
209 
210  d->image = static_cast<vtkImageData *>(d->volume->data());
211 
212  int spacing_x = d->image->GetSpacing()[0];
213  // int spacing_y = d->image->GetSpacing()[1];
214  // int spacing_z = d->image->GetSpacing()[2];
215 
216  // int dim_x = d->image->GetDimensions()[0];
217  // int dim_y = d->image->GetDimensions()[1];
218  // int dim_z = d->image->GetDimensions()[2];
219 
220 
221  if(spacing_x != 1) {
222 #if(VTK_VERSION_MINOR >= 10)
223  d->filter = vtkImageResize::New();
224 #if (VTK_MAJOR_VERSION <= 5)
225  d->filter->SetInput(d->image);
226 #else
227  d->filter->SetInputData(d->image);
228 #endif
229  d->filter->SetResizeMethodToOutputDimensions();
230  d->filter->SetOutputDimensions(spacing_x*dim_x, spacing_y*dim_y, spacing_z*dim_z);
231  d->filter->SetOutputSpacing(1, 1, 1);
232  d->filter->Update();
233 #if (VTK_MAJOR_VERSION <= 5)
234  mapper->SetInput(d->filter->GetOutput());
235 #else
236  mapper->SetInputData(d->filter->GetOutput());
237 #endif
238 #endif
239 
240  } else {
241 #if (VTK_MAJOR_VERSION <= 5)
242  mapper->SetInput(d->image);
243 #else
244  mapper->SetInputData(d->image);
245 #endif
246  }
247 
248  double min = d->volume->minValue();
249  double mid = d->volume->midValue();
250  double max = d->volume->maxValue();
251 
252  d->colorFunction = vtkSmartPointer<vtkColorTransferFunction>::New();
253  d->colorFunction->SetColorSpaceToRGB();
254  d->colorFunction->AddRGBPoint(min, 0.0, 0.0, 1.0);
255  d->colorFunction->AddRGBPoint(mid, 0.0, 1.0, 0.0);
256  d->colorFunction->AddRGBPoint(max, 1.0, 0.0, 0.0);
257 
258  d->opacityTransferFunction = vtkSmartPointer<vtkPiecewiseFunction>::New();
259  d->opacityTransferFunction->AddPoint(min, 0.5);
260  d->opacityTransferFunction->AddPoint(mid, 0.5);
261  d->opacityTransferFunction->AddPoint(max, 0.5);
262 
263  d->volProperty = vtkSmartPointer<vtkVolumeProperty>::New();
264  d->volProperty->SetColor(d->colorFunction);
265  d->volProperty->SetScalarOpacity(d->opacityTransferFunction);
266  d->volProperty->ShadeOn();
267  d->volProperty->SetSpecular(1.0);
268 
269  d->vol = vtkSmartPointer<vtkVolume>::New();
270  d->vol->SetMapper(d->mapper);
271  d->vol->SetProperty(d->volProperty);
272 
273  d->vol->SetVisibility(1);
274 
275 
276  { // Building corner outline actor
277 
278  if(!d->outline_corner)
279  d->outline_corner = vtkSmartPointer<vtkOutlineCornerFilter>::New();
280 #if (VTK_MAJOR_VERSION <= 5)
281  d->outline_corner->SetInput(d->image);
282 #else
283  d->outline_corner->SetInputData(d->image);
284 #endif
285  d->outline_corner->Update();
286 
287  if(!d->outline_corner_mapper)
288  d->outline_corner_mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
289  d->outline_corner_mapper->SetInputConnection(d->outline_corner->GetOutputPort());
290 
291  if(!d->outline_corner_actor)
292  d->outline_corner_actor = vtkSmartPointer<vtkActor>::New();
293  d->outline_corner_actor->SetMapper(d->outline_corner_mapper);
294  d->outline_corner_actor->GetProperty()->SetColor(1, 0, 0);
295  }
296 
297  { // Building outline box actor
298 
299  if(!d->outline_box)
300  d->outline_box = vtkSmartPointer<vtkOutlineFilter>::New();
301 #if (VTK_MAJOR_VERSION <= 5)
302  d->outline_box->SetInput(d->image);
303 #else
304  d->outline_box->SetInputData(d->image);
305 #endif
306  d->outline_box->Update();
307 
308  if(!d->outline_box_mapper)
309  d->outline_box_mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
310  d->outline_box_mapper->SetInputConnection(d->outline_box->GetOutputPort());
311 
312  if(!d->outline_box_actor)
313  d->outline_box_actor = vtkSmartPointer<vtkActor>::New();
314  d->outline_box_actor->SetMapper(d->outline_box_mapper);
315  d->outline_box_actor->GetProperty()->SetColor(1, 0, 0);
316  }
317 
318  { // Building outline contour actor
319 
320  if(!d->outline_contour)
321  d->outline_contour = vtkSmartPointer<vtkOutlineFilter>::New();
322 #if (VTK_MAJOR_VERSION <= 5)
323  d->outline_contour->SetInput(d->image);
324 #else
325  d->outline_contour->SetInputData(d->image);
326 #endif
327  d->outline_contour->Update();
328 
329  if(!d->outline_contour_mapper)
330  d->outline_contour_mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
331  d->outline_contour_mapper->SetInputConnection(d->outline_contour->GetOutputPort());
332 
333  if(!d->outline_contour_actor)
334  d->outline_contour_actor = vtkSmartPointer<vtkActor>::New();
335  d->outline_contour_actor->SetMapper(d->outline_contour_mapper);
336  d->outline_contour_actor->GetProperty()->SetColor(1, 0, 0);
337  }
338 
339  d->outline_contour_actor->SetVisibility(1);
340  d->outline_box_actor->SetVisibility(1);
341  d->outline_corner_actor->SetVisibility(1);
342 
343  this->AddPart(d->outline_corner_actor);
344  this->AddPart(d->outline_box_actor);
345  this->AddPart(d->outline_contour_actor);
346 
347  this->setActor(vtkSmartPointer<vtkActor>::New());
348  this->getActor()->SetMapper(this->getMapper());
349  this->AddPart(this->getActor());
350 
351 }
352 
353 dtkAbstractData *axlActorVolumeDiscrete::data(void)
354 {
355  return d->volume;
356 }
357 
359 {
360  if (!d->volume)
361  return;
362 
363 #if(VTK_VERSION_MINOR >= 10)
364  if(d->filter)
365  d->filter->Update();
366 #endif
367 
368  d->vol->Modified();
369  d->volProperty->Modified();
370  d->colorFunction->Modified();
371  d->opacityTransferFunction->Modified();
372  d->mapper->Modified();
373  d->mapper->Update();
374 }
375 
377 {
378 
379 }
380 
382 {
383  if(display)
384  if(!this->GetParts()->IsItemPresent(d->vol))
385  this->AddPart(d->vol);
386 
387  if(!display)
388  if (this->GetParts()->IsItemPresent(d->vol))
389  this->RemovePart(d->vol);
390 }
391 
392 
394 {
395  this->onModeChanged(state);
396 
397  emit stateChanged(this->data(), state);
398 }
399 
401 {
402  if(state == 0)
403  {
405  this->getActor()->SetPickable(1);
406 
407  if(axlAbstractData *data = dynamic_cast<axlAbstractData *>(this->data()))
408  {
409  QColor color = data->color();
410  this->getActor()->GetProperty()->SetColor(color.redF(), color.greenF(), color.blueF());
411  }
412 
413  }
414  else if(state == 1)
415  {
416 
418  this->getActor()->SetPickable(1);
419  vtkProperty *prop = this->getActor()->GetProperty();
420 
421  if(axlAbstractData *data = dynamic_cast<axlAbstractData *>(this->data()))
422  {
423  QColor color = data->color();
424  qreal *h = new qreal(0.0);
425  qreal *s = new qreal(0.0);
426  qreal *l = new qreal(0.0);
427  color.getHslF(h, s, l);
428  color.setHslF(*h, *s, *l + (1.0 - *l) / 2.0);
429  prop->SetColor(color.redF(), color.greenF(), color.blueF());
430  delete l;
431  delete s;
432  delete h;
433  }
434 
435  }
436  else if(state == 2)
437  {
439  this->getActor()->SetPickable(0);
440  vtkProperty *prop = this->getActor()->GetProperty();
441  if(axlAbstractData *data = dynamic_cast<axlAbstractData *>(this->data()))
442  {
443  QColor color = data->color();
444  qreal *h = new qreal(0.0);
445  qreal *s = new qreal(0.0);
446  qreal *l = new qreal(0.0);
447  color.getHslF(h, s, l);
448  color.setHslF(*h, *s, *l + (1.0 - *l)/2.0);
449  prop->SetColor(color.redF(), color.greenF(), color.blueF());
450  delete l;
451  delete s;
452  delete h;
453  }
454  }
455 
456  this->Modified();
457 }
458 
459 
461 {
462 
463 }
464 
466 {
467  this->touch();
468  this->update();
469 }
470 
471 
472 
474 {
475  d->outline_corner_actor->SetVisibility(0);
476  d->outline_box_actor->SetVisibility(0);
477  d->outline_contour_actor->SetVisibility(0);
478 }
479 
481 {
482  d->outline_corner_actor->SetVisibility(1);
483  d->outline_box_actor->SetVisibility(0);
484  d->outline_contour_actor->SetVisibility(0);
485 }
486 
488 {
489  d->outline_corner_actor->SetVisibility(0);
490  d->outline_box_actor->SetVisibility(1);
491  d->outline_contour_actor->SetVisibility(0);
492 }
493 
495 {
496  d->outline_corner_actor->SetVisibility(0);
497  d->outline_box_actor->SetVisibility(0);
498  d->outline_contour_actor->SetVisibility(1);
499 }
500 
502 {
503  return d->colorFunction;
504 }
505 
507 {
508  return d->opacityTransferFunction;
509 }
510 
512 {
513  return d->mapper;
514 }
515 
517 {
518  return d->vol;
519 }
520 
522 {
523  return d->volProperty;
524 }
525 
527 {
528  return d->image;
529 }
530 
531 axlActorVolumeDiscrete::axlActorVolumeDiscrete(void) : axlActor(), d(new axlActorVolumeDiscretePrivate)
532 {
533  d->volume = NULL;
534 #if(VTK_VERSION_MINOR >= 10)
535  d->filter = NULL;
536 #endif
537  d->mapper = vtkSmartVolumeMapper::New();
538  d->mapper->SetRequestedRenderMode(vtkSmartVolumeMapper::TextureRenderMode);
539 }
540 
542 {
543  delete d;
544 
545  d = NULL;
546 }
dtkAbstractData * data(void)
static axlActorVolumeDiscreteObserver * New(void)
void stateChanged(dtkAbstractData *data, int mode)
vtkStandardNewMacro(axlActorVolumeDiscrete)
virtual void setState(int state)
Definition: axlActor.cpp:434
void setData(dtkAbstractData *volume)
virtual void Execute(vtkObject *caller, unsigned long event, void *)
void setActor(vtkSmartPointer< vtkActor > actor)
Definition: axlActor.cpp:322
vtkSmartPointer< vtkActor > getActor(void)
Definition: axlActor.cpp:317
vtkSmartPointer< vtkPolyDataMapper > getMapper(void)
Definition: axlActor.cpp:327
axlActorVolumeDiscrete * observerDataAssembly
vtkCxxRevisionMacro(axlActorVolumeDiscrete,"$Revision: 0.0.1 $")
Class axlAbstractData defines an API for all type of axel data.