Developer documentation | Axl-2.5.1

axlActorCone.cpp
Go to the documentation of this file.
1 /* axlActorCone.cpp ---
2  *
3  * Author: Meriadeg Perrinel
4  * Copyright (C) 2008 - Meriadeg Perrinel, Inria.
5  * Created: Fri Dec 17 10:59:21 2010 (+0100)
6  * Version: $Id$
7  * Last-Updated: Mon Dec 17 15:01:03 2012 (+0100)
8  * By: Julien Wintz
9  * Update #: 40
10  */
11 
12 /* Commentary:
13  *
14  */
15 
16 /* Change log:
17  *
18  */
19 
20 #include "axlActorCone.h"
21 #include "axlActorComposite.h"
23 
24 #include <axlCore/axlCone.h>
25 #include <axlCore/axlPoint.h>
26 
27 #include <QVTKOpenGLWidget.h>
28 
29 #include <vtkActor.h>
30 #include <vtkAssemblyPath.h>
31 //#include <vtkCellPicker.h>
32 #include <vtkCommand.h>
33 #include <vtkGlyph3D.h>
34 #include <vtkInteractorStyleSwitch.h>
35 #include <vtkLight.h>
36 #include <vtkLightCollection.h>
37 #include <vtkConeSource.h>
38 #include <vtkLineWidget.h>
39 #include <vtkObjectFactory.h>
40 #include <vtkPoints.h>
41 #include <vtkPointWidget.h>
42 #include <vtkPolyData.h>
43 #include <vtkPolyDataMapper.h>
44 #include <vtkDataSetMapper.h>
45 #include <vtkProperty.h>
46 #include <vtkRenderer.h>
47 #include <vtkRendererCollection.h>
48 #include <vtkRenderWindow.h>
49 #include <vtkRenderWindowInteractor.h>
50 #include <vtkSmartPointer.h>
51 #include <vtkTransform.h>
52 
53 class axlActorConeObserver : public vtkCommand
54 {
55 public:
56  static axlActorConeObserver *New(void)
57  {
58  return new axlActorConeObserver;
59  }
60 
61  virtual void Execute(vtkObject *caller, unsigned long event, void *)
62  {
63  //vtkRenderWindowInteractor *interactor = observerDataAssembly->getInteractor(); //interactor->Render();
64 
65  if(event == vtkCommand::InteractionEvent)
66  {
67  if(!lineWidget || !radiusWidget)
68  return;
69 
70  // NOTICE : We can improve this code...
71  if (caller == lineWidget)
72  {
73 // axlPoint p1(lineWidget->GetPoint1()[0], lineWidget->GetPoint1()[1], lineWidget->GetPoint1()[2]);
74 // axlPoint p2(lineWidget->GetPoint2()[0], lineWidget->GetPoint2()[1], lineWidget->GetPoint2()[2]);
75 // if(!(axlPoint::distance(&p1, observerData_cone->apex())< 0.0001 && axlPoint::distance(&p2, observerData_cone->basePoint())<0.0001))
76 // {// There we move the line widget
77  observerData_coneSource->Update();
78  observerData_coneSource->Modified();
79  observerData_cone->setApex(lineWidget->GetPoint1());
83 // }
84  }
85  else if (caller == radiusWidget)
86  {// There we move the point widget
87 
88  axlPoint center = (*(observerData_cone->apex())+(*(observerData_cone->basePoint()))) / 2.0;
89  axlPoint p3(radiusWidget->GetPosition()[0], radiusWidget->GetPosition()[1], radiusWidget->GetPosition()[2]);
90  axlPoint mp3 = p3 - center;
92  double pv = (mp3.x() * p1p2.x() + mp3.y() * p1p2.y() + mp3.z() * p1p2.z());
93 
94  axlPoint ps = p1p2 * pv;
95  double norm = observerData_cone->length();
96 
97  axlPoint c = p3 - (ps /= (norm*norm));
98 
99  radiusWidget->SetPosition(c.coordinates());
100  double r = axlPoint::distance(&c, &center);
101 
103  observerData_coneSource->SetRadius(r);
104  observerData_coneSource->Update();
105  observerData_coneSource->Modified();
107  if(!observerData_cone->fields().isEmpty())
109  }
110  }
111  }
112 
114 // vtkCellPicker *axlConePicker;
117  vtkConeSource *observerData_coneSource;
118 
119  vtkLineWidget *lineWidget=nullptr;
120  vtkPointWidget *radiusWidget=nullptr;
121 
122 };
123 
124 // /////////////////////////////////////////////////////////////////
125 // axlActorConePrivate
126 // /////////////////////////////////////////////////////////////////
127 
128 class axlActorConePrivate
129 {
130 public:
131  axlCone *cone;
132  vtkConeSource *coneSource;
133  vtkPointWidget *radiusWidget;
134  vtkLineWidget *lineWidget;
135  axlActorConeObserver *coneObserver;
136  QVTKOpenGLWidget *widget;
137 // vtkCellPicker *axlConePicker ;
138 
139 };
140 
141 #if (VTK_MAJOR_VERSION <= 5)
142 vtkCxxRevisionMacro(axlActorCone, "$Revision: 0.0.1 $");
143 #endif
144 
146 
147 dtkAbstractData *axlActorCone::data(void)
148 {
149  return d->cone;
150 }
151 
152 vtkConeSource *axlActorCone::cone(void)
153 {
154  return d->coneSource;
155 }
156 
157 vtkSmartPointer<vtkPolyData> axlActorCone::getPolyData(){
158  return d->coneSource->GetOutput();
159 }
160 
161 void axlActorCone::setQVTKWidget(QVTKOpenGLWidget *widget)
162 {
163  d->widget = widget;
164 }
165 
166 
167 void axlActorCone::setData(dtkAbstractData *cone1)
168 {
169  axlCone *cone = dynamic_cast<axlCone *>(cone1);
170 
171  if(cone)
172  {
173  d->cone = cone;
174  this->setMapper(vtkSmartPointer<vtkPolyDataMapper>::New());
175  //this->setDataSetMapper(vtkSmartPointer<vtkDataSetMapper>::New());
176  this->setActor(vtkSmartPointer<vtkActor>::New());
177 
178  d->coneSource = vtkConeSource::New();
179  // d->coneSource->SetPoint1(d->cone->apex()->coordinates());
180  // d->coneSource->SetPoint2(d->cone->basePoint()->coordinates());
181 
182  d->coneSource->SetResolution(200);
183  d->coneSource->SetDirection(0.0, 1.0, 0.0);
184 
185  //this->SetPosition(d->cone->coordinates());
186 
187  // connection of data to actor
188  //this->getMapper()->SetInput(d->coneSource->GetOutput());
189  //this->setPolyData(d->coneSource->GetOutput());
190 
191  this->onUpdateGeometry();
192 #if (VTK_MAJOR_VERSION <= 5)
193  this->getMapper()->SetInput(d->coneSource->GetOutput());
194  //this->getDataSetMapper()->SetInput(d->coneSource->GetOutput());
195 #else
196  this->getMapper()->SetInputData(d->coneSource->GetOutput());
197  //this->getDataSetMapper()->SetInputData(d->coneSource->GetOutput());
198 #endif
199  this->getActor()->SetMapper(this->getMapper());
200  //this->getActor()->SetMapper(this->getDataSetMapper());
201 
202  this->AddPart(this->getActor());
203 
204  if(!d->coneObserver)
205  {
206 // d->axlConePicker = vtkCellPicker::New();
207  d->coneObserver = axlActorConeObserver::New() ;
208  this->getInteractor()->AddObserver(vtkCommand::InteractionEvent, d->coneObserver);
209  this->getInteractor()->AddObserver(vtkCommand::MouseMoveEvent, d->coneObserver);
210 
211 
212  d->coneObserver->observerDataAssembly = this;
213 // d->coneObserver->axlConePicker = d->axlConePicker;
214  d->coneObserver->observerData_coneSource = d->coneSource;
215  d->coneObserver->observerData_cone = d->cone;
216  d->coneObserver->axlInteractorStyle = dynamic_cast<axlInteractorStyleSwitch *> (this->getInteractor()->GetInteractorStyle());
217  }
218 
219  QColor color = d->cone->color();
220  this->getActor()->GetProperty()->SetColor(color.redF(), color.greenF(), color.blueF());
221 
222  QString shader = d->cone->shader();
223  if(!shader.isEmpty())
224  this->setShader(shader);
225 
226  //this->getActor()->SetScale(d->cone->size());
227 
228  this->setOpacity(d->cone->opacity());
229 
230  connect(d->cone,SIGNAL(modifiedGeometry()),this,SLOT(onUpdateGeometry()));
231  connect(d->cone,SIGNAL(modifiedProperty()),this,SLOT(onUpdateProperty()));
232  }
233  else
234  qDebug()<< "no axlCone available";
235 
236 }
237 
238 
239 void axlActorCone::setDisplay(bool display)
240 {
241  axlActor::setDisplay(display);
242 
243  if(display && d->lineWidget){
244  this->showConeWidget(true);
245  }
246 
247  if(!display && d->lineWidget){
248  this->showConeWidget(false);
249  }
250 }
251 
253 {
254  if(!d->lineWidget || !d->radiusWidget) {
255  qDebug() << "No tet actor computed for this axlActorCone.";
256  return;
257  }
258 
259  if(show){
260  d->lineWidget->SetEnabled(1);
261  d->radiusWidget->SetEnabled(1);
262  }
263 
264  if(!show){
265  d->lineWidget->SetEnabled(0);
266  d->radiusWidget->SetEnabled(0);
267 
268  }
269 }
270 
271 void axlActorCone::setConeWidget(bool coneWidget)
272 {
273 
274  if(coneWidget) {
275  if(!d->lineWidget || !d->radiusWidget)
276  {
277  //widget drawing
278 
279  d->lineWidget = vtkLineWidget::New();
280  d->lineWidget->SetInteractor(this->getInteractor());
281  d->lineWidget->SetProp3D(this->getActor());
282  d->lineWidget->PlaceWidget();
283  d->lineWidget->SetPoint1(d->cone->apex()->coordinates());
284  d->lineWidget->SetPoint2(d->cone->basePoint()->coordinates());
285 
286  d->radiusWidget = vtkPointWidget::New();
287  d->radiusWidget->SetInteractor(this->getInteractor());
288  d->radiusWidget->SetProp3D(this->getActor());
289  d->radiusWidget->PlaceWidget();
290  d->radiusWidget->AllOff();
291  d->radiusWidget->SetTranslationMode(1);
292 // axlPoint v = *(d->cone->apex())+(*(d->cone->basePoint()));
293 // //normal of v with 0 in x
294 // axlPoint n(-v.y(), v.x(), v.z());
295 // if(v.x() < 0.0005 && v.y() < 0.0005)
296 // n.setCoordinates(1.0, 0.0, 0.0); // need if cone is in z direction
297 // n.normalize();
298 // n *= d->cone->radius();
299 // v /= 2.0;
300 //
301 // v += n;
302 //
303 // d->radiusWidget->SetPosition(v.x(), v.y(), v.z());
304  axlPoint center = (*(d->cone->apex())+(*(d->cone->basePoint()))) / 2.0;
305  axlPoint p1p2 = (*(d->cone->basePoint())-(*(d->cone->apex())));
306  axlPoint mp3(1.0, 1.0, 1.0);
307  //axlPoint pv(mp3.y() * p1p2.z() - mp3.z() * p1p2.y(), mp3.x() * p1p2.z() - mp3.z() * p1p2.x(), mp3.x() * p1p2.y() - mp3.y() * p1p2.x());
308  axlPoint pv = axlPoint::crossProduct(mp3, p1p2);
309  pv.normalize();
310  pv *= (1 * d->cone->radius());
311  pv += center;
312  d->radiusWidget->SetPosition(pv.coordinates());
313  }
314 
315  if(d->coneObserver)
316  {
317  d->lineWidget->AddObserver(vtkCommand::InteractionEvent, d->coneObserver);
318  d->radiusWidget->AddObserver(vtkCommand::InteractionEvent, d->coneObserver);
319 
320 
321  d->coneObserver->lineWidget = d->lineWidget;
322  d->coneObserver->radiusWidget = d->radiusWidget;
323  }
324 
325  // there is always the controlPoints there
326  d->lineWidget->SetEnabled(true);
327  d->radiusWidget->SetEnabled(true);
328 
329 
330 
331  }
332 
333  if (!coneWidget)
334  {
335  if (this->getActor()) {
336  // this->getMapper()->SetInput(this->getPolyData());
337 
338  if(d->lineWidget)
339  {
340  d->lineWidget->RemoveAllObservers();
341  d->lineWidget->SetEnabled(false);
342  d->lineWidget->Delete(); // warning not sure
343  d->lineWidget = NULL;
344  }
345 
346  if(d->radiusWidget)
347  {
348  d->radiusWidget->RemoveAllObservers();
349  d->radiusWidget->SetEnabled(false);
350  d->radiusWidget->Delete(); // warning not sure
351  d->radiusWidget = NULL;
352  }
353  }
354  }
355  if (d->coneObserver){
356  d->coneObserver->lineWidget = d->lineWidget;
357  d->coneObserver->radiusWidget = d->radiusWidget;
358  }
359 }
360 
362 {
363 
364  if(!d->lineWidget || !d->radiusWidget) {
365  qDebug() << "No tet actor computed for this axlActorBSpline.";
366  return false;
367  }
368 
369  return d->lineWidget->GetEnabled() && d->radiusWidget->GetEnabled();
370 }
371 
372 
373 void axlActorCone::setMode(int state)
374 {
375  this->onModeChanged(state);
376 
377  emit stateChanged(this->data(), state);
378 }
379 
381 {
382  if(state == 0)
383  {
385  this->getActor()->SetPickable(1);
386 
387  if(axlAbstractData *data = dynamic_cast<axlAbstractData *>(this->data()))
388  {
389  QColor color = data->color();
390  this->getActor()->GetProperty()->SetColor(color.redF(), color.greenF(), color.blueF());
391  }
392  this->setConeWidget(false);
393 
394  }
395  else if(state == 1)
396  {
397 
399  this->setConeWidget(false);
400  this->getActor()->SetPickable(1);
401  vtkProperty *prop = this->getActor()->GetProperty();
402 
403  if(axlAbstractData *data = dynamic_cast<axlAbstractData *>(this->data()))
404  {
405  QColor color = data->color();
406  qreal *h = new qreal(0.0);
407  qreal *s = new qreal(0.0);
408  qreal *l = new qreal(0.0);
409  color.getHslF(h, s, l);
410  color.setHslF(*h, *s, *l + (1.0 - *l) / 2.0);
411  prop->SetColor(color.redF(), color.greenF(), color.blueF());
412  delete l;
413  delete s;
414  delete h;
415  }
416 
417  }
418  else if(state == 2)
419  {
421  this->setConeWidget(true);
422  this->getActor()->SetPickable(0);
423  vtkProperty *prop = this->getActor()->GetProperty();
424  if(axlAbstractData *data = dynamic_cast<axlAbstractData *>(this->data()))
425  {
426  QColor color = data->color();
427  qreal *h = new qreal(0.0);
428  qreal *s = new qreal(0.0);
429  qreal *l = new qreal(0.0);
430  color.getHslF(h, s, l);
431  color.setHslF(*h, *s, *l + (1.0 - *l)/2.0);
432  prop->SetColor(color.redF(), color.greenF(), color.blueF());
433  delete l;
434  delete s;
435  delete h;
436  }
437  }
438 
439  this->Modified();
440 }
441 
442 
444 {
445  // if on edit mode, change to selection mode (for stability)
446  if (this->getState() == 2)
447  setMode(1);
448 
449  //remove line specificity
450  if(d->coneObserver)
451  {
452  this->getInteractor()->RemoveObservers(vtkCommand::InteractionEvent, d->coneObserver);
453  this->getInteractor()->RemoveObservers(vtkCommand::MouseMoveEvent, d->coneObserver);
454  d->coneObserver->observerDataAssembly = NULL;
455 // d->coneObserver->axlConePicker = NULL;
456  d->coneObserver->observerData_coneSource = NULL;
457  d->coneObserver->observerData_cone = NULL;
458  d->coneObserver->axlInteractorStyle = NULL;
459  d->coneObserver->Delete();
460  d->coneObserver = NULL;
461 
462 // d->axlConePicker->Delete();
463 // d->axlConePicker = NULL;
464 
465  }
466  if(d->coneSource)
467  {
468  d->coneSource->Delete();
469  d->coneSource = NULL;
470  }
471  if(d->widget)
472  {
473  d->widget = NULL;
474  }
475  if(d->cone)
476  {
477  d->cone = NULL;
478  }
479  if(d->lineWidget && d->radiusWidget)
480  {
481  this->setConeWidget(false);
482  d->lineWidget = NULL;
483  d->radiusWidget = NULL;
484  }
485 
486  //remove actor specificity
487  this->RemoveAllObservers();
488  this->RemovePart(this->getActor());
489  this->getActor()->RemoveAllObservers();
490 
491  if(axlActorComposite *actorComposite = dynamic_cast<axlActorComposite *>(this->parent()) )
492  actorComposite->removeActorReference(this);
493 }
494 
496 {
497 
498  d->coneSource->SetHeight(axlPoint::distance(d->cone->apex(), d->cone->basePoint()));
499  d->coneSource->SetRadius(d->cone->radius());
500  //d->coneSource->SetResolution(100);
501  d->coneSource->Modified();
502  d->coneSource->Update();
503 
504  if(d->lineWidget)
505  {
506  d->lineWidget->SetPoint1(d->cone->apex()->coordinates());
507  d->lineWidget->SetPoint2(d->cone->basePoint()->coordinates());
508  }
509 
510  axlPoint center = (*(d->cone->apex())+(*(d->cone->basePoint()))) / 2.0;
511 
512  // Find the good axes
513  axlPoint v = *(d->cone->apex()) - center;
514  v.normalize();
515 
516  // vectorial product
517  axlPoint n(-v.z(), 0.0, v.x());
518  if(!(fabs(n.x()) < 0.00001 && fabs(n.z()) < 0.0001))// vectorial product is not null
519  {
520  n.normalize();
521  //rotation
522  this->getActor()->SetOrientation(0.0, 0.0, 0.0);
523  this->getActor()->RotateWXYZ(-acos(v.y()) * 180 / 3.14159, n.x(), 0.0, n.z());
524  }
525 
526  if(d->radiusWidget) {
527  axlPoint p1p2 = (*(d->cone->basePoint())-(*(d->cone->apex())));
528  axlPoint mp3(1.0, 1.0, 1.0);
529 
530  //axlPoint pv(mp3.y() * p1p2.z() - mp3.z() * p1p2.y(), mp3.x() * p1p2.z() - mp3.z() * p1p2.x(), mp3.x() * p1p2.y() - mp3.y() * p1p2.x());
531  axlPoint pv = axlPoint::crossProduct(mp3, p1p2);
532  pv.normalize();
533  pv *= d->cone->radius();
534  pv += center;
535 
536  d->radiusWidget->SetPosition(pv.coordinates());
537  }
538 
539  //Translation
540  this->getActor()->SetPosition(center.coordinates());
541 
542  //Update fields.
543  if(!d->cone->fields().isEmpty())
544  d->cone->touchField();
545 
546  if(d->cone->updateView())
547  emit updated();
548 }
549 
550 axlActorCone::axlActorCone(void) : axlActor(), d(new axlActorConePrivate)
551 {
552  d->cone = NULL;
553  d->lineWidget = NULL;
554  d->radiusWidget = NULL;
555 // d->axlConePicker = NULL;
556  d->coneObserver = NULL;
557  d->coneSource =NULL;
558  d->widget = NULL;
559 }
560 
562 {
563  delete d;
564 
565  d = NULL;
566 }
567 
568 
570 
571  return axlActorCone::New();
572 }
void touchGeometry(void)
Class axlPoint defines 3D points.
Definition: axlPoint.h:34
vtkConeSource * observerData_coneSource
void onUpdateGeometry()
virtual void touchField(void)
virtual void setDisplay(bool display)
Definition: axlActor.cpp:440
double * coordinates(void) const
Returns coordinates of this point.
Definition: axlPoint.cpp:445
static axlActorConeObserver * New(void)
void stateChanged(dtkAbstractData *data, int mode)
axlPoint apex
Definition: axlCone.h:37
void showConeWidget(bool show)
void setQVTKWidget(QVTKOpenGLWidget *widget)
axlPoint basePoint
Definition: axlCone.h:37
static axlActorCone * New(void)
void setApex(axlPoint *apex)
Change apex of this cone.
Definition: axlCone.cpp:185
axlAbstractActor * createAxlActorCone(void)
virtual void setState(int state)
Definition: axlActor.cpp:434
void setRadius(double radius)
Change radius of this cone.
Definition: axlCone.cpp:221
virtual void Execute(vtkObject *caller, unsigned long event, void *)
void setConeWidget(bool coneWidget)
virtual int getState(void)
Definition: axlActor.cpp:429
vtkPointWidget * radiusWidget
void setMode(int state)
void updated(void)
bool isShowConeWidget(void)
vtkStandardNewMacro(axlActorCone)
void normalize(void)
Definition: axlPoint.cpp:410
virtual void setShader(QString vsfile)
Definition: axlActor.cpp:517
double length(void) const
Returns length of the cone.
Definition: axlCone.cpp:163
virtual axlAbstractActor * parent(void)
virtual void setOpacity(double opacity)
Definition: axlActor.cpp:461
virtual void setData(dtkAbstractData *cone1)
axlInteractorStyleSwitch * axlInteractorStyle
void setMapper(vtkSmartPointer< vtkPolyDataMapper > mapper)
Definition: axlActor.cpp:332
void setActor(vtkSmartPointer< vtkActor > actor)
Definition: axlActor.cpp:322
vtkSmartPointer< vtkActor > getActor(void)
Definition: axlActor.cpp:317
double y
Definition: axlPoint.h:37
virtual void onUpdateProperty(void)
vtkSmartPointer< vtkPolyDataMapper > getMapper(void)
Definition: axlActor.cpp:327
dtkAbstractData * data(void)
double z
Definition: axlPoint.h:38
vtkConeSource * cone(void)
vtkSmartPointer< vtkPolyData > getPolyData()
Class axlCone defines 3D cones.
Definition: axlCone.h:34
void setDisplay(bool display)
void onModeChanged(int state)
vtkLineWidget * lineWidget
vtkCxxRevisionMacro(axlActorCone,"$Revision: 0.0.1 $")
QList< axlAbstractField * > fields(void)
static axlPoint crossProduct(const axlPoint &lhs, const axlPoint &rhs)
Returns the cross product between lhs (coords) and rhs (coords).
Definition: axlPoint.cpp:485
void setBasePoint(axlPoint *basePoint)
Change base point of this cone.
Definition: axlCone.cpp:203
static double distance(const axlPoint &lhs, const axlPoint &rhs)
Returns the distance between lhs point and rhs point.
Definition: axlPoint.cpp:459
double x
Definition: axlPoint.h:37
virtual vtkRenderWindowInteractor * getInteractor(void)
Definition: axlActor.cpp:264
Class axlAbstractData defines an API for all type of axel data.
axlActorCone * observerDataAssembly