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