Salome HOME
This file is given from DESCARTES project
[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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
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 GLViewer_Grid::GLViewer_Grid() :
33        myGridList( 0 ), myGridHeight( (GLfloat)0.0 ), myGridWidth( (GLfloat)0.0 ),
34        myWinW( (GLfloat)0.0 ), myWinH( (GLfloat)0.0 ), myXSize( (GLfloat)0.0 ), myYSize( (GLfloat)0.0 ),
35        myXPan( (GLfloat)0.0 ), myYPan( (GLfloat)0.0 ), myXScale( (GLfloat)1.0 ), myYScale( (GLfloat)1.0 ),
36        myLineWidth( (GLfloat)0.05 ), myCenterWidth( (GLfloat)1.5 ), myCenterRadius( (GLfloat)5.0 ), 
37        myScaleFactor( 10 ), myIsUpdate( GL_FALSE )
38 {
39   myGridColor[0] = 0.5;
40   myGridColor[1] = 0.5;
41   myGridColor[2] = 0.5;
42   myAxisColor[0] = 0.75;
43   myAxisColor[1] = 0.75;
44   myAxisColor[2] = 0.75;
45 }
46
47 GLViewer_Grid::GLViewer_Grid( GLfloat width, GLfloat height,
48                               GLfloat winW, GLfloat winH,
49                               GLfloat xSize, GLfloat ySize,
50                               GLfloat xPan, GLfloat yPan,
51                               GLfloat xScale, GLfloat yScale ) :
52        myGridList( 0 ), myGridHeight( (GLfloat)0.0 ), myGridWidth( (GLfloat)0.0 ),
53        myWinW( (GLfloat)0.0 ), myWinH( (GLfloat)0.0 ), myXSize( (GLfloat)0.0 ), myYSize( (GLfloat)0.0 ),
54        myXPan( (GLfloat)0.0 ), myYPan( (GLfloat)0.0 ), myXScale( (GLfloat)1.0 ), myYScale( (GLfloat)1.0 ),
55        myLineWidth( (GLfloat)0.05 ), myCenterWidth( (GLfloat)1.5 ), myCenterRadius( (GLfloat)5.0 ), 
56        myScaleFactor( 10 ), myIsUpdate( GL_FALSE )
57 {
58   myGridColor[0] = 0.5;
59   myGridColor[1] = 0.5;
60   myGridColor[2] = 0.5;
61   myAxisColor[0] = 0.75;
62   myAxisColor[1] = 0.75;
63   myAxisColor[2] = 0.75;
64 }
65
66 GLViewer_Grid::~GLViewer_Grid()
67 {
68 }
69
70 void GLViewer_Grid::draw()
71 {
72   if ( myGridList == 0 || myIsUpdate )
73     initList();
74
75   glCallList( myGridList );
76 }
77
78 void GLViewer_Grid::setGridColor( GLfloat r, GLfloat g, GLfloat b )
79 {
80   if( myGridColor[0] == r && myGridColor[1] == g && myGridColor[2] == b )
81     return;
82
83   myGridColor[0] = r;
84   myGridColor[1] = g;
85   myGridColor[2] = b;
86   myIsUpdate = GL_TRUE;
87 }
88
89 void GLViewer_Grid::setAxisColor( GLfloat r, GLfloat g, GLfloat b )
90 {
91   if( myAxisColor[0] == r && myAxisColor[1] == g && myAxisColor[2] == b )
92     return;
93
94   myAxisColor[0] = r;
95   myAxisColor[1] = g;
96   myAxisColor[2] = b;
97   myIsUpdate = GL_TRUE;
98 }
99
100 void GLViewer_Grid::setGridWidth( float w )
101 {
102   if( myGridWidth == w )
103     return;
104
105   myGridWidth = w;
106   myIsUpdate = GL_TRUE;
107 }
108
109 void GLViewer_Grid::setCenterRadius( int r )
110 {
111   if( myCenterRadius == r )
112     return;
113
114   myCenterRadius = r;
115   myIsUpdate = GL_TRUE;
116 }
117
118 void GLViewer_Grid::setSize( float xSize, float ySize )
119 {
120   if( myXSize == xSize && myYSize == ySize )
121     return;
122   
123   myXSize = xSize;
124   myYSize = ySize;
125   myIsUpdate = GL_TRUE;
126 }
127
128 void GLViewer_Grid::setPan( float xPan, float yPan )
129 {
130   if( myXPan == xPan && myYPan == yPan )
131     return;
132  
133   myXPan = xPan;
134   myYPan = yPan;
135   myIsUpdate = GL_TRUE; 
136 }
137
138 bool GLViewer_Grid::setZoom( float zoom )
139 {
140   if( zoom == 1.0 )
141     return true;
142   
143   //backup values
144   float bXScale = myXScale;
145   float bYScale = myYScale;
146
147   myXScale /= zoom; 
148   myYScale /= zoom;
149
150   if( fabs(myXScale) < Precision::Confusion() || fabs(myYScale) < Precision::Confusion() )
151   { //undo
152     myXScale = bXScale;
153     myYScale = bYScale;
154     return false;
155   }
156   
157   myGridWidth /= zoom; 
158   myGridHeight /= zoom;  
159   myIsUpdate = GL_TRUE;
160   return true;
161 }
162
163 void GLViewer_Grid::setResize( float WinW, float WinH, float zoom )
164 {
165   if( myWinW == WinW && myWinH == WinH && zoom == 1.0 )
166     return;
167
168   myGridWidth = myGridWidth + ( WinW - myWinW ) * myXScale; 
169   myGridHeight = myGridHeight + ( WinH - myWinH ) * myYScale;
170   myWinW = WinW;
171   myWinH = WinH;
172   setZoom( zoom );
173   myIsUpdate = GL_TRUE;
174 }
175
176 void GLViewer_Grid::getSize( float& xSize, float& ySize ) const
177 {
178   xSize = myXSize;
179   ySize = myYSize;
180 }
181
182 void GLViewer_Grid::getPan( float& xPan, float& yPan ) const
183 {
184   xPan = myXPan;
185   yPan = myYPan;
186 }
187
188 void GLViewer_Grid::getScale( float& xScale, float& yScale ) const
189 {
190   xScale = myXScale;
191   yScale = myYScale;
192 }
193
194 bool GLViewer_Grid::initList()
195 {
196   myIsUpdate = GL_FALSE;
197    
198     if( myXSize == (GLfloat)0.0 )
199         myXSize = (GLfloat)0.1;
200     if( myYSize == (GLfloat)0.0 )
201         myYSize = (GLfloat)0.1;
202
203 label:
204   if( ( myXSize >= myGridWidth/5 ) && ( myYSize >= myGridHeight/5 ) )
205   { //zoom in
206     myXSize /= myScaleFactor;
207     myYSize /= myScaleFactor;
208     goto label;
209   }
210   else if( ( myXSize * myScaleFactor < myGridWidth/5 ) 
211         || ( myYSize * myScaleFactor < myGridHeight/5 ) )
212   { //zoom out
213     myXSize *= myScaleFactor;
214     myYSize *= myScaleFactor;
215     goto label;
216   }
217
218   //int n = myGridWidth / myXSize;
219   //int m = myGridHeight / myYSize;
220   // do not initialise integer by float
221   //if( ( n != 0 ) || ( m != 0 ) ) 
222   if( ( myGridWidth > 0.5 * myXSize ) || ( myGridHeight > 0.5 * myYSize ) )
223   { 
224     if ( myGridList != 0 )  
225     { 
226       glDeleteLists( myGridList, 1 ); 
227       if ( glGetError() != GL_NO_ERROR ) 
228     return FALSE;
229     } 
230          
231     float xLoc = (int)(myXPan / myXSize) * myXSize; 
232     float yLoc = (int)(myYPan / myYSize) * myYSize; 
233  
234     myGridList = glGenLists( 1 ); 
235     glNewList( myGridList, GL_COMPILE ); 
236
237     glColor3f( myGridColor[0], myGridColor[1], myGridColor[2] );  
238     glLineWidth( myLineWidth ); 
239     
240     glBegin( GL_LINES ); 
241     for( int j = 0; ( j-1 ) * myXSize <= myGridWidth / 2 ; j++ )
242     { 
243       glVertex2d( -myXSize * j - xLoc, -myGridHeight / 2 - myYSize - yLoc );
244       glVertex2d( -myXSize * j - xLoc,  myGridHeight / 2 + myYSize - yLoc ); 
245       glVertex2d(  myXSize * j - xLoc, -myGridHeight / 2 - myYSize - yLoc );
246       glVertex2d(  myXSize * j - xLoc,  myGridHeight / 2 + myYSize - yLoc );
247     }
248     for( int i = 0; ( i-1 ) * myYSize <= myGridHeight / 2 ; i++)  
249     {
250       glVertex2d( -myGridWidth / 2 - myXSize - xLoc, -myYSize * i - yLoc ); 
251       glVertex2d(  myGridWidth / 2 + myXSize - xLoc, -myYSize * i - yLoc ); 
252       glVertex2d( -myGridWidth / 2 - myXSize - xLoc,  myYSize * i - yLoc ); 
253       glVertex2d(  myGridWidth / 2 + myXSize - xLoc,  myYSize * i - yLoc ); 
254     } 
255     glEnd();
256
257     glColor3f( myAxisColor[0], myAxisColor[1], myAxisColor[2] );
258     glLineWidth( myCenterWidth );
259
260     glBegin( GL_LINES );
261     glVertex2d(  myGridWidth / 2 + myXSize - xLoc, 0); 
262     glVertex2d( -myGridWidth / 2 - myXSize - xLoc, 0); 
263     glVertex2d( 0,  myGridHeight / 2 + myYSize - yLoc );
264     glVertex2d( 0, -myGridHeight / 2 - myYSize - yLoc );    
265     glEnd();
266
267     glBegin( GL_LINE_LOOP ); 
268     double angle = 0.0;
269     for ( int k = 0; k < SEGMENTS; k++ )     
270     { 
271       glVertex2f( cos(angle) * myCenterRadius * myXScale,
272           sin(angle) * myCenterRadius * myYScale ); 
273       angle += STEP; 
274     } 
275     glEnd();
276
277     glEndList();
278   }
279   return TRUE;
280 }