Salome HOME
044d5ba33142bf1a1d826106b1c043764dc461c1
[modules/gui.git] / src / VTKViewer / VTKViewer_Trihedron.cxx
1 // Copyright (C) 2007-2021  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include "VTKViewer_Trihedron.h"
24 #include "VTKViewer_Actor.h"
25 #include "VTKViewer_Algorithm.h"
26
27 // VTK Includes
28 #include <vtkConfigure.h>
29 #include <vtkMath.h>
30 #include <vtkMapper.h>
31 #include <vtkDataSet.h>
32 #include <vtkRenderer.h>
33 #include <vtkRenderWindow.h>
34 #include <vtkObjectFactory.h>
35
36 #include <vtkActor.h>
37 #include <vtkProperty.h>
38 #include <vtkLineSource.h>
39 #include <vtkConeSource.h>
40 #include <vtkPolyDataMapper.h>
41 #include <vtkPolyDataMapper2D.h>
42 #include <vtkVectorText.h>
43 #include <vtkTextActor.h>
44 #include <vtkTextMapper.h>
45 #include <vtkTextProperty.h>
46
47 // QT includes
48 #include <QtGlobal>
49
50 vtkStandardNewMacro(VTKViewer_UnScaledActor)
51
52 /*!Constructor*/
53 VTKViewer_UnScaledActor::VTKViewer_UnScaledActor() 
54 {
55   Bounds[0] = Bounds[2] = Bounds[4] = VTK_FLOAT_MAX;
56   Bounds[1] = Bounds[3] = Bounds[5] = -VTK_FLOAT_MAX;
57 }
58
59 /*!
60   \return bounding box
61 */
62 double* 
63 VTKViewer_UnScaledActor
64 ::GetBounds()
65 {
66   return Bounds;
67 }
68
69 /*! Sets \a mySize= \a theSize variable.
70  * \param  theSize - integer size
71  */
72 void VTKViewer_UnScaledActor::SetSize(int theSize)
73 {
74   mySize = theSize;
75 }
76
77 /*!This causes the actor to be rendered.
78  * Set new scale for actor.
79  */
80 void VTKViewer_UnScaledActor::Render(vtkRenderer *theRenderer)
81 {
82   if(theRenderer){
83     double P[2][3] = {{-1.0, -1.0, 0.0},{+1.0, +1.0, 0.0}};
84     theRenderer->ViewToWorld(P[0][0],P[0][1],P[0][2]);
85     theRenderer->ViewToWorld(P[1][0],P[1][1],P[1][2]);
86     double aWorldDiag = sqrt((P[1][0]-P[0][0])*(P[1][0]-P[0][0])+
87                                            (P[1][1]-P[0][1])*(P[1][1]-P[0][1])+
88                                            (P[1][2]-P[0][2])*(P[1][2]-P[0][2]));
89     int* aSize = theRenderer->GetRenderWindow()->GetSize();
90     double aWinDiag = sqrt(double(aSize[0]*aSize[0]+aSize[1]*aSize[1]));
91     vtkDataSet* aDataSet = GetMapper()->GetInput();
92     GetMapper()->Update();
93     double aLength = aDataSet->GetLength();
94     double aPrecision = 1.0E-3;
95     double aZeroTol   = 1.0E-12;
96     double anOldScale = GetScale()[0];
97     double aScale = anOldScale;
98     double aMaxSize = (double)qMax(aSize[1],aSize[0]);
99     if (qAbs(aWinDiag) > aZeroTol && qAbs(aLength) > aZeroTol && qAbs(aMaxSize) > aZeroTol)
100       aScale = mySize*aWorldDiag/aWinDiag/aLength*sqrt(double(qMin(aSize[1],aSize[0]))/aMaxSize);
101     if(qAbs(aScale) > aZeroTol && qAbs(aScale - anOldScale)/aScale > aPrecision){
102       SetScale(aScale);
103     }
104   }
105   vtkFollower::Render(theRenderer);
106 }
107
108 vtkStandardNewMacro(VTKViewer_LineActor)
109
110 #ifdef IPAL21440
111 vtkCxxSetObjectMacro(VTKViewer_LineActor,LabelActor,vtkTextActor);
112 #else
113 vtkCxxSetObjectMacro(VTKViewer_LineActor,LabelActor,VTKViewer_UnScaledActor)
114 #endif
115 vtkCxxSetObjectMacro(VTKViewer_LineActor,ArrowActor,vtkFollower)
116
117 /*!Adds Label and Arrow actors to \a theRenderer.*/
118 void VTKViewer_LineActor::Render(vtkRenderer *theRenderer)
119 {
120 #ifndef IPAL21440
121   if(LabelActor && LabelActor->GetVisibility()){
122     LabelActor->Modified();
123     LabelActor->Render(theRenderer);
124   }
125 #endif
126   if(ArrowActor && ArrowActor->GetVisibility()){
127     ArrowActor->Modified();
128     ArrowActor->Render(theRenderer);
129   }
130   vtkFollower::Render(theRenderer);
131 }
132
133 /*!
134   Constructor
135 */
136 VTKViewer_Axis::VTKViewer_Axis()
137 {
138   /*! \li Initialize the Line pipe-line representation*/
139   myLineSource = vtkLineSource::New();
140   myLineSource->SetPoint1(0.0,0.0,0.0);
141   
142   myMapper[0] = vtkPolyDataMapper::New();
143   myMapper[0]->SetInputConnection(myLineSource->GetOutputPort());
144   
145   myLineActor = VTKViewer_LineActor::New();
146   myLineActor->SetMapper(myMapper[0]);
147   myLineActor->PickableOff();
148   
149   /*! \li Initialize the Arrow pipe-line representation*/
150   myConeSource =  vtkConeSource::New();
151   myConeSource->SetResolution(16);
152   myConeSource->SetAngle(10);
153   myConeSource->SetCenter(-0.5,0.0,0.0);
154   
155   myMapper[1] = vtkPolyDataMapper::New();
156   myMapper[1]->SetInputConnection(myConeSource->GetOutputPort());
157   
158   myArrowActor = vtkFollower::New();
159   myArrowActor->SetMapper(myMapper[1]);
160   static int aArrowActorSize = 16;
161   myArrowActor->SetScale(aArrowActorSize);
162   myArrowActor->PickableOff();
163   
164   myLineActor->SetArrowActor(myArrowActor);
165   
166   /*! \li Initialize the Label pipe-line representation */
167 #ifdef IPAL21440
168   myTextMapper = vtkTextMapper::New();
169   
170   myLabelActor = vtkTextActor::New();
171   myLabelActor->SetMapper(myTextMapper);
172   myLabelActor->SetTextScaleModeToNone();
173   myLabelActor->PickableOff();
174   
175   vtkCoordinate* aCoord = vtkCoordinate::New();
176   myLabelActor->GetPositionCoordinate()->SetReferenceCoordinate( aCoord );
177   aCoord->Delete();
178 #else
179   myVectorText = vtkVectorText::New();
180   
181   myMapper[2] = vtkPolyDataMapper::New();
182   myMapper[2]->SetInputConnection(myVectorText->GetOutputPort());
183   
184   myLabelActor = VTKViewer_UnScaledActor::New();
185   myLabelActor->SetMapper(myMapper[2]);
186   static int aLabelActorSize = 12;
187   myLabelActor->SetSize(aLabelActorSize);
188   myLabelActor->PickableOff();
189   //myLabelActor->DebugOn();
190 #endif
191   
192   myLineActor->SetLabelActor(myLabelActor);
193   
194   /*! \li Initialise visibility param.*/
195   myVisibility = VTKViewer_Trihedron::eOn;
196 }
197
198 /*!
199   Destructor
200 */
201 VTKViewer_Axis::~VTKViewer_Axis()
202 {
203   /*! \li Destroy of the Label pipe-line representation */
204   myLabelActor->Delete();
205   
206   myMapper[0]->RemoveAllInputs();
207   myMapper[0]->Delete();
208   
209   /*! \li Destroy of the Arrow pipe-line representation */
210   myArrowActor->Delete();
211   
212   myMapper[1]->RemoveAllInputs();
213   myMapper[1]->Delete();
214   
215   myConeSource->Delete();
216   
217   /*! \li Destroy of the Line pipe-line representation */
218   myLineActor->Delete();
219   
220 #ifdef IPAL21440
221   myTextMapper->RemoveAllInputs();
222   myTextMapper->Delete();
223 #else
224   myVectorText->Delete();
225   
226   myMapper[2]->RemoveAllInputs();
227   myMapper[2]->Delete();
228 #endif
229   
230   myLineSource->Delete();
231 }
232
233 /*! Add to renderer
234  * \param theRenderer - vtkRenderer pointer
235  */
236 void VTKViewer_Axis::AddToRender(vtkRenderer* theRenderer){
237   /*! \li Order of the calls are important*/
238   theRenderer->AddActor(myLineActor);
239   theRenderer->AddActor(myLabelActor);
240   theRenderer->AddActor(myArrowActor);
241 }
242
243 /*! Remove actor of acis from \a theRenderer which are in myPresent.
244  * \param theRenderer - vtkRenderer pointer
245  */
246 void VTKViewer_Axis::RemoveFromRender(vtkRenderer* theRenderer){
247   /*! \li Order of the calls are important*/
248   theRenderer->RemoveActor(myLineActor);
249   theRenderer->RemoveActor(myLabelActor);
250   theRenderer->RemoveActor(myArrowActor);
251 }
252
253 /*! Sets visibility for all Axis to \a theVis*/
254 void VTKViewer_Axis::SetVisibility(VTKViewer_Trihedron::TVisibility theVis)
255 {
256   switch(theVis){
257   case VTKViewer_Trihedron::eOff:
258   case VTKViewer_Trihedron::eOn:
259     myLabelActor->SetVisibility(theVis);
260     myArrowActor->SetVisibility(theVis);
261     myLineActor->SetVisibility(theVis);
262     break;
263   case VTKViewer_Trihedron::eOnlyLineOn:
264     myLabelActor->VisibilityOff();
265     myArrowActor->VisibilityOff();
266     myLineActor->VisibilityOn();
267     break;
268   default:
269     return;
270   }
271   myVisibility = theVis;
272 }
273
274 /*! Set camera for myLabelActor
275  */
276 void VTKViewer_Axis::SetCamera(vtkCamera* theCamera){
277 #ifndef IPAL21440
278   myLabelActor->SetCamera(theCamera);
279 #endif
280 }
281
282 /*! Sets color for actors: myLineActor,myLabelActor,myArrowActor
283  */
284 void VTKViewer_Axis::SetColor(double theRed, double theGreen, double theBlue)
285 {
286   // Set color property for arrow and line actors
287   vtkProperty* aProperty = vtkProperty::New();
288   aProperty->SetColor(theRed, theGreen, theBlue);
289
290   myArrowActor->SetProperty(aProperty);
291   myLineActor->SetProperty(aProperty);
292 #ifndef IPAL21440
293   myLabelActor->SetProperty(aProperty);
294 #endif
295
296   aProperty->Delete();
297   
298   // Set color property for label actor
299 #ifdef IPAL21440
300   vtkTextProperty* aTextProperty = vtkTextProperty::New();
301   aTextProperty->SetColor(theRed, theGreen, theBlue);
302
303   myLabelActor->SetTextProperty(aTextProperty);
304
305   aTextProperty->Delete();
306 #endif
307 }
308
309 /*! Set size of VTKViewer_Axis
310  */
311 void VTKViewer_Axis::SetSize(double theSize)
312 {
313   double aPosition[3] = {myDir[0]*theSize, myDir[1]*theSize, myDir[2]*theSize};
314
315   double aCoef = 0.99;
316   double aLinePosition[3] = {aPosition[0]*aCoef, aPosition[1]*aCoef, aPosition[2]*aCoef};
317   myLineSource->SetPoint2(aLinePosition);
318   
319   myArrowActor->SetPosition(0.0,0.0,0.0);
320   myArrowActor->AddPosition(aPosition);
321   myArrowActor->SetOrientation(myRot);
322   myArrowActor->SetScale(theSize / 10.);
323   
324 #ifdef IPAL21440
325   if( vtkCoordinate* aCoord = myLabelActor->GetPositionCoordinate()->GetReferenceCoordinate() )
326     aCoord->SetValue( aPosition );
327 #else
328   myLabelActor->SetPosition(0.0,0.0,0.0);
329   myLabelActor->AddPosition(aPosition);
330 #endif
331 }
332
333 /*! Check if actor belongs to the axis object
334  * \param theActor - vtkActor pointer
335  * \retval Return true if the actor belongs to the axis object
336  */
337 bool VTKViewer_Axis::OwnActor(const vtkActor* theActor)
338 {
339   return theActor == myLineActor  || 
340          theActor == myArrowActor ||
341 #ifdef IPAL21440
342          false;
343 #else
344          theActor == myLabelActor;
345 #endif
346 }
347
348 /*! \class VTKViewer_XAxis
349  * \brief X Axis actor
350  */
351 class VTKViewer_XAxis : public VTKViewer_Axis
352 {
353 protected:
354   VTKViewer_XAxis();
355   VTKViewer_XAxis(const VTKViewer_XAxis&);
356 public:
357   vtkTypeMacro(VTKViewer_XAxis,VTKViewer_Axis)
358   static VTKViewer_XAxis *New();
359 };
360
361 vtkStandardNewMacro(VTKViewer_XAxis)
362
363 /*!Initialize X Axis*/
364 VTKViewer_XAxis::VTKViewer_XAxis(){ 
365   myDir[0] = 1.0; myDir[1] = 0.0; myDir[2] = 0.0;
366   myRot[0] = 0.0; myRot[1] = 0.0; myRot[2] = 0.0;
367 #ifdef IPAL21440
368   myTextMapper->SetInput("X");
369 #else
370   myVectorText->SetText("X");
371 #endif
372   SetColor(1.0,0.0,0.0);
373 }
374
375 /*! \class VTKViewer_YAxis
376  * \brief Y Axis actor
377  */
378 class VTKViewer_YAxis : public VTKViewer_Axis{
379 protected:
380   VTKViewer_YAxis();
381   VTKViewer_YAxis(const VTKViewer_YAxis&);
382 public:
383   vtkTypeMacro(VTKViewer_YAxis,VTKViewer_Axis)
384   static VTKViewer_YAxis *New();
385 };
386
387 vtkStandardNewMacro(VTKViewer_YAxis)
388
389 /*!Initialize Y Axis*/
390 VTKViewer_YAxis::VTKViewer_YAxis()
391
392   myDir[0] = 0.0; myDir[1] = 1.0; myDir[2] = 0.0;
393   myRot[0] = 0.0; myRot[1] = 0.0; myRot[2] = 90.;
394 #ifdef IPAL21440
395   myTextMapper->SetInput("Y");
396 #else
397   myVectorText->SetText("Y");
398 #endif
399   SetColor(0.0,1.0,0.0);
400 }
401
402 /*! \class VTKViewer_ZAxis
403  * \brief Z Axis actor
404  */
405 class VTKViewer_ZAxis : public VTKViewer_Axis
406 {
407 protected:
408   VTKViewer_ZAxis();
409   VTKViewer_ZAxis(const VTKViewer_ZAxis&);
410 public:
411   vtkTypeMacro(VTKViewer_ZAxis,VTKViewer_Axis)
412   static VTKViewer_ZAxis *New();
413 };
414
415 vtkStandardNewMacro(VTKViewer_ZAxis)
416
417 /*!Initialize Z Axis*/
418 VTKViewer_ZAxis::VTKViewer_ZAxis()
419 {
420   myDir[0] = 0.0; myDir[1] = 0.0; myDir[2] = 1.0;
421   myRot[0] = 0.0; myRot[1] = -90; myRot[2] = 0.0;
422 #ifdef IPAL21440
423   myTextMapper->SetInput("Z");
424 #else
425   myVectorText->SetText("Z");
426 #endif
427   SetColor(0.0,0.0,1.0);
428 }
429
430 vtkStandardNewMacro(VTKViewer_Trihedron)
431
432 /*!
433   Constructor
434 */
435 VTKViewer_Trihedron::VTKViewer_Trihedron()
436 {
437   myPresent = vtkActorCollection::New();
438   myAxis[0] = VTKViewer_XAxis::New();
439   myAxis[1] = VTKViewer_YAxis::New();
440   myAxis[2] = VTKViewer_ZAxis::New();
441   static double aSize = 100;
442   SetSize(aSize);
443 }
444
445 /*!
446   Destructor
447 */
448 VTKViewer_Trihedron::~VTKViewer_Trihedron()
449 {
450   myPresent->RemoveAllItems();
451   myPresent->Delete();
452   for(int i = 0; i < 3; i++)
453     myAxis[i]->Delete();
454 }
455
456 /*! Set size of axes
457  */
458 void VTKViewer_Trihedron::SetSize(double theSize)
459 {
460   mySize = theSize;
461   for(int i = 0; i < 3; i++)
462     myAxis[i]->SetSize(theSize);
463 }
464
465 /*! Set visibility of axes
466  */
467 void VTKViewer_Trihedron::SetVisibility(TVisibility theVis)
468 {
469   for(int i = 0; i < 3; i++)
470     myAxis[i]->SetVisibility(theVis);
471 }
472
473 /*!
474   \return visibility of first axis
475 */
476 VTKViewer_Trihedron::TVisibility VTKViewer_Trihedron::GetVisibility()
477 {
478   return myAxis[0]->GetVisibility();
479 }
480
481 /*! Add to render all Axis
482  * \param theRenderer - vtkRenderer pointer
483  */
484 void VTKViewer_Trihedron::AddToRender(vtkRenderer* theRenderer)
485 {
486   vtkCamera* aCamera = theRenderer->GetActiveCamera();
487   for(int i = 0; i < 3; i++){
488     myAxis[i]->AddToRender(theRenderer);
489     myAxis[i]->SetCamera(aCamera);
490   }
491 }
492
493 /*! Remove all actors from \a theRenderer which are in myPresent.
494  * \param theRenderer - vtkRenderer pointer
495  */
496 void VTKViewer_Trihedron::RemoveFromRender(vtkRenderer* theRenderer)
497 {
498   myPresent->InitTraversal();
499   while(vtkActor* anActor = myPresent->GetNextActor())
500     theRenderer->RemoveActor(anActor);
501   for(int i = 0; i < 3; i++)
502     myAxis[i]->RemoveFromRender(theRenderer);
503 }
504
505 /*! Return count of visible actors.
506  * \param theRenderer - vtkRenderer pointer
507  */
508 int VTKViewer_Trihedron::GetVisibleActorCount(vtkRenderer* theRenderer)
509 {
510   //TVisibility aVis = GetVisibility();
511   //SetVisibility(eOff);
512   VTK::ActorCollectionCopy aCopy(theRenderer->GetActors());
513   vtkActorCollection* aCollection = aCopy.GetActors();
514   aCollection->InitTraversal();
515   int aCount = 0;
516   while(vtkActor* prop = aCollection->GetNextActor()) {
517     if( prop->GetVisibility()) {
518       if(VTKViewer_Actor* anActor = VTKViewer_Actor::SafeDownCast(prop)) {
519         if(!anActor->IsInfinitive()) 
520           aCount++;
521       }
522       else if ( !OwnActor( anActor ) ) {
523         aCount++;
524       }
525         //int aCount = theRenderer->VisibleActorCount();
526         //SetVisibility(aVis);
527     }
528   }
529   return aCount;
530 }
531
532 /*! Check if actor belongs to the axis object
533  * \param theActor - vtkActor pointer
534  * \retval Return true if the actor belongs to the axis object
535  */
536 bool VTKViewer_Trihedron::OwnActor(const vtkActor* theActor)
537 {
538   myPresent->InitTraversal();
539   while(vtkActor* anActor = myPresent->GetNextActor()) {
540     if ( anActor == theActor ) return true;
541   }
542   for(int i = 0; i < 3; i++) {
543     if ( myAxis[i]->OwnActor(theActor) ) return true;
544   }
545   return false;
546 }