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