Developer documentation | Axl-2.5.1

axlLightsWidget.cpp
Go to the documentation of this file.
1 /* axlLightsWidget.Lightp ---
2  *
3  * Author: Meriadeg Perrinel
4  * Copyright (C) 2008 - Meriadeg Perrinel, Inria.
5  * Created: Fri Feb 18 17:29:04 2011 (+0100)
6  * Version: $Id$
7  * Last-Updated: Mon Dec 17 14:40:53 2012 (+0100)
8  * By: Julien Wintz
9  * Update #: 123
10  */
11 
12 /* Commentary:
13  *
14  */
15 
16 /* Change log:
17  *
18  */
19 
20 #include "axlActorCurveBSpline.h"
21 #include "axlActorSurfaceBSpline.h"
22 #include "axlLightsWidget.h"
24 
25 #include <axlCore/axlPoint.h>
27 
28 #include <vtkActor.h>
29 #include <vtkAssemblyNode.h>
30 #include <vtkAssemblyPath.h>
31 #include <vtkCallbackCommand.h>
32 #include <vtkCamera.h>
33 #include <vtkCellArray.h>
34 #include <vtkCellPicker.h>
35 #include <vtkAreaPicker.h>
36 #include <vtkDoubleArray.h>
37 #include <vtkFloatArray.h>
38 #include <vtkLine.h>
39 #include <vtkLight.h>
40 #include <vtkLightActor.h>
41 #include <vtkLightCollection.h>
42 #include <vtkObjectFactory.h>
43 #include <vtkPlanes.h>
44 #include <vtkPoints.h>
45 #include <vtkPolyData.h>
46 #include <vtkPolyDataMapper.h>
47 #include <vtkProperty.h>
48 #include <vtkRenderWindowInteractor.h>
49 #include <vtkRenderer.h>
50 #include <vtkRendererCollection.h>
51 #include <vtkRenderWindow.h>
52 #include <vtkSphereSource.h>
53 #include <vtkTransform.h>
54 #include <vtkGlyph3D.h>
55 #include <vtkSmartPointer.h>
56 #include <vtkTransform.h>
57 #include <vtkCursor3D.h>
58 #include <vtkProp3DCollection.h>
59 #include <vtkProp.h>
60 #include <vtkPropAssembly.h>
61 #include <vtkCollectionIterator.h>
62 #include <vtkCommand.h>
63 
64 #include <vtkRenderWindow.h>
65 
67 
68 class axlLightsWidgetPrivate
69 {
70 public:
71  vtkActor **LightActor;
72  vtkLightActor **LightProp;
73  vtkPolyDataMapper **LightMapper;
74  vtkSphereSource **LightSphere;
75  //vtkActor *LightCurrentActor;
76  vtkActor *LightCurrentActor;
77  int LightCurrentActorIndex;
78  vtkPoints *LightPoints; //used by others as well
79  vtkCellPicker *LightCursorPicker;
80  vtkAreaPicker *LightRectanglePicker;
81  axlInteractorStyleRubberBandPick *LightRubberBanPick;
82  vtkProperty *LightHandleProperty;
83  vtkProperty *LightSelectedHandleProperty;
84 
85  vtkAssemblyNode *LightCurrentAssemblyNode;
86 
87  vtkActorCollection *LightActorCollection;
88 
89  int NbLight;
90 
91  // rectangle behavior
92  int XStartPosition;
93  int YStartPosition;
94 
95 
96 
97  //the 3dCursor
98  vtkPolyDataMapper *LightCursorMapper;
99  vtkActor *LightCursorActor;
100 
101  axlAbstractView *view;
102 
103 };
104 
105 axlLightsWidget::axlLightsWidget() :d(new axlLightsWidgetPrivate)
106 {
108  this->EventCallbackCommand->SetCallback(axlLightsWidget::ProcessEvents);
109  // Set up the initial properties
110  this->CreateDefaultProperties();
111 
112  d->NbLight = 0;
113 
114  // connection for the cursor
115  d->LightCursorMapper = vtkPolyDataMapper::New();
116  d->LightCursorActor = vtkActor::New();
117  d->LightCursorActor->VisibilityOff();
118  d->LightCursorActor->SetMapper(d->LightCursorMapper);
119 
120  // Define the point coordinates
121  double bounds[6];
122  bounds[0] = -0.5;
123  bounds[1] = 0.5;
124  bounds[2] = -0.5;
125  bounds[3] = 0.5;
126  bounds[4] = -0.5;
127  bounds[5] = 0.5;
128 
129  d->XStartPosition =-1;
130  d->YStartPosition =-1;
131 
132  this->PlaceWidget(bounds);
133 }
134 
136 {
137  delete d;
138 
139  d = NULL;
140 }
141 
143 {
144  d->view = view;
145 }
146 
148 {
149  vtkRenderWindow *renderWindow = this->Interactor->GetRenderWindow();
150  vtkRendererCollection * rendererCollection = renderWindow->GetRenderers();
151  vtkRenderer *render = rendererCollection->GetFirstRenderer();
152 
153  vtkLightCollection *lightCollection = render->GetLights();
154  d->NbLight = lightCollection->GetNumberOfItems();
155  lightCollection->InitTraversal();
156  //vtkLight *currentLight = lightCollection->GetNextItem();
157 
158  // Construct initial points CellAray and PolyData
159  d->LightPoints = vtkPoints::New();
160 
161  //Manage the picking stuff
162  d->LightCursorPicker = vtkCellPicker::New();
163  d->LightRectanglePicker = vtkAreaPicker::New();
164  d->LightRubberBanPick = dynamic_cast<axlInteractorStyleRubberBandPick *>(this->Interactor->GetInteractorStyle());//axlInteractorStyleRubberBandPick::New();
165  this->Interactor->SetPicker(d->LightRectanglePicker);
166 
167  d->LightMapper = new vtkPolyDataMapper *[d->NbLight];
168  d->LightSphere = new vtkSphereSource *[d->NbLight];
169  d->LightActor = new vtkActor *[d->NbLight];
170  d->LightProp = new vtkLightActor *[d->NbLight];
171 
172  d->LightActorCollection = vtkActorCollection::New();
173 
174  d->LightPoints->SetNumberOfPoints(d->NbLight);
175 
176  vtkLight *currentLight = NULL;
177 
178  d->LightCursorPicker->SetTolerance(0.01);
179 
180  for (int i = 0; i < d->NbLight; i++)
181  {
182  currentLight = lightCollection->GetNextItem();
183  //storage of points
184  d->LightPoints->SetPoint(i, currentLight->GetPosition());
185 
186  // Construct the poly data representing Lights points
187  d->LightMapper[i] = vtkPolyDataMapper::New();
188  d->LightSphere[i] =vtkSphereSource::New();
189  d->LightSphere[i]->SetPhiResolution(15);
190  d->LightSphere[i]->SetThetaResolution(15);
191  d->LightSphere[i]->SetRadius(0.01);
192  d->LightSphere[i]->SetCenter(d->LightPoints->GetPoint(i));
193 #if (VTK_MAJOR_VERSION <= 5)
194  d->LightMapper[i]->SetInput( d->LightSphere[i]->GetOutput());
195 #else
196  d->LightMapper[i]->SetInputData( d->LightSphere[i]->GetOutput());
197 #endif
198  d->LightActor[i] = vtkActor::New();
199 
200  d->LightActor[i]->SetMapper(d->LightMapper[i]);
201  d->LightActor[i]->VisibilityOn();
202 
203  d->LightActorCollection->AddItem(d->LightActor[i]);
204 
205 
206  d->LightProp[i] = vtkLightActor::New();
207  d->LightProp[i]->SetLight(currentLight);
208  d->LightProp[i]->SetPosition(currentLight->GetPosition());
209 
210  // TO DO : ADD TO RENDERER THE LIGHT
211  render->AddActor(d->LightProp[i]);
212  }
213 }
214 
215 
217 {
218  for (int i = 0; i <d->NbLight; i++)
219  d->LightActor[i]->SetProperty(d->LightHandleProperty);
220 }
221 
222 
223 vtkActorCollection *axlLightsWidget::ptsActors(void)
224 {
225  return d->LightActorCollection;
226 }
227 
228 void axlLightsWidget::SetEnabled(int enabling)
229 {
230 
231  if ( ! this->Interactor )
232  {
233  vtkErrorMacro(<<"The interactor must be set prior to enabling/disabling widget");
234  return;
235  }
236 
237  if ( enabling ) //------------------------------------------------------------
238  {
239  vtkDebugMacro(<<"Enabling widget");
240 
241  if ( this->Enabled ) //already enabled, just return
242  {
243  return;
244  }
245 
246  if ( ! this->CurrentRenderer )
247  {
248  this->SetCurrentRenderer(this->Interactor->FindPokedRenderer(
249  this->Interactor->GetLastEventPosition()[0],
250  this->Interactor->GetLastEventPosition()[1]));
251  if (this->CurrentRenderer == NULL)
252  {
253  return;
254  }
255  }
256 
257  this->Enabled = 1;
258 
259  // listen to the following events
260  vtkRenderWindowInteractor *i = this->Interactor;
261  i->AddObserver(vtkCommand::MouseMoveEvent, this->EventCallbackCommand,
262  this->Priority);
263  i->AddObserver(vtkCommand::LeftButtonPressEvent,
264  this->EventCallbackCommand, this->Priority);
265  i->AddObserver(vtkCommand::LeftButtonReleaseEvent,
266  this->EventCallbackCommand, this->Priority);
267 
268 
269  for (int i = 0; i <d->NbLight; i++)
270  {
271  d->LightActor[i]->SetVisibility(true);
272  d->LightProp[i]->SetVisibility(true);
273  }
274 
275  d->LightCurrentActorIndex =-1;
276  d->XStartPosition =-1;
277  d->YStartPosition =-1;
278 
279 
280  this->InvokeEvent(vtkCommand::EnableEvent,NULL);
281  }
282 
283  else //disabling-------------------------------------------------------------
284  {
285  vtkDebugMacro(<<"Disabling widget");
286 
287  if ( ! this->Enabled ) //already disabled, just return
288  {
289  return;
290  }
291 
292  this->Enabled = 0;
293 
294  // don't listen for events any more
295  this->Interactor->RemoveObserver(this->EventCallbackCommand);
296 
297 
298  for (int i = 0; i <d->NbLight; i++)
299  {
300  d->LightActor[i]->SetVisibility(false);
301  d->LightProp[i]->SetVisibility(false);
302  }
303 
304  d->LightCurrentActorIndex =-1;
305  d->XStartPosition =-1;
306  d->YStartPosition =-1;
307 
308  this->InvokeEvent(vtkCommand::DisableEvent,NULL);
309  this->SetCurrentRenderer(NULL);
310  }
311 
312  this->Interactor->Render();
313 }
314 
316 {
317 
318  // if(d->LightRubberBanPick->getCurrentMode()==0)
319  // {//We select point with the cursor
320  // first unhighlight anything picked
321  this->resetProperty();
322 
323  d->LightCurrentActor = static_cast<vtkActor *>(prop);
324 
325  if ( d->LightCurrentActor )
326  {
327  for (int i = 0; i <d->NbLight; i++)
328  {
329  if ( d->LightCurrentActor == d->LightActor[i] )
330  {
331  d->LightCurrentActor->SetProperty(d->LightSelectedHandleProperty);
332  d->LightCursorPicker->GetPickPosition(this->LastPickPosition);
333  d->LightRectanglePicker->GetPickPosition(this->LastPickPosition);
334  return i;
335  }
336  }
337  }
338  // }
339  // else// we select points with rectangle
340  // {
341  // d->LightCurrentActor = static_cast<vtkActor *>(prop);
342  // if(d->LightCurrentActor->GetProperty()!=d->LightSelectedHandleProperty)
343  // {
344  // this->resetProperty();
345  // this->State = axlLightsWidget::Outside;
346  // }
347  // }
348 
349 
350  return -1;
351 }
352 
353 
354 
355 void axlLightsWidget::ProcessEvents(vtkObject* vtkNotUsed(object), unsigned long event, void *clientdata, void *vtkNotUsed(calldata))
356 {
357  axlLightsWidget* self = reinterpret_cast<axlLightsWidget *>( clientdata );
358 
359  //okay, let's do the right thing
360  switch(event)
361  {
362  case vtkCommand::LeftButtonPressEvent:
363  self->OnLeftButtonDown();
364  break;
365  case vtkCommand::LeftButtonReleaseEvent:
366  self->OnLeftButtonUp();
367  break;
368  case vtkCommand::MouseMoveEvent:
369  self->OnMouseMove();
370  break;
371  }
372 }
373 
374 void axlLightsWidget::PlaceWidget(double bds[6])
375 {
376  int i;
377  double bounds[6], center[3];
378 
379  this->AdjustBounds(bds, bounds, center);
380 
381  for (i=0; i<6; i++)
382  {
383  this->InitialBounds[i] = bounds[i];
384  }
385 
386  this->InitialLength = sqrt((bounds[1]-bounds[0])*(bounds[1]-bounds[0]) +
387  (bounds[3]-bounds[2])*(bounds[3]-bounds[2]) +
388  (bounds[5]-bounds[4])*(bounds[5]-bounds[4]));
389 }
390 
391 void axlLightsWidget::PrintSelf(ostream& os, vtkIndent indent)
392 {
393  this->Superclass::PrintSelf(os,indent);
394 }
395 
396 #define VTK_AVERAGE(a,b,c) \
397  c[0] = (a[0] + b[0])/2.0; \
398  c[1] = (a[1] + b[1])/2.0; \
399  c[2] = (a[2] + b[2])/2.0;
400 
401 #undef VTK_AVERAGE
402 
404 {
405  // d->interaction = true;
406  int X = this->Interactor->GetEventPosition()[0];
407  int Y = this->Interactor->GetEventPosition()[1];
408 
409  // Okay, we can process this. Try to pick handles first;
410  // if no handles picked, then pick the bounding box.
411  if (!this->CurrentRenderer || !this->CurrentRenderer->IsInViewport(X, Y))
412  {
414  return;
415  }
416 
417  d->XStartPosition =X;
418  d->YStartPosition = Y;
419 
420  vtkAssemblyPath *path = NULL;
421  d->LightCursorPicker->Pick(X, Y, 0.0, this->CurrentRenderer);
422 
423  path = d->LightCursorPicker->GetPath();
424 
425  if ( path != NULL)
426  {
428  d->LightCurrentActorIndex=this->HighlightHandle(path->GetLastNode()->GetViewProp());
429  d->LightCurrentAssemblyNode = path->GetLastNode();
430  d->LightCursorPicker->GetPickPosition(this->LastPickPosition);
431 
432  if( d->LightCurrentActorIndex == -1)
433  {
434  this->resetProperty();
436  return;
437  }
438 
439 
440  }
441  else
442  {
443  this->resetProperty();
445  return;
446  }
447  this->EventCallbackCommand->SetAbortFlag(1);
448  this->StartInteraction();
449  //this->InvokeEvent(vtkCommand::StartInteractionEvent, NULL);
450  //this->Interactor->Render();
451 }
452 
454 {
455  // d->interaction = true;
456  int X = this->Interactor->GetEventPosition()[0];
457  int Y = this->Interactor->GetEventPosition()[1];
458  // Okay, we can process this. Try to pick handles first;
459  // if no handles picked, then pick the bounding box.
460  if (!this->CurrentRenderer || !this->CurrentRenderer->IsInViewport(X, Y))
461  {
463  return;
464  }
465 
466  /*if(d->LightRubberBanPick->getCurrentMode()==1)// mode rectangle selection activated
467  {
468  vtkProp3DCollection *listProp;
469  d->LightRectanglePicker->AreaPick(d->LightRubberBanPick->getStartPositionX(),d->LightRubberBanPick->getStartPositionY(),d->LightRubberBanPick->getEndPositionX(),d->LightRubberBanPick->getEndPositionY(),this->CurrentRenderer);
470  listProp = d->LightRectanglePicker->GetProp3Ds();
471  if ( listProp != NULL )
472  {
473  vtkCollectionIterator *listPropIterator =listProp->NewIterator();
474  listPropIterator->InitTraversal();
475  while(!listPropIterator->IsDoneWithTraversal())
476  {
477  static_cast<vtkActor *>(listPropIterator->GetCurrentObject())->SetProperty(d->LightSelectedHandleProperty);
478  listPropIterator->GoToNextItem();
479  }
480  }
481 
482  }*/
483 
484  if ( this->State == axlLightsWidget::Outside || this->State == axlLightsWidget::Start )
485  {
486  return;
487  }
488 
489 
491 
492  this->EventCallbackCommand->SetAbortFlag(0);
493  this->EndInteraction();
494  this->InvokeEvent(vtkCommand::EndInteractionEvent, NULL);
495 }
496 
498 {
499  // See whether we're active
500  if ( this->State == axlLightsWidget::Outside ||
501  this->State == axlLightsWidget::Start )
502  {
503  return;
504  }
505 
506  int X = this->Interactor->GetEventPosition()[0];
507  int Y = this->Interactor->GetEventPosition()[1];
508 
509  // Do different things depending on state
510  // Calculations everybody does
511  double focalPoint[4], pickPoint[4], prevPickPoint[4], motionVector[4];
512  double z;
513 
514  vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
515  if ( !camera )
516  {
517  return;
518  }
519 
520  // Compute the two points defining the motion vector
521  this->ComputeWorldToDisplay(this->LastPickPosition[0], this->LastPickPosition[1], this->LastPickPosition[2], focalPoint);
522  z = focalPoint[2];
523  this->ComputeDisplayToWorld(double(this->Interactor->GetLastEventPosition()[0]),double(this->Interactor->GetLastEventPosition()[1]),
524  z, prevPickPoint);
525  this->ComputeDisplayToWorld(double(X), double(Y), z, pickPoint);
526  for(int i=0;i<4;i++)
527  {
528  motionVector[i]=pickPoint[i]-prevPickPoint[i];
529  }
530 
531  vtkMatrix4x4 *motion = vtkMatrix4x4::New();
532 
533  if(d->LightCurrentAssemblyNode)
534  motion->DeepCopy(d->LightCurrentAssemblyNode->GetMatrix());
535  motion->Invert();
536 
537  if ( this->State == axlLightsWidget::Moving )
538  { // Okay to process
539 
540  vtkRenderWindow *renderWindow = this->Interactor->GetRenderWindow();
541  vtkRendererCollection * rendererCollection = renderWindow->GetRenderers();
542  vtkRenderer *render = rendererCollection->GetFirstRenderer();
543 
544  vtkLightCollection *lightCollection = render->GetLights();
545  lightCollection->InitTraversal();
546 
547  vtkLight *currentLight = NULL;
548 
549  // set CurrentLight to the Light picked
550  for(int i = 0; i<= d->LightCurrentActorIndex; i++)
551  currentLight = lightCollection->GetNextItem();
552 
553 
554  double *newMotion = motion->MultiplyDoublePoint(motionVector);
555  double newPosition[4];
556  for(int j = 0 ;j < 4; j++)
557  {
558  newPosition[j]=d->LightPoints->GetPoint(d->LightCurrentActorIndex)[j]+newMotion[j];
559  }
560 
561  d->LightPoints->SetPoint(d->LightCurrentActorIndex, newPosition[0], newPosition[1], newPosition[2]);
562  d->LightPoints->Modified();
563  d->LightSphere[d->LightCurrentActorIndex]->SetCenter(d->LightPoints->GetPoint(d->LightCurrentActorIndex));
564  currentLight->SetPosition(newPosition[0], newPosition[1], newPosition[2]);
565 
566  d->LightProp[d->LightCurrentActorIndex]->SetPosition(newPosition[0], newPosition[1], newPosition[2]);
567  d->LightSphere[d->LightCurrentActorIndex]->Update();
568  d->LightProp[d->LightCurrentActorIndex]->Modified();
569 
570  d->view->onLightPositionChanged(newPosition[0], newPosition[1], newPosition[2]);
571 
572  }
573  else
574  {
575  return; //avoid the extra render
576  }
577 
578  motion->Delete();
579 
580  this->EventCallbackCommand->SetAbortFlag(1);
581  this->InvokeEvent(vtkCommand::InteractionEvent,NULL);
582  this->Interactor->Render();
583 }
584 
585 
587 {
588  vtkRenderWindow *renderWindow = this->Interactor->GetRenderWindow();
589  vtkRendererCollection * rendererCollection = renderWindow->GetRenderers();
590  vtkRenderer *render = rendererCollection->GetFirstRenderer();
591 
592  vtkLightCollection *lightCollection = render->GetLights();
593  lightCollection->InitTraversal();
594 
595  vtkLight *currentLight = NULL;
596 
597  for(int i = 0 ; i < d->NbLight ; i++)
598  {
599  d->LightCurrentActorIndex = i;
600  // set CurrentLight to the Light picked
601  currentLight = lightCollection->GetNextItem();
602 
603 
604  double newPosition[4];
605  for(int j = 0 ;j < 4; j++)
606  {
607  newPosition[j]=currentLight->GetPosition()[j];
608  }
609 
610  d->LightPoints->SetPoint(d->LightCurrentActorIndex, newPosition[0], newPosition[1], newPosition[2]);
611  d->LightPoints->Modified();
612  d->LightSphere[d->LightCurrentActorIndex]->SetCenter(d->LightPoints->GetPoint(d->LightCurrentActorIndex));
613  currentLight->SetPosition(newPosition[0], newPosition[1], newPosition[2]);
614  d->LightSphere[d->LightCurrentActorIndex]->Update();
615  d->LightSphere[d->LightCurrentActorIndex]->Modified();
616  d->LightProp[d->LightCurrentActorIndex]->SetPosition(newPosition[0], newPosition[1], newPosition[2]);
617  // d->LightSphere[d->LightCurrentActorIndex]->Update();
618  d->LightActor[d->LightCurrentActorIndex]->Modified();
619  }
620 
621  this->Interactor->Render();
622 }
623 
625 {
626  // Handle properties
627  d->LightHandleProperty = vtkProperty::New();
628  d->LightHandleProperty->SetColor(1,1,1);
629 
630  d->LightSelectedHandleProperty = vtkProperty::New();
631  d->LightSelectedHandleProperty->SetColor(1,0,0);
632 }
633 
void PrintSelf(ostream &os, vtkIndent indent)
vtkActorCollection * ptsActors(void)
void initializePoints(void)
static void ProcessEvents(vtkObject *object, unsigned long event, void *clientdata, void *calldata)
vtkStandardNewMacro(axlLightsWidget)
virtual void OnLeftButtonDown(void)
void resetProperty(void)
virtual void OnLeftButtonUp(void)
void setView(axlAbstractView *view)
int HighlightHandle(vtkProp *prop)
void PlaceWidget(void)
virtual void OnMouseMove(void)
void CreateDefaultProperties(void)