]> SALOME platform Git repositories - modules/gui.git/blob - src/VTKViewer/VTKViewer_Utilities.cxx
Salome HOME
9ed586d6f2e195f3105537e6567f444d2a53eb39
[modules/gui.git] / src / VTKViewer / VTKViewer_Utilities.cxx
1 #include "VTKViewer_Actor.h"
2
3 // VTK Includes
4 #include <vtkMath.h>
5 #include <vtkCamera.h>
6 #include <vtkRenderer.h>
7 #include <vtkRenderWindow.h>
8 #include "VTKViewer_Utilities.h"
9
10
11 /*!@see vtkRenderer::ResetCamera(float bounds[6]) method*/
12 void ResetCamera(vtkRenderer* theRenderer, int theUsingZeroFocalPoint)
13 {  
14   if(!theRenderer) return;
15   float bounds[6];
16   int aCount = ComputeVisiblePropBounds(theRenderer,bounds);
17   if(theUsingZeroFocalPoint || aCount){
18     float aLength = bounds[1]-bounds[0];
19     aLength = max((bounds[3]-bounds[2]),aLength);
20     aLength = max((bounds[5]-bounds[4]),aLength);
21     
22     double vn[3];
23     if ( theRenderer->GetActiveCamera() != NULL )
24       theRenderer->GetActiveCamera()->GetViewPlaneNormal(vn);
25     else{
26       return;
27     }
28     
29     float center[3] = {0.0, 0.0, 0.0};
30     if(!theUsingZeroFocalPoint){
31       center[0] = (bounds[0] + bounds[1])/2.0;
32       center[1] = (bounds[2] + bounds[3])/2.0;
33       center[2] = (bounds[4] + bounds[5])/2.0;
34     }
35     theRenderer->GetActiveCamera()->SetFocalPoint(center[0],center[1],center[2]);
36     
37     float width = sqrt((bounds[1]-bounds[0])*(bounds[1]-bounds[0]) +
38       (bounds[3]-bounds[2])*(bounds[3]-bounds[2]) +
39       (bounds[5]-bounds[4])*(bounds[5]-bounds[4]));
40     
41     double ang = theRenderer->GetActiveCamera()->GetViewAngle();
42     float distance = 2.0*width/tan(ang*vtkMath::Pi()/360.0);
43     
44     // check view-up vector against view plane normal
45     double *vup = theRenderer->GetActiveCamera()->GetViewUp();
46     if ( fabs(vtkMath::Dot(vup,vn)) > 0.999 ){
47       theRenderer->GetActiveCamera()->SetViewUp(-vup[2], vup[0], vup[1]);
48     }
49     
50     // update the camera
51     theRenderer->GetActiveCamera()->SetPosition(center[0]+distance*vn[0],
52                                                 center[1]+distance*vn[1],
53                                                 center[2]+distance*vn[2]);
54     // find size of the window
55     int* winsize = theRenderer->GetSize();
56     if(winsize[0] < winsize[1]) width *= float(winsize[1])/float(winsize[0]);
57     
58     if(theUsingZeroFocalPoint) width *= sqrt(2.0);
59     
60     theRenderer->GetActiveCamera()->SetParallelScale(width/2.0);
61   }
62   //workaround on VTK
63   //theRenderer->ResetCameraClippingRange(bounds);
64   ResetCameraClippingRange(theRenderer);
65 }
66
67 /*! Compute the bounds of the visible props*/
68 int ComputeVisiblePropBounds(vtkRenderer* theRenderer, float theBounds[6])
69 {
70   float      *bounds;
71   int        aCount=0;
72   
73   theBounds[0] = theBounds[2] = theBounds[4] = VTK_LARGE_FLOAT;
74   theBounds[1] = theBounds[3] = theBounds[5] = -VTK_LARGE_FLOAT;
75   
76   // loop through all props
77   vtkActorCollection* aCollection = theRenderer->GetActors();
78   aCollection->InitTraversal();
79   while (vtkActor* prop = aCollection->GetNextActor()) {
80     // if it's invisible, or has no geometry, we can skip the rest 
81     if ( prop->GetVisibility() )
82     {
83       if(VTKViewer_Actor* anActor = VTKViewer_Actor::SafeDownCast(prop))
84         if(anActor->IsInfinitive()) continue;
85         bounds = prop->GetBounds();
86         // make sure we haven't got bogus bounds
87         if ( bounds != NULL &&
88           bounds[0] > -VTK_LARGE_FLOAT && bounds[1] < VTK_LARGE_FLOAT &&
89           bounds[2] > -VTK_LARGE_FLOAT && bounds[3] < VTK_LARGE_FLOAT &&
90           bounds[4] > -VTK_LARGE_FLOAT && bounds[5] < VTK_LARGE_FLOAT )
91         {
92           aCount++;
93           
94           if (bounds[0] < theBounds[0])
95           {
96             theBounds[0] = bounds[0]; 
97           }
98           if (bounds[1] > theBounds[1])
99           {
100             theBounds[1] = bounds[1]; 
101           }
102           if (bounds[2] < theBounds[2])
103           {
104             theBounds[2] = bounds[2]; 
105           }
106           if (bounds[3] > theBounds[3])
107           {
108             theBounds[3] = bounds[3]; 
109           }
110           if (bounds[4] < theBounds[4])
111           {
112             theBounds[4] = bounds[4]; 
113           }
114           if (bounds[5] > theBounds[5])
115           {
116             theBounds[5] = bounds[5]; 
117           }
118         }//not bogus
119     }
120   }
121   return aCount;
122 }
123
124 /*!@see vtkRenderer::ResetCameraClippingRange(float bounds[6]) method*/
125 void ResetCameraClippingRange(vtkRenderer* theRenderer)
126 {
127   if(!theRenderer || !theRenderer->VisibleActorCount()) return;
128   
129   vtkCamera* anActiveCamera = theRenderer->GetActiveCamera();
130   if( anActiveCamera == NULL ){
131     return;
132   }
133   
134   // Find the plane equation for the camera view plane
135   double vn[3];
136   anActiveCamera->GetViewPlaneNormal(vn);
137   double  position[3];
138   anActiveCamera->GetPosition(position);
139   
140   float bounds[6];
141   theRenderer->ComputeVisiblePropBounds(bounds);
142   
143   double center[3];
144   center[0] = (bounds[0] + bounds[1])/2.0;
145   center[1] = (bounds[2] + bounds[3])/2.0;
146   center[2] = (bounds[4] + bounds[5])/2.0;
147   
148   double width = sqrt((bounds[1]-bounds[0])*(bounds[1]-bounds[0]) +
149     (bounds[3]-bounds[2])*(bounds[3]-bounds[2]) +
150     (bounds[5]-bounds[4])*(bounds[5]-bounds[4]));
151   
152   double distance = sqrt((position[0]-center[0])*(position[0]-center[0]) +
153        (position[1]-center[1])*(position[1]-center[1]) +
154        (position[2]-center[2])*(position[2]-center[2]));
155   
156   float range[2] = {distance - width/2.0, distance + width/2.0};
157   
158   // Do not let the range behind the camera throw off the calculation.
159   if (range[0] < 0.0) range[0] = 0.0;
160   
161   anActiveCamera->SetClippingRange( range );
162 }
163
164 /*!Compute trihedron size.*/
165 bool ComputeTrihedronSize( vtkRenderer* theRenderer,double& theNewSize,
166                            const double theSize, const float theSizeInPercents )
167 {
168   // calculating diagonal of visible props of the renderer
169   float bnd[ 6 ];
170   if ( ComputeVisiblePropBounds( theRenderer, bnd ) == 0 )
171   {
172     bnd[ 1 ] = bnd[ 3 ] = bnd[ 5 ] = 100;
173     bnd[ 0 ] = bnd[ 2 ] = bnd[ 4 ] = 0;
174   }
175   float aLength = 0;
176
177   aLength = bnd[ 1 ]-bnd[ 0 ];
178   aLength = max( ( bnd[ 3 ] - bnd[ 2 ] ),aLength );
179   aLength = max( ( bnd[ 5 ] - bnd[ 4 ] ),aLength );
180
181   static float EPS_SIZE = 5.0E-3;
182   theNewSize = aLength * theSizeInPercents / 100.0;
183
184   // if the new trihedron size have sufficient difference, then apply the value
185   return fabs( theNewSize - theSize) > theSize * EPS_SIZE ||
186          fabs( theNewSize-theSize ) > theNewSize * EPS_SIZE;
187 }