0023428: Extend OpenGl_Context to use Geometry Shaders extension
[occt.git] / src / OpenGl / OpenGl_GraduatedTrihedron.cxx
1 // Created on: 2011-09-20
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2012 OPEN CASCADE SAS
4 //
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
9 //
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 //
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
19
20
21 #include <OpenGl_GlCore11.hxx>
22
23 #include <stddef.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <math.h>
27
28 #include <InterfaceGraphic_Graphic3d.hxx>
29 #include <InterfaceGraphic_Aspect.hxx>
30 #include <InterfaceGraphic_Visual3d.hxx>
31
32 #include <GL/glu.h> // gluUnProject()
33
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
37 #ifdef HAVE_STRING_H
38 #include <string.h>
39 #endif
40
41 #include <OpenGl_Workspace.hxx>
42 #include <OpenGl_View.hxx>
43 #include <OpenGl_GraduatedTrihedron.hxx>
44 #include <OpenGl_AspectLine.hxx>
45
46 IMPLEMENT_STANDARD_HANDLE(OpenGl_GraduatedTrihedron,MMgt_TShared)
47 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_GraduatedTrihedron,MMgt_TShared)
48
49 const OpenGl_AspectLine myDefaultAspectLine;
50
51 /* Bounding box */
52 float xmin = 0.0f, ymin = 0.0f, zmin = 0.0f, xmax = 100.0f, ymax = 100.0f, zmax = 100.0f;
53
54 /* Normal of the view (not normalized!) */
55 static float getNormal(float* normal) 
56 {
57   GLint viewport[4];
58   GLdouble model_matrix[16], proj_matrix[16];
59
60   glGetDoublev(GL_MODELVIEW_MATRIX,  model_matrix);
61   glGetDoublev(GL_PROJECTION_MATRIX, proj_matrix);
62   glGetIntegerv(GL_VIEWPORT, viewport);
63
64   double x1, y1, z1, x2, y2, z2, x3, y3, z3;
65   gluUnProject(viewport[0], viewport[1], 0., model_matrix, proj_matrix, viewport, &x1, &y1, &z1);
66   gluUnProject(viewport[0] + viewport[2], viewport[1], 0., model_matrix, proj_matrix, viewport, &x2, &y2, &z2);
67   gluUnProject(viewport[0], viewport[1] + viewport[3], 0., model_matrix, proj_matrix, viewport, &x3, &y3, &z3);
68
69   /* Normal out of user is p1p3^p1p2 */
70   const double dx1 = x3 - x1;
71   const double dy1 = y3 - y1;
72   const double dz1 = z3 - z1;
73   const double dx2 = x2 - x1;
74   const double dy2 = y2 - y1;
75   const double dz2 = z2 - z1;
76   normal[0] = (float) (dy1 * dz2 - dz1 * dy2);
77   normal[1] = (float) (dz1 * dx2 - dx1 * dz2);
78   normal[2] = (float) (dx1 * dy2 - dy1 * dx2);
79
80   /* Distance corresponding to 1 pixel */
81   const float width = (float) sqrt(dx2 * dx2 + dy2 * dy2 + dz2 * dz2);
82   return width / (float) viewport[2];
83 }
84
85 static float getDistance2Corner(float* normal, float* center, float x, float y, float z)
86 {
87     return normal[0] * (x - center[0]) + normal[1] * (y - center[1]) + normal[2] * (z - center[2]);
88 }
89
90 static char getFarestCorner(float d000, float d100, float d010, float d001, 
91                             float d110, float d101, float d011, float d111)
92 {
93     if (d000 > 0.0f && 
94         d000 > d100 && d000 > d010 && d000 > d001 && d000 > d110 && 
95         d000 > d101 && d000 > d011 && d000 > d111)
96     {
97         return 1;
98     }
99     else if (d100 > 0.0f &&
100              d100 > d000 && d100 > d010 && d100 > d001 && d100 > d110 && 
101              d100 > d101 && d100 > d011 && d100 > d111)
102     {
103         return 2;
104     }
105     else if (d010 > 0.0f &&
106              d010 > d000 && d010 > d100 && d010 > d001 && d010 > d110 && 
107              d010 > d101 && d010 > d011 && d010 > d111)
108     {
109         return 3;
110     }
111     else if (d001 > 0.0f &&
112              d001 > d000 && d001 > d100 && d001 > d010 && d001 > d110 && 
113              d001 > d101 && d001 > d011 && d001 > d111)
114     {
115         return 4;
116     }
117     else if (d110 > 0.0f &&
118              d110 > d000 && d110 > d100 && d110 > d010 && d110 > d001 && 
119              d110 > d101 && d110 > d011 && d110 > d111)
120     {
121         return 5;
122     }
123     else if (d101 > 0.0f &&
124              d101 > d000 && d101 > d100 && d101 > d010 && d101 > d001 && 
125              d101 > d110 && d101 > d011 && d101 > d111)
126     {
127         return 6;
128     }
129     else if (d011 > 0.0f &&
130              d011 > d000 && d011 > d100 && d011 > d010 && d011 > d001 && 
131              d011 > d110 && d011 > d101 && d011 > d111)
132     {
133         return 7;
134     }
135     return 8; /* d111 */
136 }
137
138 static void drawText(const Handle(OpenGl_Workspace) &AWorkspace, const wchar_t* text, const char* font, OSD_FontAspect style, int size, float x, float y, float z)
139 {
140   AWorkspace->FindFont(font, style, size);
141   AWorkspace->RenderText(text, 0, x, y, z);
142
143 /* 4 OCC 6.3.1 and older:
144     GLuint fontBase;
145
146 #ifndef WNT
147      fontBase = tXfmsetfont (1.0F, 1.0F);
148 #else
149      fontBase = WNTSetFont (1.0F, 1.0F);
150 #endif
151
152 #ifndef WNT
153      tXfmprstr(text, fontBase, x, y, z);
154 #else
155      WNTPuts(text, fontBase, 0, x, y, z);
156 #endif
157 */
158 }
159
160 static void drawArrow(float x1, float y1, float z1, 
161                       float x2, float y2, float z2,
162                       float xn, float yn, float zn)
163 {
164     float h, r;
165     float xa, ya, za;
166     float x0, y0, z0;
167     float xr, yr, zr;
168     float xa1, ya1, za1, xa2, ya2, za2;
169
170     /* Start of arrow: at 10% from the end */
171     x0 = x1 + 0.9f * (x2 - x1); y0 = y1 + 0.9f * (y2 - y1); z0 = z1 + 0.9f * (z2 - z1);
172
173     /* Base of the arrow */
174     xa = (x2 - x0); ya = (y2 - y0); za = (z2 - z0);
175
176     /* Height of the arrow */
177     h = sqrtf(xa * xa + ya * ya + za * za);
178     if (h <= 0.0f)
179         return;
180     xa = xa / h; ya = ya / h; za = za / h;
181
182     /* Radial direction to the arrow */
183     xr = ya * zn - za * yn;
184     yr = za * xn - xa * zn;
185     zr = xa * yn - ya * xn;
186
187     /* Normalize the radial vector */
188     r = sqrtf(xr * xr + yr * yr + zr * zr);
189     if (r <= 0.0f)
190         return;
191     xr = xr / r; yr = yr / r; zr = zr / r;
192
193     /* First point of the base of the arrow */
194     r = 0.2f * h;
195     xr = r * xr; yr = r * yr; zr = r * zr;
196     xa1 = x0 + xr; ya1 = y0 + yr; za1 = z0 + zr;
197
198     /* Second point of the base of the arrow */
199     xa2 = x0 - xr; ya2 = y0 - yr; za2 = z0 - zr;
200
201     /* Draw a line to the arrow */
202     glBegin(GL_LINES);
203         glVertex3f(x1, y1, z1);
204         glVertex3f(x0, y0, z0);
205     glEnd();
206
207     /* Draw a triangle of the arrow */
208     glBegin(GL_LINE_LOOP);
209         glVertex3f(xa1, ya1, za1);
210         glVertex3f(xa2, ya2, za2);
211         glVertex3f(x2,  y2,  z2);
212     glEnd();
213 }
214
215 OpenGl_GraduatedTrihedron::OpenGl_GraduatedTrihedron (const Graphic3d_CGraduatedTrihedron &AData)
216 : myXName(NULL), myYName(NULL), myZName(NULL),
217   myDrawXName(AData.xdrawname), myDrawYName(AData.ydrawname), myDrawZName(AData.zdrawname),
218   myDrawXValues(AData.xdrawvalues), myDrawYValues(AData.ydrawvalues), myDrawZValues(AData.zdrawvalues),
219   myDrawGrid(AData.drawgrid), myDrawAxes(AData.drawaxes),
220   myNbX(AData.nbx), myNbY(AData.nby), myNbZ(AData.nbz),
221   myXOffset(AData.xoffset), myYOffset(AData.yoffset), myZOffset(AData.zoffset),
222   myXAxisOffset(AData.xaxisoffset), myYAxisOffset(AData.yaxisoffset), myZAxisOffset(AData.zaxisoffset),
223   myDrawXTickmarks(AData.xdrawtickmarks), myDrawYTickmarks(AData.ydrawtickmarks), myDrawZTickmarks(AData.zdrawtickmarks),
224   myXTickmarkLength(AData.xtickmarklength), myYTickmarkLength(AData.ytickmarklength), myZTickmarkLength(AData.ztickmarklength),
225   myFontOfNames(NULL),
226   myStyleOfNames(AData.styleOfNames),
227   mySizeOfNames(AData.sizeOfNames),
228   myFontOfValues(NULL),
229   myStyleOfValues(AData.styleOfValues),
230   mySizeOfValues(AData.sizeOfValues),
231   myCbCubicAxes(AData.cbCubicAxes),
232   myPtrVisual3dView(AData.ptrVisual3dView)
233 {
234   /* Names of axes */
235   /* X-name */
236   int len = AData.xname.Length();
237   if (len)
238   {
239     Standard_ExtString iname = AData.xname.ToExtString();
240     wchar_t *xname = new wchar_t[len+1];
241     len = 0; while (xname[len] = (wchar_t)(iname[len])) len++;
242     myXName = xname;
243   }
244   /* Y-name */
245   len = AData.yname.Length();
246   if (len)
247   {
248     Standard_ExtString iname = AData.yname.ToExtString();
249     wchar_t *yname = new wchar_t[len+1];
250     len = 0; while (yname[len] = (wchar_t)(iname[len])) len++;
251     myYName = yname;
252   }
253   /* Z-name */
254   len = AData.zname.Length();
255   if (len)
256   {
257     Standard_ExtString iname = AData.zname.ToExtString();
258     wchar_t *zname = new wchar_t[len+1];
259     len = 0; while (zname[len] = (wchar_t)(iname[len])) len++;
260     myZName = zname;
261   }
262   /* Grid color */
263   myGridColor[0] = (float) AData.gridcolor.Red();
264   myGridColor[1] = (float) AData.gridcolor.Green();
265   myGridColor[2] = (float) AData.gridcolor.Blue();
266   /* X name color */
267   myXNameColor[0] = (float) AData.xnamecolor.Red();
268   myXNameColor[1] = (float) AData.xnamecolor.Green();
269   myXNameColor[2] = (float) AData.xnamecolor.Blue();
270   /* Y name color */
271   myYNameColor[0] = (float) AData.ynamecolor.Red();
272   myYNameColor[1] = (float) AData.ynamecolor.Green();
273   myYNameColor[2] = (float) AData.ynamecolor.Blue();
274   /* Z name color */
275   myZNameColor[0] = (float) AData.znamecolor.Red();
276   myZNameColor[1] = (float) AData.znamecolor.Green();
277   myZNameColor[2] = (float) AData.znamecolor.Blue();
278   /* X color of axis and values */
279   myXColor[0] = (float) AData.xcolor.Red();
280   myXColor[1] = (float) AData.xcolor.Green();
281   myXColor[2] = (float) AData.xcolor.Blue();
282   /* Y color of axis and values */
283   myYColor[0] = (float) AData.ycolor.Red();
284   myYColor[1] = (float) AData.ycolor.Green();
285   myYColor[2] = (float) AData.ycolor.Blue();
286   /* Z color of axis and values */
287   myZColor[0] = (float) AData.zcolor.Red();
288   myZColor[1] = (float) AData.zcolor.Green();
289   myZColor[2] = (float) AData.zcolor.Blue();
290   /* Font name of names of axes: Courier, Arial, ... */
291   len = AData.fontOfNames.Length();
292   char *fontOfNames = new char[len+1];
293   if (len)
294     strcpy(fontOfNames, AData.fontOfNames.ToCString());
295   else
296     fontOfNames[0] = '\0';
297   myFontOfNames = fontOfNames;
298   /* Font name of values: Courier, Arial, ... */
299   len = AData.fontOfValues.Length();
300   char *fontOfValues = new char[len+1];
301   if (len)
302     strcpy(fontOfValues, AData.fontOfValues.ToCString());
303   else
304     fontOfValues[0] = '\0';
305   myFontOfValues = fontOfValues;
306 }
307
308 OpenGl_GraduatedTrihedron::~OpenGl_GraduatedTrihedron ()
309 {
310   // Names of axes
311   if (myXName)
312     delete[] myXName;
313   if (myYName)
314     delete[] myYName;
315   if (myZName)
316     delete[] myZName;
317
318   // Fonts
319   if (myFontOfNames)
320     delete[] myFontOfNames;
321   if (myFontOfValues)
322     delete[] myFontOfValues;
323 }
324
325 //call_graduatedtrihedron_redraw
326 void OpenGl_GraduatedTrihedron::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
327 {
328   const OpenGl_AspectLine *oldAspectLine = AWorkspace->SetAspectLine(&myDefaultAspectLine);
329   AWorkspace->AspectLine(Standard_True);
330
331   /* Update boundary box */
332   if (myCbCubicAxes)
333     myCbCubicAxes(myPtrVisual3dView);
334
335   /* Disable lighting for lines */
336   GLboolean light = glIsEnabled(GL_LIGHTING);
337   if (light)
338     glDisable(GL_LIGHTING);
339
340   /* Find the farest point of bounding box */
341
342   /* Get normal of the view out of user. */
343   /* Also, the method return distance corresponding to 1 pixel */
344   float normal[3];
345   float dpix = getNormal(normal);
346
347   /* Normalize normal */
348   float d = sqrtf(normal[0] * normal[0] + normal[1] * normal[1] + normal[2] * normal[2]);
349   normal[0] /= d;
350   normal[1] /= d;
351   normal[2] /= d;
352
353   /* Get central point of bounding box */
354   float center[3];
355   center[0] = 0.5f * (xmin + xmax);
356   center[1] = 0.5f * (ymin + ymax);
357   center[2] = 0.5f * (zmin + zmax);
358
359   /* Check distance to corners of bounding box along the normal */
360   float d000 = getDistance2Corner(normal, center, xmin, ymin, zmin);
361   float d100 = getDistance2Corner(normal, center, xmax, ymin, zmin);
362   float d010 = getDistance2Corner(normal, center, xmin, ymax, zmin);
363   float d001 = getDistance2Corner(normal, center, xmin, ymin, zmax);
364   float d110 = getDistance2Corner(normal, center, xmax, ymax, zmin);
365   float d101 = getDistance2Corner(normal, center, xmax, ymin, zmax);
366   float d011 = getDistance2Corner(normal, center, xmin, ymax, zmax);
367   float d111 = getDistance2Corner(normal, center, xmax, ymax, zmax);
368   unsigned char farestCorner = getFarestCorner(d000, d100, d010, d001, d110, d101, d011, d111);
369
370   /* Choose axes for the grid. */
371   float LX1[6], LX2[6], LX3[6]; /* Lines along X direction */
372   float LY1[6], LY2[6], LY3[6]; /* Lines along Y direction */
373   float LZ1[6], LZ2[6], LZ3[6]; /* Lines along Z direction */
374   unsigned char LX1draw, LX2draw, LX3draw; /* Allows drawing of X-line (000 - 100 is forbidden) */
375   unsigned char LY1draw, LY2draw, LY3draw; /* Allows drawing of Y-line (000 - 010 is forbidden) */
376   unsigned char LZ1draw, LZ2draw, LZ3draw; /* Allows drawing of Z-line (000 - 001 is forbidden) */
377
378   /* The first axis will be used for drawing the text and the values. */
379   switch (farestCorner)
380   {
381     case 1: /* d000 */
382     {
383       /* 001 - 101 */
384       LX1draw = 1;
385       LX1[0] = xmin; LX1[1] = ymin; LX1[2] = zmax; LX1[3] = xmax; LX1[4] = ymin; LX1[5] = zmax;
386       /* 000 - 100 */
387       LX2draw = 0; /* forbidden! */
388       LX2[0] = xmin; LX2[1] = ymin; LX2[2] = zmin; LX2[3] = xmax; LX2[4] = ymin; LX2[5] = zmin;
389       /* 010 - 110 */
390       LX3draw = 1;
391       LX3[0] = xmin; LX3[1] = ymax; LX3[2] = zmin; LX3[3] = xmax; LX3[4] = ymax; LX3[5] = zmin;
392
393       /* 100 - 110 */
394       LY1draw = 1;
395       LY1[0] = xmax; LY1[1] = ymin; LY1[2] = zmin; LY1[3] = xmax; LY1[4] = ymax; LY1[5] = zmin;
396       /* 000 - 010 */
397       LY2draw = 0; /* forbidden! */
398       LY2[0] = xmin; LY2[1] = ymin; LY2[2] = zmin; LY2[3] = xmin; LY2[4] = ymax; LY2[5] = zmin;
399       /* 001 - 011 */
400       LY3draw = 1;
401       LY3[0] = xmin; LY3[1] = ymin; LY3[2] = zmax; LY3[3] = xmin; LY3[4] = ymax; LY3[5] = zmax;
402
403       /* 100 - 101 */
404       LZ1draw = 1;
405       LZ1[0] = xmax; LZ1[1] = ymin; LZ1[2] = zmin; LZ1[3] = xmax; LZ1[4] = ymin; LZ1[5] = zmax;
406       /* 000 - 001 */
407       LZ2draw = 0; /* forbidden! */
408       LZ2[0] = xmin; LZ2[1] = ymin; LZ2[2] = zmin; LZ2[3] = xmin; LZ2[4] = ymin; LZ2[5] = zmax;
409       /* 010 - 011 */
410       LZ3draw = 1;
411       LZ3[0] = xmin; LZ3[1] = ymax; LZ3[2] = zmin; LZ3[3] = xmin; LZ3[4] = ymax; LZ3[5] = zmax;
412
413       break;
414     }
415     case 2: /* d100 */
416     {
417       /* 001 - 101 */
418       LX1draw = 1;
419       LX1[0] = xmin; LX1[1] = ymin; LX1[2] = zmax; LX1[3] = xmax; LX1[4] = ymin; LX1[5] = zmax;
420       /* 000 - 100 */
421       LX2draw = 0; /* forbidden! */
422       LX2[0] = xmin; LX2[1] = ymin; LX2[2] = zmin; LX2[3] = xmax; LX2[4] = ymin; LX2[5] = zmin;
423       /* 010 - 110 */
424       LX3draw = 1;
425       LX3[0] = xmin; LX3[1] = ymax; LX3[2] = zmin; LX3[3] = xmax; LX3[4] = ymax; LX3[5] = zmin;
426
427       /* 000 - 010 */
428       LY1draw = 0; /* forbidden! */
429       LY1[0] = xmin; LY1[1] = ymin; LY1[2] = zmin; LY1[3] = xmin; LY1[4] = ymax; LY1[5] = zmin;
430       /* 100 - 110 */
431       LY2draw = 1;
432       LY2[0] = xmax; LY2[1] = ymin; LY2[2] = zmin; LY2[3] = xmax; LY2[4] = ymax; LY2[5] = zmin;
433       /* 101 - 111 */
434       LY3draw = 1;
435       LY3[0] = xmax; LY3[1] = ymin; LY3[2] = zmax; LY3[3] = xmax; LY3[4] = ymax; LY3[5] = zmax;
436
437       /* 000 - 001 */
438       LZ1draw = 0; /* forbidden! */
439       LZ1[0] = xmin; LZ1[1] = ymin; LZ1[2] = zmin; LZ1[3] = xmin; LZ1[4] = ymin; LZ1[5] = zmax;
440       /* 100 - 101 */
441       LZ2draw = 1;
442       LZ2[0] = xmax; LZ2[1] = ymin; LZ2[2] = zmin; LZ2[3] = xmax; LZ2[4] = ymin; LZ2[5] = zmax;
443       /* 110 - 111 */
444       LZ3draw = 1;
445       LZ3[0] = xmax; LZ3[1] = ymax; LZ3[2] = zmin; LZ3[3] = xmax; LZ3[4] = ymax; LZ3[5] = zmax;
446
447       break;
448     }
449     case 3: /* d010 */
450     {
451       /* 000 - 100 */
452       LX1draw = 0; /* forbidden */
453       LX1[0] = xmin; LX1[1] = ymin; LX1[2] = zmin; LX1[3] = xmax; LX1[4] = ymin; LX1[5] = zmin;
454       /* 010 - 110 */
455       LX2draw = 1;
456       LX2[0] = xmin; LX2[1] = ymax; LX2[2] = zmin; LX2[3] = xmax; LX2[4] = ymax; LX2[5] = zmin;
457       /* 011 - 111 */
458       LX3draw = 1;
459       LX3[0] = xmin; LX3[1] = ymax; LX3[2] = zmax; LX3[3] = xmax; LX3[4] = ymax; LX3[5] = zmax;
460
461       /* 100 - 110 */
462       LY1draw = 1;
463       LY1[0] = xmax; LY1[1] = ymin; LY1[2] = zmin; LY1[3] = xmax; LY1[4] = ymax; LY1[5] = zmin;
464       /* 000 - 010 */
465       LY2draw = 0; /* forbidden */
466       LY2[0] = xmin; LY2[1] = ymin; LY2[2] = zmin; LY2[3] = xmin; LY2[4] = ymax; LY2[5] = zmin;
467       /* 001 - 011 */
468       LY3draw = 1;
469       LY3[0] = xmin; LY3[1] = ymin; LY3[2] = zmax; LY3[3] = xmin; LY3[4] = ymax; LY3[5] = zmax;
470
471       /* 110 - 111 */
472       LZ1draw = 1;
473       LZ1[0] = xmax; LZ1[1] = ymax; LZ1[2] = zmin; LZ1[3] = xmax; LZ1[4] = ymax; LZ1[5] = zmax;
474       /* 010 - 011 */
475       LZ2draw = 1;
476       LZ2[0] = xmin; LZ2[1] = ymax; LZ2[2] = zmin; LZ2[3] = xmin; LZ2[4] = ymax; LZ2[5] = zmax;
477       /* 000 - 001 */
478       LZ3draw = 0; /* forbidden */
479       LZ3[0] = xmin; LZ3[1] = ymin; LZ3[2] = zmin; LZ3[3] = xmin; LZ3[4] = ymin; LZ3[5] = zmax;
480
481       break;
482     }
483     case 4: /* d001 */
484     {
485       /* 000 - 100 */
486       LX1draw = 0; /* forbidden */
487       LX1[0] = xmin; LX1[1] = ymin; LX1[2] = zmin; LX1[3] = xmax; LX1[4] = ymin; LX1[5] = zmin;
488       /* 001 - 101 */
489       LX2draw = 1;
490       LX2[0] = xmin; LX2[1] = ymin; LX2[2] = zmax; LX2[3] = xmax; LX2[4] = ymin; LX2[5] = zmax;
491       /* 011 - 111 */
492       LX3draw = 1;
493       LX3[0] = xmin; LX3[1] = ymax; LX3[2] = zmax; LX3[3] = xmax; LX3[4] = ymax; LX3[5] = zmax;
494
495       /* 000 - 010 */
496       LY1draw = 0; /* forbidden */
497       LY1[0] = xmin; LY1[1] = ymin; LY1[2] = zmin; LY1[3] = xmin; LY1[4] = ymax; LY1[5] = zmin;
498       /* 001 - 011 */
499       LY2draw = 1;
500       LY2[0] = xmin; LY2[1] = ymin; LY2[2] = zmax; LY2[3] = xmin; LY2[4] = ymax; LY2[5] = zmax;
501       /* 101 - 111 */
502       LY3draw = 1;
503       LY3[0] = xmax; LY3[1] = ymin; LY3[2] = zmax; LY3[3] = xmax; LY3[4] = ymax; LY3[5] = zmax;
504
505       /* 100 - 101 */
506       LZ1draw = 1;
507       LZ1[0] = xmax; LZ1[1] = ymin; LZ1[2] = zmin; LZ1[3] = xmax; LZ1[4] = ymin; LZ1[5] = zmax;
508       /* 000 - 001 */
509       LZ2draw = 0; /* forbidden */
510       LZ2[0] = xmin; LZ2[1] = ymin; LZ2[2] = zmin; LZ2[3] = xmin; LZ2[4] = ymin; LZ2[5] = zmax;
511       /* 010 - 011 */
512       LZ3draw = 1;
513       LZ3[0] = xmin; LZ3[1] = ymax; LZ3[2] = zmin; LZ3[3] = xmin; LZ3[4] = ymax; LZ3[5] = zmax;
514
515       break;
516     }
517     case 5: /* d110 */
518     {
519       /* 000 - 100 */
520       LX1draw = 0; /* forbidden */
521       LX1[0] = xmin; LX1[1] = ymin; LX1[2] = zmin; LX1[3] = xmax; LX1[4] = ymin; LX1[5] = zmin;
522       /* 010 - 110 */
523       LX2draw = 1;
524       LX2[0] = xmin; LX2[1] = ymax; LX2[2] = zmin; LX2[3] = xmax; LX2[4] = ymax; LX2[5] = zmin;
525       /* 011 - 111 */
526       LX3draw = 1;
527       LX3[0] = xmin; LX3[1] = ymax; LX3[2] = zmax; LX3[3] = xmax; LX3[4] = ymax; LX3[5] = zmax;
528
529       /* 000 - 010 */
530       LY1draw = 0; /* forbidden */
531       LY1[0] = xmin; LY1[1] = ymin; LY1[2] = zmin; LY1[3] = xmin; LY1[4] = ymax; LY1[5] = zmin;
532       /* 100 - 110 */
533       LY2draw = 1;
534       LY2[0] = xmax; LY2[1] = ymin; LY2[2] = zmin; LY2[3] = xmax; LY2[4] = ymax; LY2[5] = zmin;
535       /* 101 - 111 */
536       LY3draw = 1;
537       LY3[0] = xmax; LY3[1] = ymin; LY3[2] = zmax; LY3[3] = xmax; LY3[4] = ymax; LY3[5] = zmax;
538
539       /* 100 - 101 */
540       LZ1draw = 1;
541       LZ1[0] = xmax; LZ1[1] = ymin; LZ1[2] = zmin; LZ1[3] = xmax; LZ1[4] = ymin; LZ1[5] = zmax;
542       /* 110 - 111 */
543       LZ2draw = 1;
544       LZ2[0] = xmax; LZ2[1] = ymax; LZ2[2] = zmin; LZ2[3] = xmax; LZ2[4] = ymax; LZ2[5] = zmax;
545       /* 010 - 011 */
546       LZ3draw = 1;
547       LZ3[0] = xmin; LZ3[1] = ymax; LZ3[2] = zmin; LZ3[3] = xmin; LZ3[4] = ymax; LZ3[5] = zmax;
548
549       break;
550     }
551     case 6: /* d101 */
552     {
553       /* 000 - 100 */
554       LX1draw = 0; /* forbidden */
555       LX1[0] = xmin; LX1[1] = ymin; LX1[2] = zmin; LX1[3] = xmax; LX1[4] = ymin; LX1[5] = zmin;
556       /* 001 - 101 */
557       LX2draw = 1;
558       LX2[0] = xmin; LX2[1] = ymin; LX2[2] = zmax; LX2[3] = xmax; LX2[4] = ymin; LX2[5] = zmax;
559       /* 011 - 111 */
560       LX3draw = 1;
561       LX3[0] = xmin; LX3[1] = ymax; LX3[2] = zmax; LX3[3] = xmax; LX3[4] = ymax; LX3[5] = zmax;
562
563       /* 100 - 110 */
564       LY1draw = 1;
565       LY1[0] = xmax; LY1[1] = ymin; LY1[2] = zmin; LY1[3] = xmax; LY1[4] = ymax; LY1[5] = zmin;
566       /* 101 - 111 */
567       LY2draw = 1;
568       LY2[0] = xmax; LY2[1] = ymin; LY2[2] = zmax; LY2[3] = xmax; LY2[4] = ymax; LY2[5] = zmax;
569       /* 001 - 011 */
570       LY3draw = 1;
571       LY3[0] = xmin; LY3[1] = ymin; LY3[2] = zmax; LY3[3] = xmin; LY3[4] = ymax; LY3[5] = zmax;
572
573       /* 000 - 001 */
574       LZ1draw = 0; /* forbidden */
575       LZ1[0] = xmin; LZ1[1] = ymin; LZ1[2] = zmin; LZ1[3] = xmin; LZ1[4] = ymin; LZ1[5] = zmax;
576       /* 100 - 101 */
577       LZ2draw = 1;
578       LZ2[0] = xmax; LZ2[1] = ymin; LZ2[2] = zmin; LZ2[3] = xmax; LZ2[4] = ymin; LZ2[5] = zmax;
579       /* 110 - 111 */
580       LZ3draw = 1;
581       LZ3[0] = xmax; LZ3[1] = ymax; LZ3[2] = zmin; LZ3[3] = xmax; LZ3[4] = ymax; LZ3[5] = zmax;
582
583       break;
584     }
585     case 7: /* d011 */
586     {
587       /* 001 - 101 */
588       LX1draw = 1;
589       LX1[0] = xmin; LX1[1] = ymin; LX1[2] = zmax; LX1[3] = xmax; LX1[4] = ymin; LX1[5] = zmax;
590       /* 011 - 111 */
591       LX2draw = 1;
592       LX2[0] = xmin; LX2[1] = ymax; LX2[2] = zmax; LX2[3] = xmax; LX2[4] = ymax; LX2[5] = zmax;
593       /* 010 - 110 */
594       LX3draw = 1;
595       LX3[0] = xmin; LX3[1] = ymax; LX3[2] = zmin; LX3[3] = xmax; LX3[4] = ymax; LX3[5] = zmin;
596
597       /* 000 - 010 */
598       LY1draw = 0; /* forbidden */
599       LY1[0] = xmin; LY1[1] = ymin; LY1[2] = zmin; LY1[3] = xmin; LY1[4] = ymax; LY1[5] = zmin;
600       /* 001 - 011 */
601       LY2draw = 1;
602       LY2[0] = xmin; LY2[1] = ymin; LY2[2] = zmax; LY2[3] = xmin; LY2[4] = ymax; LY2[5] = zmax;
603       /* 101 - 111 */
604       LY3draw = 1;
605       LY3[0] = xmax; LY3[1] = ymin; LY3[2] = zmax; LY3[3] = xmax; LY3[4] = ymax; LY3[5] = zmax;
606
607       /* 000 - 001 */
608       LZ1draw = 0; /* forbidden */
609       LZ1[0] = xmin; LZ1[1] = ymin; LZ1[2] = zmin; LZ1[3] = xmin; LZ1[4] = ymin; LZ1[5] = zmax;
610       /* 010 - 011 */
611       LZ2draw = 1;
612       LZ2[0] = xmin; LZ2[1] = ymax; LZ2[2] = zmin; LZ2[3] = xmin; LZ2[4] = ymax; LZ2[5] = zmax;
613       /* 110 - 111 */
614       LZ3draw = 1;
615       LZ3[0] = xmax; LZ3[1] = ymax; LZ3[2] = zmin; LZ3[3] = xmax; LZ3[4] = ymax; LZ3[5] = zmax;
616
617       break;
618     }
619     case 8: /* d111 */
620     {
621       /* 010 - 110 */
622       LX1draw = 1;
623       LX1[0] = xmin; LX1[1] = ymax; LX1[2] = zmin; LX1[3] = xmax; LX1[4] = ymax; LX1[5] = zmin;
624       /* 011 - 111 */
625       LX2draw = 1;
626       LX2[0] = xmin; LX2[1] = ymax; LX2[2] = zmax; LX2[3] = xmax; LX2[4] = ymax; LX2[5] = zmax;
627       /* 001 - 101 */
628       LX3draw = 1;
629       LX3[0] = xmin; LX3[1] = ymin; LX3[2] = zmax; LX3[3] = xmax; LX3[4] = ymin; LX3[5] = zmax;
630
631       /* 100 - 110 */
632       LY1draw = 1;
633       LY1[0] = xmax; LY1[1] = ymin; LY1[2] = zmin; LY1[3] = xmax; LY1[4] = ymax; LY1[5] = zmin;
634       /* 101 - 111 */
635       LY2draw = 1;
636       LY2[0] = xmax; LY2[1] = ymin; LY2[2] = zmax; LY2[3] = xmax; LY2[4] = ymax; LY2[5] = zmax;
637       /* 001 - 011 */
638       LY3draw = 1;
639       LY3[0] = xmin; LY3[1] = ymin; LY3[2] = zmax; LY3[3] = xmin; LY3[4] = ymax; LY3[5] = zmax;
640
641       /* 100 - 101 */
642       LZ1draw = 1;
643       LZ1[0] = xmax; LZ1[1] = ymin; LZ1[2] = zmin; LZ1[3] = xmax; LZ1[4] = ymin; LZ1[5] = zmax;
644       /* 110 - 111 */
645       LZ2draw = 1;
646       LZ2[0] = xmax; LZ2[1] = ymax; LZ2[2] = zmin; LZ2[3] = xmax; LZ2[4] = ymax; LZ2[5] = zmax;
647       /* 010 - 011 */
648       LZ3draw = 1;
649       LZ3[0] = xmin; LZ3[1] = ymax; LZ3[2] = zmin; LZ3[3] = xmin; LZ3[4] = ymax; LZ3[5] = zmax;
650
651       break;
652     }
653   }
654
655   /* Draw the graduated trihedron */
656   unsigned int i, j, offset;
657   float m1[3], m2[3];
658   float step, dx, dy, dz;
659
660   /* Grid */
661   if (myDrawGrid)
662   {
663     glColor3fv(myGridColor);
664     glBegin(GL_LINES);
665     /* Boundary grid-lines */
666     if (LX1draw == 1)
667     {
668       glVertex3fv(&(LX1[0]));
669       glVertex3fv(&(LX1[3]));
670     }
671     if (LX2draw == 1)
672     {
673       glVertex3fv(&(LX2[0]));
674       glVertex3fv(&(LX2[3]));
675     }
676     if (LX3draw == 1)
677     {
678       glVertex3fv(&(LX3[0]));
679       glVertex3fv(&(LX3[3]));
680     }
681     if (LY1draw == 1)
682     {
683       glVertex3fv(&(LY1[0]));
684       glVertex3fv(&(LY1[3]));
685     }
686     if (LY2draw == 1)
687     {
688       glVertex3fv(&(LY2[0]));
689       glVertex3fv(&(LY2[3]));
690     }
691     if (LY3draw == 1)
692     {
693       glVertex3fv(&(LY3[0]));
694       glVertex3fv(&(LY3[3]));
695     }
696     if (LZ1draw == 1)
697     {
698       glVertex3fv(&(LZ1[0]));
699       glVertex3fv(&(LZ1[3]));
700     }
701     if (LZ2draw == 1)
702     {
703       glVertex3fv(&(LZ2[0]));
704       glVertex3fv(&(LZ2[3]));
705     }
706     if (LZ3draw == 1)
707     {
708       glVertex3fv(&(LZ3[0]));
709       glVertex3fv(&(LZ3[3]));
710     }
711     glEnd();
712
713     /* Intermediate grid-lines */
714     /* X-Grid lines */
715     if (myNbX > 0)
716     {
717       i = myDrawAxes ? 1 : 0;
718       step = fabsf(LX1[3] - LX1[0]) / (float) myNbX;
719       while (i < myNbX)
720       {
721         glBegin(GL_LINE_STRIP);
722         glVertex3f(LX1[0] + i * step, LX1[1], LX1[2]);
723         glVertex3f(LX2[0] + i * step, LX2[1], LX2[2]);
724         glVertex3f(LX3[0] + i * step, LX3[1], LX3[2]);
725         glEnd();
726         i++;
727       }
728     }
729     /* Y-Grid lines */
730     if (myNbY > 0)
731     {
732       i = myDrawAxes ? 1 : 0;
733       step = fabsf(LY1[4] - LY1[1]) / (float) myNbY;
734       while (i < myNbY)
735       {
736         glBegin(GL_LINE_STRIP);
737         glVertex3f(LY1[0], LY1[1] + i * step, LY1[2]);
738         glVertex3f(LY2[0], LY2[1] + i * step, LY2[2]);
739         glVertex3f(LY3[0], LY3[1] + i * step, LY3[2]);
740         glEnd();
741         i++;
742       }
743     }
744     /* Z-Grid lines */
745     if (myNbZ > 0)
746     {
747       i = myDrawAxes ? 1 : 0;
748       step = fabsf(LZ1[5] - LZ1[2]) / (float) myNbZ;
749       while (i < myNbZ)
750       {
751         glBegin(GL_LINE_STRIP);
752         glVertex3f(LZ1[0], LZ1[1], LZ1[2] + i * step);
753         glVertex3f(LZ2[0], LZ2[1], LZ2[2] + i * step);
754         glVertex3f(LZ3[0], LZ3[1], LZ3[2] + i * step);
755         glEnd();
756         i++;
757       }
758     }
759   }
760
761   /* Axes (arrows) */
762   if (myDrawAxes)
763   {
764     /* X-axis */
765     glColor3fv(myXColor);
766     drawArrow(xmin, ymin, zmin, xmax, ymin, zmin, normal[0], normal[1], normal[2]);
767
768     /* Y-axis */
769     glColor3fv(myYColor);
770     drawArrow(xmin, ymin, zmin, xmin, ymax, zmin, normal[0], normal[1], normal[2]);
771
772     /* Z-axis */
773     glColor3fv(myZColor);
774     drawArrow(xmin, ymin, zmin, xmin, ymin, zmax, normal[0], normal[1], normal[2]);
775   }
776
777   /* Names of axes & values */
778   char textValue[128];
779   wchar_t wtextValue[128];
780
781   if (myDrawXName || myDrawXValues)
782   {
783     /* Middle point of the first X-axis */
784     m1[0] = 0.5f * (LX1[0] + LX1[3]);
785     m1[1] = 0.5f * (LX1[1] + LX1[4]);
786     m1[2] = 0.5f * (LX1[2] + LX1[5]);
787
788     /* Middle point of the second X-axis */
789     m2[0] = 0.5f * (LX2[0] + LX2[3]);
790     m2[1] = 0.5f * (LX2[1] + LX2[4]);
791     m2[2] = 0.5f * (LX2[2] + LX2[5]);
792
793     /* Apply offset to m1 */
794     dy = m1[1] - m2[1];
795     if (fabsf(dy) > 1.e-7f)
796     {
797       dy = (dy > 0.0f)? 1.0f : -1.0f;
798     }
799     dz = m1[2] - m2[2];
800     if (fabsf(dz) > 1.e-7f)
801     {
802       dz = (dz > 0.0f)? 1.0f : -1.0f;
803     }
804     m2[1] = dpix * dy;
805     m2[2] = dpix * dz;
806
807     /* Name of X-axis */
808     if (myDrawXName)
809     {
810       glColor3fv(myXNameColor);
811       offset = myXAxisOffset + myXTickmarkLength;
812       drawText(AWorkspace, myXName, myFontOfNames, myStyleOfNames, mySizeOfNames, 
813                m1[0], m1[1] + offset * m2[1], m1[2] + offset * m2[2]);
814     }
815
816     /* X-values */
817     if (myDrawXValues && myNbX > 0)
818     {
819       glColor3fv(myXColor);
820
821       i = 0;
822       step = fabsf(LX1[3] - LX1[0]) / (float) myNbX;
823       offset = myXOffset + myXTickmarkLength;
824       while (i <= myNbX)
825       {
826         sprintf(textValue, "%g", LX1[0] + i * step);
827         j = 0; while (wtextValue[j] = textValue[j]) j++;
828         drawText(AWorkspace, wtextValue, myFontOfValues, myStyleOfValues, mySizeOfValues, 
829                  LX1[0] + i * step, m1[1] + offset * m2[1], m1[2] + offset * m2[2]);
830         i++;
831       }
832     }
833
834     /* X-tickmark */
835     if (myDrawXTickmarks && myNbX > 0)
836     {
837       glColor3fv(myGridColor);
838
839       i = 0;
840       step = fabsf(LX1[3] - LX1[0]) / (float) myNbX;
841       while (i <= myNbX)
842       {
843         glBegin(GL_LINES);
844         glVertex3f(LX1[0] + i * step, m1[1],                             m1[2]);
845         glVertex3f(LX1[0] + i * step, m1[1] + myXTickmarkLength * m2[1], m1[2] + myXTickmarkLength * m2[2]);
846         glEnd();
847         i++;
848       }
849     }
850   }
851
852   if (myDrawYName || myDrawYValues)
853   {
854     /* Middle point of the first Y-axis */
855     m1[0] = 0.5f * (LY1[0] + LY1[3]);
856     m1[1] = 0.5f * (LY1[1] + LY1[4]);
857     m1[2] = 0.5f * (LY1[2] + LY1[5]);
858
859     /* Middle point of the second Y-axis */
860     m2[0] = 0.5f * (LY2[0] + LY2[3]);
861     m2[1] = 0.5f * (LY2[1] + LY2[4]);
862     m2[2] = 0.5f * (LY2[2] + LY2[5]);
863
864     /* Apply offset to m1 */
865     dx = m1[0] - m2[0];
866     if (fabsf(dx) > 1.e-7f)
867     {
868       dx = (dx > 0.0f)? 1.0f : -1.0f;
869     }
870     dz = m1[2] - m2[2];
871     if (fabsf(dz) > 1.e-7f)
872     {
873       dz = (dz > 0.0f)? 1.0f : -1.0f;
874     }
875
876     m2[0] = dpix * dx;
877     m2[2] = dpix * dz;
878
879     /* Name of Y-axis */
880     if (myDrawYName)
881     {
882       glColor3fv(myYNameColor);
883       offset = myYAxisOffset + myYTickmarkLength;
884       drawText(AWorkspace, myYName, myFontOfNames, myStyleOfNames, mySizeOfNames, 
885                m1[0] + offset * m2[0], m1[1], m1[2] + offset * m2[2]);
886     }
887
888     /* Y-values */
889     if (myDrawYValues && myNbY > 0)
890     {
891       glColor3fv(myYColor);
892
893       i = 0;
894       step = fabsf(LY1[4] - LY1[1]) / (float) myNbY;
895       offset = myYOffset + myYTickmarkLength;
896       while (i <= myNbY)
897       {
898         sprintf(textValue, "%g", LY1[1] + i * step);
899         j = 0; while (wtextValue[j] = textValue[j]) j++;
900         drawText(AWorkspace, wtextValue, myFontOfValues, myStyleOfValues, mySizeOfValues, 
901                  m1[0] + offset * m2[0], LY1[1] + i * step, m1[2] + offset * m2[2]);
902         i++;
903       }
904     }
905
906     /* Y-tickmark */
907     if (myDrawYTickmarks && myNbY > 0)
908     {
909       glColor3fv(myGridColor);
910
911       i = 0;
912       step = fabsf(LY1[4] - LY1[1]) / (float) myNbY;
913       while (i <= myNbY)
914       {
915         glBegin(GL_LINES);
916         glVertex3f(m1[0],                             LY1[1] + i * step, m1[2]);
917         glVertex3f(m1[0] + myYTickmarkLength * m2[0], LY1[1] + i * step, m1[2] + myYTickmarkLength * m2[2]);
918         glEnd();
919         i++;
920       }
921     }
922   }
923
924   if (myDrawZName || myDrawZValues)
925   {
926     /* Middle point of the first Z-axis */
927     m1[0] = 0.5f * (LZ1[0] + LZ1[3]);
928     m1[1] = 0.5f * (LZ1[1] + LZ1[4]);
929     m1[2] = 0.5f * (LZ1[2] + LZ1[5]);
930
931     /* Middle point of the second Z-axis */
932     m2[0] = 0.5f * (LZ2[0] + LZ2[3]);
933     m2[1] = 0.5f * (LZ2[1] + LZ2[4]);
934     m2[2] = 0.5f * (LZ2[2] + LZ2[5]);
935
936     /* Apply offset to m1 */
937     dx = m1[0] - m2[0];
938     if (fabsf(dx) > 1.e-7f)
939     {
940       dx = (dx > 0.0f)? 1.0f : -1.0f;
941     }
942     dy = m1[1] - m2[1];
943     if (fabsf(dy) > 1.e-7f)
944     {
945       dy = (dy > 0.0f)? 1.0f : -1.0f;
946     }
947
948     m2[0] = dpix * dx;
949     m2[1] = dpix * dy;
950
951     /* Name of Z-axis */
952     if (myDrawZName)
953     {
954       glColor3fv(myZNameColor);
955       offset = myZAxisOffset + myZTickmarkLength;
956       drawText(AWorkspace, myZName, myFontOfNames, myStyleOfNames, mySizeOfNames, 
957                m1[0] + offset * m2[0], m1[1] + offset * m2[1], m1[2]);
958     }
959
960     /* Z-values */
961     if (myDrawZValues && myNbZ > 0)
962     {
963       glColor3fv(myZColor);
964
965       i = 0;
966       step = fabsf(LZ1[5] - LZ1[2]) / (float) myNbZ;
967       offset = myZOffset + myZTickmarkLength;
968       while (i <= myNbZ)
969       {
970         sprintf(textValue, "%g", LZ1[2] + i * step);
971         j = 0; while (wtextValue[j] = textValue[j]) j++;
972         drawText(AWorkspace, wtextValue, myFontOfValues, myStyleOfValues, mySizeOfValues, 
973                  m1[0] + offset * m2[0], m1[1] + offset * m2[1], LZ1[2] + i * step);
974         i++;
975       }
976     }
977
978     /* Z-tickmark */
979     if (myDrawZTickmarks && myNbZ > 0)
980     {
981       glColor3fv(myGridColor);
982
983       i = 0;
984       step = fabsf(LZ1[5] - LZ1[2]) / (float) myNbZ;
985       while (i <= myNbZ)
986       {
987         glBegin(GL_LINES);
988         glVertex3f(m1[0],                             m1[1],                             LZ1[2] + i * step);
989         glVertex3f(m1[0] + myZTickmarkLength * m2[0], m1[1] + myZTickmarkLength * m2[1], LZ1[2] + i * step);
990         glEnd();
991         i++;
992       }
993     }
994   }
995
996   /* Activate the lighting if it was turned off by this method call */
997   if (light)
998     glEnable(GL_LIGHTING);
999
1000   AWorkspace->SetAspectLine(oldAspectLine);
1001 }
1002
1003 //call_graduatedtrihedron_minmaxvalues
1004 void OpenGl_GraduatedTrihedron::SetMinMax (const Standard_ShortReal xMin, const Standard_ShortReal yMin, const Standard_ShortReal zMin,
1005                                           const Standard_ShortReal xMax, const Standard_ShortReal yMax, const Standard_ShortReal zMax)
1006 {
1007   xmin = xMin;
1008   ymin = yMin;
1009   zmin = zMin;
1010   xmax = xMax;
1011   ymax = yMax;
1012   zmax = zMax;
1013 }