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