Salome HOME
Join modifications from branch BR_DEBUG_3_2_0b1
[modules/gui.git] / src / GLViewer / GLViewer_Grid.cxx
1 //  Copyright (C) 2005 OPEN CASCADE
2 //
3 //  This library is free software; you can redistribute it and/or
4 //  modify it under the terms of the GNU Lesser General Public
5 //  License as published by the Free Software Foundation; either
6 //  version 2.1 of the License.
7 //
8 //  This library is distributed in the hope that it will be useful,
9 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 //  Lesser General Public License for more details.
12 //
13 //  You should have received a copy of the GNU Lesser General Public
14 //  License along with this library; if not, write to the Free Software
15 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 //  Author : OPEN CASCADE
20 //
21
22 // File:      GLViewer_Grid.cxx
23 // Created:   November, 2004
24
25 //#include <GLViewerAfx.h>
26 #include "GLViewer_Grid.h"
27 #include "GLViewer_Defs.h"
28
29 #include <Precision.hxx>
30 #include <qglobal.h>
31
32 /*!
33   Default constructor
34 */
35 GLViewer_Grid::GLViewer_Grid() :
36        myGridList( 0 ), myGridHeight( (GLfloat)0.0 ), myGridWidth( (GLfloat)0.0 ),
37        myWinW( (GLfloat)0.0 ), myWinH( (GLfloat)0.0 ), myXSize( (GLfloat)0.0 ), myYSize( (GLfloat)0.0 ),
38        myXPan( (GLfloat)0.0 ), myYPan( (GLfloat)0.0 ), myXScale( (GLfloat)1.0 ), myYScale( (GLfloat)1.0 ),
39        myLineWidth( (GLfloat)0.05 ), myCenterWidth( (GLfloat)1.5 ), myCenterRadius( (GLfloat)5.0 ), 
40        myScaleFactor( 10 ), myIsUpdate( GL_FALSE )
41 {
42   myGridColor[0] = 0.5;
43   myGridColor[1] = 0.5;
44   myGridColor[2] = 0.5;
45   myAxisColor[0] = 0.75;
46   myAxisColor[1] = 0.75;
47   myAxisColor[2] = 0.75;
48 }
49
50 /*!
51   Constructor
52   \param  width and \param height - width and height of grid 
53   \param winW and \param winH     - width and height of window 
54   \param xSize and \param ySize   - steps along x and y direction
55   \param xPan and \param yPan     - offsets along x and y direction
56   \param xScale and \param yScal  - scale factors along x and y direction
57 */
58 GLViewer_Grid::GLViewer_Grid( GLfloat width, GLfloat height,
59                               GLfloat winW, GLfloat winH,
60                               GLfloat xSize, GLfloat ySize,
61                               GLfloat xPan, GLfloat yPan,
62                               GLfloat xScale, GLfloat yScale ) :
63        myGridList( 0 ), myGridHeight( (GLfloat)0.0 ), myGridWidth( (GLfloat)0.0 ),
64        myWinW( (GLfloat)0.0 ), myWinH( (GLfloat)0.0 ), myXSize( (GLfloat)0.0 ), myYSize( (GLfloat)0.0 ),
65        myXPan( (GLfloat)0.0 ), myYPan( (GLfloat)0.0 ), myXScale( (GLfloat)1.0 ), myYScale( (GLfloat)1.0 ),
66        myLineWidth( (GLfloat)0.05 ), myCenterWidth( (GLfloat)1.5 ), myCenterRadius( (GLfloat)5.0 ), 
67        myScaleFactor( 10 ), myIsUpdate( GL_FALSE )
68 {
69   myGridColor[0] = 0.5;
70   myGridColor[1] = 0.5;
71   myGridColor[2] = 0.5;
72   myAxisColor[0] = 0.75;
73   myAxisColor[1] = 0.75;
74   myAxisColor[2] = 0.75;
75 }
76
77 /*!
78   Destructor
79 */
80 GLViewer_Grid::~GLViewer_Grid()
81 {
82 }
83
84 /*!
85   Performs OpenGL drawing
86 */
87 void GLViewer_Grid::draw()
88 {
89   if ( myGridList == 0 || myIsUpdate )
90     initList();
91
92   glCallList( myGridList );
93 }
94
95 /*!
96   Changes color of grid
97   \param r, g, b - components of color
98 */
99 void GLViewer_Grid::setGridColor( GLfloat r, GLfloat g, GLfloat b )
100 {
101   if( myGridColor[0] == r && myGridColor[1] == g && myGridColor[2] == b )
102     return;
103
104   myGridColor[0] = r;
105   myGridColor[1] = g;
106   myGridColor[2] = b;
107   myIsUpdate = GL_TRUE;
108 }
109
110 /*!
111   Changes color of axis
112   \param r, g, b - components of color
113 */
114 void GLViewer_Grid::setAxisColor( GLfloat r, GLfloat g, GLfloat b )
115 {
116   if( myAxisColor[0] == r && myAxisColor[1] == g && myAxisColor[2] == b )
117     return;
118
119   myAxisColor[0] = r;
120   myAxisColor[1] = g;
121   myAxisColor[2] = b;
122   myIsUpdate = GL_TRUE;
123 }
124
125 /*!
126   Changes grid width
127   \param w - new grid width
128 */
129 void GLViewer_Grid::setGridWidth( float w )
130 {
131   if( myGridWidth == w )
132     return;
133
134   myGridWidth = w;
135   myIsUpdate = GL_TRUE;
136 }
137
138 /*!
139   Sets Radius of center point( begin coords )
140   \param r - new radius
141 */
142 void GLViewer_Grid::setCenterRadius( int r )
143 {
144   if( myCenterRadius == r )
145     return;
146
147   myCenterRadius = r;
148   myIsUpdate = GL_TRUE;
149 }
150
151 /*!
152   Sets grid size along X and Y axis
153   \param xSize - size along X axis
154   \param ySize - size along Y axis
155 */
156 void GLViewer_Grid::setSize( float xSize, float ySize )
157 {
158   if( myXSize == xSize && myYSize == ySize )
159     return;
160   
161   myXSize = xSize;
162   myYSize = ySize;
163   myIsUpdate = GL_TRUE;
164 }
165
166 /*!
167   Sets panning of grid
168   \param xPan - panning along X axis
169   \param yPan - panning along Y axis
170 */
171 void GLViewer_Grid::setPan( float xPan, float yPan )
172 {
173   if( myXPan == xPan && myYPan == yPan )
174     return;
175  
176   myXPan = xPan;
177   myYPan = yPan;
178   myIsUpdate = GL_TRUE; 
179 }
180
181 /*!
182   Sets zoom 
183   \param zoom - new coefficient of zooming
184 */
185 bool GLViewer_Grid::setZoom( float zoom )
186 {
187   if( zoom == 1.0 )
188     return true;
189   
190   //backup values
191   float bXScale = myXScale;
192   float bYScale = myYScale;
193
194   myXScale /= zoom; 
195   myYScale /= zoom;
196
197   if( fabs(myXScale) < Precision::Confusion() || fabs(myYScale) < Precision::Confusion() )
198   { //undo
199     myXScale = bXScale;
200     myYScale = bYScale;
201     return false;
202   }
203   
204   myGridWidth /= zoom; 
205   myGridHeight /= zoom;  
206   myIsUpdate = GL_TRUE;
207   return true;
208 }
209
210 /*!
211   Sets parameters of grid by zoom coefficient and window size
212   \param WinW - window width
213   \param WinH - window height
214   \param zoom - zoom coefficient
215 */
216 void GLViewer_Grid::setResize( float WinW, float WinH, float zoom )
217 {
218   if( myWinW == WinW && myWinH == WinH && zoom == 1.0 )
219     return;
220
221   myGridWidth = myGridWidth + ( WinW - myWinW ) * myXScale; 
222   myGridHeight = myGridHeight + ( WinH - myWinH ) * myYScale;
223   myWinW = WinW;
224   myWinH = WinH;
225   setZoom( zoom );
226   myIsUpdate = GL_TRUE;
227 }
228
229 /*!
230   \return grid size along x and y axis
231   \param xSize - for size along x axis
232   \param ySize - for size along y axis
233 */
234 void GLViewer_Grid::getSize( float& xSize, float& ySize ) const
235 {
236   xSize = myXSize;
237   ySize = myYSize;
238 }
239
240 /*!
241   \return panning along x and y axis
242   \param xPan - for panning along x axis
243   \param yPan - for panning along y axis
244 */
245 void GLViewer_Grid::getPan( float& xPan, float& yPan ) const
246 {
247   xPan = myXPan;
248   yPan = myYPan;
249 }
250
251 /*!
252   \return scaling along x and y axis
253   \param xScale - for scaling along x axis
254   \param yScale - for scaling along y axis
255 */
256 void GLViewer_Grid::getScale( float& xScale, float& yScale ) const
257 {
258   xScale = myXScale;
259   yScale = myYScale;
260 }
261
262 /*!
263   Initialize grid display list
264 */
265 bool GLViewer_Grid::initList()
266 {
267   myIsUpdate = GL_FALSE;
268    
269     if( myXSize == (GLfloat)0.0 )
270         myXSize = (GLfloat)0.1;
271     if( myYSize == (GLfloat)0.0 )
272         myYSize = (GLfloat)0.1;
273
274 label:
275   if( ( myXSize >= myGridWidth/5 ) && ( myYSize >= myGridHeight/5 ) )
276   { //zoom in
277     myXSize /= myScaleFactor;
278     myYSize /= myScaleFactor;
279     goto label;
280   }
281   else if( ( myXSize * myScaleFactor < myGridWidth/5 ) 
282         || ( myYSize * myScaleFactor < myGridHeight/5 ) )
283   { //zoom out
284     myXSize *= myScaleFactor;
285     myYSize *= myScaleFactor;
286     goto label;
287   }
288
289   //int n = myGridWidth / myXSize;
290   //int m = myGridHeight / myYSize;
291   // do not initialise integer by float
292   //if( ( n != 0 ) || ( m != 0 ) ) 
293   if( ( myGridWidth > 0.5 * myXSize ) || ( myGridHeight > 0.5 * myYSize ) )
294   { 
295     if ( myGridList != 0 )  
296     { 
297       glDeleteLists( myGridList, 1 ); 
298       if ( glGetError() != GL_NO_ERROR ) 
299     return FALSE;
300     } 
301          
302     float xLoc = (int)(myXPan / myXSize) * myXSize; 
303     float yLoc = (int)(myYPan / myYSize) * myYSize; 
304  
305     myGridList = glGenLists( 1 ); 
306     glNewList( myGridList, GL_COMPILE ); 
307
308     glColor3f( myGridColor[0], myGridColor[1], myGridColor[2] );  
309     glLineWidth( myLineWidth ); 
310     
311     glBegin( GL_LINES ); 
312     for( int j = 0; ( j-1 ) * myXSize <= myGridWidth / 2 ; j++ )
313     { 
314       glVertex2d( -myXSize * j - xLoc, -myGridHeight / 2 - myYSize - yLoc );
315       glVertex2d( -myXSize * j - xLoc,  myGridHeight / 2 + myYSize - yLoc ); 
316       glVertex2d(  myXSize * j - xLoc, -myGridHeight / 2 - myYSize - yLoc );
317       glVertex2d(  myXSize * j - xLoc,  myGridHeight / 2 + myYSize - yLoc );
318     }
319     for( int i = 0; ( i-1 ) * myYSize <= myGridHeight / 2 ; i++)  
320     {
321       glVertex2d( -myGridWidth / 2 - myXSize - xLoc, -myYSize * i - yLoc ); 
322       glVertex2d(  myGridWidth / 2 + myXSize - xLoc, -myYSize * i - yLoc ); 
323       glVertex2d( -myGridWidth / 2 - myXSize - xLoc,  myYSize * i - yLoc ); 
324       glVertex2d(  myGridWidth / 2 + myXSize - xLoc,  myYSize * i - yLoc ); 
325     } 
326     glEnd();
327
328     glColor3f( myAxisColor[0], myAxisColor[1], myAxisColor[2] );
329     glLineWidth( myCenterWidth );
330
331     glBegin( GL_LINES );
332     glVertex2d(  myGridWidth / 2 + myXSize - xLoc, 0); 
333     glVertex2d( -myGridWidth / 2 - myXSize - xLoc, 0); 
334     glVertex2d( 0,  myGridHeight / 2 + myYSize - yLoc );
335     glVertex2d( 0, -myGridHeight / 2 - myYSize - yLoc );    
336     glEnd();
337
338     glBegin( GL_LINE_LOOP ); 
339     double angle = 0.0;
340     for ( int k = 0; k < SEGMENTS; k++ )     
341     { 
342       glVertex2f( cos(angle) * myCenterRadius * myXScale,
343           sin(angle) * myCenterRadius * myYScale ); 
344       angle += STEP; 
345     } 
346     glEnd();
347
348     glEndList();
349   }
350   return TRUE;
351 }