1 // File: OpenGl_graduatedtrihedron.cxx
2 // Created: 6 March 2011
3 // Author: Sergey ZERCHANINOV
4 // Copyright: OPEN CASCADE SA 2011
6 #include <OpenGl_tgl_all.hxx>
7 #include <OpenGl_graduatedtrihedron.hxx>
17 #include <InterfaceGraphic_Graphic3d.hxx>
18 #include <InterfaceGraphic_Aspect.hxx>
19 #include <InterfaceGraphic_Visual3d.hxx>
21 #include <OpenGl_tgl_funcs.hxx>
22 #include <OpenGl_tgl_subrs.hxx>
23 #include <OpenGl_TextRender.hxx>
32 struct TEL_GRADUATEDTRIHEDRON_DATA
35 wchar_t *xname, *yname, *zname;
36 unsigned char xdrawname, ydrawname, zdrawname;
37 unsigned char xdrawvalues, ydrawvalues, zdrawvalues;
38 unsigned char drawgrid;
39 unsigned char drawaxes;
40 unsigned int nbx, nby, nbz;
41 int xoffset, yoffset, zoffset;
42 int xaxisoffset, yaxisoffset, zaxisoffset;
43 unsigned char xdrawtickmarks, ydrawtickmarks, zdrawtickmarks;
44 unsigned int xtickmarklength, ytickmarklength, ztickmarklength;
53 OSD_FontAspect styleOfNames;
56 OSD_FontAspect styleOfValues;
58 minMaxValuesCallback cbCubicAxes;
59 void* ptrVisual3dView;
60 IMPLEMENT_MEMORY_OPERATORS
62 typedef TEL_GRADUATEDTRIHEDRON_DATA* tel_graduatedtrihedron_data;
64 /* Graduated trihedron data */
65 static int nbWsIds = 0; /* Number of the views (size of the arrays below */
66 static tel_graduatedtrihedron_data* graduatedTrihedronData = 0; /* The array contains graduated trihedron data of all views */
69 float xmin = 0.0f, ymin = 0.0f, zmin = 0.0f, xmax = 100.0f, ymax = 100.0f, zmax = 100.0f;
71 static void copyData(const Graphic3d_CGraduatedTrihedron *fromData, TEL_GRADUATEDTRIHEDRON_DATA* toData)
77 len = fromData->xname.Length();
80 Standard_ExtString iname = fromData->xname.ToExtString();
81 toData->xname = new wchar_t[len+1];
82 len = 0; while (toData->xname[len] = (wchar_t)(iname[len])) len++;
87 len = fromData->yname.Length();
90 Standard_ExtString iname = fromData->yname.ToExtString();
91 toData->yname = new wchar_t[len+1];
92 len = 0; while (toData->yname[len] = (wchar_t)(iname[len])) len++;
97 len = fromData->zname.Length();
100 Standard_ExtString iname = fromData->zname.ToExtString();
101 toData->zname = new wchar_t[len+1];
102 len = 0; while (toData->zname[len] = (wchar_t)(iname[len])) len++;
105 toData->zname = NULL;
107 toData->xdrawname = fromData->xdrawname;
108 toData->ydrawname = fromData->ydrawname;
109 toData->zdrawname = fromData->zdrawname;
111 toData->xdrawvalues = fromData->xdrawvalues;
112 toData->ydrawvalues = fromData->ydrawvalues;
113 toData->zdrawvalues = fromData->zdrawvalues;
115 toData->drawgrid = fromData->drawgrid;
117 toData->drawaxes = fromData->drawaxes;
118 /* Number of splits along axes */
119 toData->nbx = fromData->nbx;
120 toData->nby = fromData->nby;
121 toData->nbz = fromData->nbz;
122 /* Offset for drawing values */
123 toData->xoffset = fromData->xoffset;
124 toData->yoffset = fromData->yoffset;
125 toData->zoffset = fromData->zoffset;
126 /* Offset for drawing names of axes */
127 toData->xaxisoffset = fromData->xaxisoffset;
128 toData->yaxisoffset = fromData->yaxisoffset;
129 toData->zaxisoffset = fromData->zaxisoffset;
131 toData->xdrawtickmarks = fromData->xdrawtickmarks;
132 toData->ydrawtickmarks = fromData->ydrawtickmarks;
133 toData->zdrawtickmarks = fromData->zdrawtickmarks;
134 /* Length of tickmarks */
135 toData->xtickmarklength = fromData->xtickmarklength;
136 toData->ytickmarklength = fromData->ytickmarklength;
137 toData->ztickmarklength = fromData->ztickmarklength;
139 toData->gridcolor[0] = (float) fromData->gridcolor.Red();
140 toData->gridcolor[1] = (float) fromData->gridcolor.Green();
141 toData->gridcolor[2] = (float) fromData->gridcolor.Blue();
143 toData->xnamecolor[0] = (float) fromData->xnamecolor.Red();
144 toData->xnamecolor[1] = (float) fromData->xnamecolor.Green();
145 toData->xnamecolor[2] = (float) fromData->xnamecolor.Blue();
147 toData->ynamecolor[0] = (float) fromData->ynamecolor.Red();
148 toData->ynamecolor[1] = (float) fromData->ynamecolor.Green();
149 toData->ynamecolor[2] = (float) fromData->ynamecolor.Blue();
151 toData->znamecolor[0] = (float) fromData->znamecolor.Red();
152 toData->znamecolor[1] = (float) fromData->znamecolor.Green();
153 toData->znamecolor[2] = (float) fromData->znamecolor.Blue();
154 /* X color of axis and values */
155 toData->xcolor[0] = (float) fromData->xcolor.Red();
156 toData->xcolor[1] = (float) fromData->xcolor.Green();
157 toData->xcolor[2] = (float) fromData->xcolor.Blue();
158 /* Y color of axis and values */
159 toData->ycolor[0] = (float) fromData->ycolor.Red();
160 toData->ycolor[1] = (float) fromData->ycolor.Green();
161 toData->ycolor[2] = (float) fromData->ycolor.Blue();
162 /* Z color of axis and values */
163 toData->zcolor[0] = (float) fromData->zcolor.Red();
164 toData->zcolor[1] = (float) fromData->zcolor.Green();
165 toData->zcolor[2] = (float) fromData->zcolor.Blue();
166 /* Font name of names of axes: Courier, Arial, ... */
167 len = fromData->fontOfNames.Length();
168 toData->fontOfNames = new char[len+1];
170 strcpy(toData->fontOfNames, fromData->fontOfNames.ToCString());
172 toData->fontOfNames[0] = L'\0';
173 /* Style of names of axes: OSD_FA_Regular, OSD_FA_Bold, ... */
174 toData->styleOfNames = fromData->styleOfNames;
175 /* Size of names of axes: 8, 10, 12, 14, ... */
176 toData->sizeOfNames = fromData->sizeOfNames;
177 /* Font name of values: Courier, Arial, ... */
178 len = fromData->fontOfValues.Length();
179 toData->fontOfValues = new char[len+1];
181 strcpy(toData->fontOfValues, fromData->fontOfValues.ToCString());
183 toData->fontOfValues[0] = L'\0';
184 /* Style of values: OSD_FA_Regular, OSD_FA_Bold, ... */
185 toData->styleOfValues = fromData->styleOfValues;
186 /* Size of values: 8, 10, 12, 14, ... */
187 toData->sizeOfValues = fromData->sizeOfValues;
188 /* Callback - updater of boundary box */
189 toData->cbCubicAxes = fromData->cbCubicAxes;
190 toData->ptrVisual3dView = fromData->ptrVisual3dView;
193 static void freeData()
198 tel_graduatedtrihedron_data gtdata;
199 for (i = 0; i < nbWsIds; i++)
201 gtdata = graduatedTrihedronData[i];
205 delete[] gtdata->xname;
207 delete[] gtdata->yname;
209 delete[] gtdata->zname;
212 if (gtdata->fontOfNames)
213 delete[] gtdata->fontOfNames;
214 if (gtdata->fontOfValues)
215 delete[] gtdata->fontOfValues;
219 delete graduatedTrihedronData;
220 graduatedTrihedronData = 0;
225 static int getGraduatedTrihedronDataIndex(int WsId)
228 for (; i < nbWsIds; i++)
230 if (graduatedTrihedronData[i]->WsId == WsId)
236 /* Normal of the view (not normalized!) */
237 static float getNormal(float* normal)
240 GLdouble model_matrix[16], proj_matrix[16];
241 double x1, y1, z1, x2, y2, z2, x3, y3, z3;
242 double dx1, dy1, dz1, dx2, dy2, dz2, width;
244 glGetDoublev(GL_MODELVIEW_MATRIX, model_matrix);
245 glGetDoublev(GL_PROJECTION_MATRIX, proj_matrix);
246 glGetIntegerv(GL_VIEWPORT, viewport);
248 gluUnProject(viewport[0], viewport[1], 0., model_matrix, proj_matrix, viewport, &x1, &y1, &z1);
249 gluUnProject(viewport[0] + viewport[2], viewport[1], 0., model_matrix, proj_matrix, viewport, &x2, &y2, &z2);
250 gluUnProject(viewport[0], viewport[1] + viewport[3], 0., model_matrix, proj_matrix, viewport, &x3, &y3, &z3);
252 /* Normal out of user is p1p3^p1p2 */
253 dx1 = x3 - x1; dy1 = y3 - y1; dz1 = z3 - z1;
254 dx2 = x2 - x1; dy2 = y2 - y1; dz2 = z2 - z1;
255 normal[0] = (float) (dy1 * dz2 - dz1 * dy2);
256 normal[1] = (float) (dz1 * dx2 - dx1 * dz2);
257 normal[2] = (float) (dx1 * dy2 - dy1 * dx2);
259 /* Distance corresponding to 1 pixel */
260 width = sqrt(dx2 * dx2 + dy2 * dy2 + dz2 * dz2);
261 return (float) width / (float) viewport[2];
264 static float getDistance2Corner(float* normal, float* center, float x, float y, float z)
266 return normal[0] * (x - center[0]) + normal[1] * (y - center[1]) + normal[2] * (z - center[2]);
269 static char getFarestCorner(float d000, float d100, float d010, float d001,
270 float d110, float d101, float d011, float d111)
273 d000 > d100 && d000 > d010 && d000 > d001 && d000 > d110 &&
274 d000 > d101 && d000 > d011 && d000 > d111)
278 else if (d100 > 0.0f &&
279 d100 > d000 && d100 > d010 && d100 > d001 && d100 > d110 &&
280 d100 > d101 && d100 > d011 && d100 > d111)
284 else if (d010 > 0.0f &&
285 d010 > d000 && d010 > d100 && d010 > d001 && d010 > d110 &&
286 d010 > d101 && d010 > d011 && d010 > d111)
290 else if (d001 > 0.0f &&
291 d001 > d000 && d001 > d100 && d001 > d010 && d001 > d110 &&
292 d001 > d101 && d001 > d011 && d001 > d111)
296 else if (d110 > 0.0f &&
297 d110 > d000 && d110 > d100 && d110 > d010 && d110 > d001 &&
298 d110 > d101 && d110 > d011 && d110 > d111)
302 else if (d101 > 0.0f &&
303 d101 > d000 && d101 > d100 && d101 > d010 && d101 > d001 &&
304 d101 > d110 && d101 > d011 && d101 > d111)
308 else if (d011 > 0.0f &&
309 d011 > d000 && d011 > d100 && d011 > d010 && d011 > d001 &&
310 d011 > d110 && d011 > d101 && d011 > d111)
317 static void drawText(const wchar_t* text, char* font, OSD_FontAspect style, int size, float x, float y, float z)
319 OpenGl_TextRender* textRenderer = OpenGl_TextRender::instance();
320 const GLuint fontBase = textRenderer->FindFont((Tchar*) font, style, (float) size);
321 textRenderer->RenderText(text, fontBase, 0, x, y, z);
323 /* 4 OCC 6.3.1 and older:
327 fontBase = tXfmsetfont (1.0F, 1.0F);
329 fontBase = WNTSetFont (1.0F, 1.0F);
333 tXfmprstr(text, fontBase, x, y, z);
335 WNTPuts(text, fontBase, 0, x, y, z);
340 static void drawArrow(float x1, float y1, float z1,
341 float x2, float y2, float z2,
342 float xn, float yn, float zn)
348 float xa1, ya1, za1, xa2, ya2, za2;
350 /* Start of arrow: at 10% from the end */
351 x0 = x1 + 0.9f * (x2 - x1); y0 = y1 + 0.9f * (y2 - y1); z0 = z1 + 0.9f * (z2 - z1);
353 /* Base of the arrow */
354 xa = (x2 - x0); ya = (y2 - y0); za = (z2 - z0);
356 /* Height of the arrow */
357 h = sqrtf(xa * xa + ya * ya + za * za);
360 xa = xa / h; ya = ya / h; za = za / h;
362 /* Radial direction to the arrow */
363 xr = ya * zn - za * yn;
364 yr = za * xn - xa * zn;
365 zr = xa * yn - ya * xn;
367 /* Normalize the radial vector */
368 r = sqrtf(xr * xr + yr * yr + zr * zr);
371 xr = xr / r; yr = yr / r; zr = zr / r;
373 /* First point of the base of the arrow */
375 xr = r * xr; yr = r * yr; zr = r * zr;
376 xa1 = x0 + xr; ya1 = y0 + yr; za1 = z0 + zr;
378 /* Second point of the base of the arrow */
379 xa2 = x0 - xr; ya2 = y0 - yr; za2 = z0 - zr;
381 /* Draw a line to the arrow */
383 glVertex3f(x1, y1, z1);
384 glVertex3f(x0, y0, z0);
387 /* Draw a triangle of the arrow */
388 glBegin(GL_LINE_LOOP);
389 glVertex3f(xa1, ya1, za1);
390 glVertex3f(xa2, ya2, za2);
391 glVertex3f(x2, y2, z2);
395 TStatus call_graduatedtrihedron_display(int WsId, const Graphic3d_CGraduatedTrihedron &data)
397 /* Initialize data for a new view */
398 int index = getGraduatedTrihedronDataIndex(WsId);
401 /* Extend array for +1 */
402 tel_graduatedtrihedron_data* newGraduatedTrihedronData = new tel_graduatedtrihedron_data[nbWsIds+1];
404 /* Copy existing contents */
406 for (i = 0; i < nbWsIds; i++)
407 newGraduatedTrihedronData[i] = graduatedTrihedronData[i];
411 newGraduatedTrihedronData[index] = new TEL_GRADUATEDTRIHEDRON_DATA;
412 newGraduatedTrihedronData[index]->WsId = WsId;
414 /* Switch to new array */
415 delete graduatedTrihedronData;
416 graduatedTrihedronData = newGraduatedTrihedronData;
418 copyData(&data, graduatedTrihedronData[index]);
419 return call_graduatedtrihedron_redraw(WsId);
422 TStatus call_graduatedtrihedron_erase(int WsId)
424 int index = getGraduatedTrihedronDataIndex(WsId);
426 return TSuccess; /* Nothing to remove */
428 /* If trihedron is displayed only in one view, just free the array and set nbWsIds equal to 0. */
435 /* Reduce array for -1 */
436 tel_graduatedtrihedron_data* newGraduatedTrihedronData = new tel_graduatedtrihedron_data[nbWsIds-1];
438 /* Copy existing contents */
440 for (i = 0, j = 0; i < nbWsIds; i++)
442 if (graduatedTrihedronData[i]->WsId != WsId)
443 newGraduatedTrihedronData[j++] = graduatedTrihedronData[i];
447 /* Switch to new array */
448 delete graduatedTrihedronData;
449 graduatedTrihedronData = newGraduatedTrihedronData;
454 TStatus call_graduatedtrihedron_redraw(int WsId)
456 /* Get index of the trihedron data */
457 int index = getGraduatedTrihedronDataIndex(WsId);
461 tel_graduatedtrihedron_data data = graduatedTrihedronData[index];
463 /* Update boundary box */
464 if (data->cbCubicAxes)
465 data->cbCubicAxes(data->ptrVisual3dView);
467 /* Disable lighting for lines */
468 GLboolean light = glIsEnabled(GL_LIGHTING);
470 glDisable(GL_LIGHTING);
472 /* Find the farest point of bounding box */
474 /* Get normal of the view out of user. */
475 /* Also, the method return distance corresponding to 1 pixel */
477 float dpix = getNormal(normal);
479 /* Normalize normal */
480 float d = sqrtf(normal[0] * normal[0] + normal[1] * normal[1] + normal[2] * normal[2]);
485 /* Get central point of bounding box */
487 center[0] = 0.5f * (xmin + xmax);
488 center[1] = 0.5f * (ymin + ymax);
489 center[2] = 0.5f * (zmin + zmax);
491 /* Check distance to corners of bounding box along the normal */
492 float d000 = getDistance2Corner(normal, center, xmin, ymin, zmin);
493 float d100 = getDistance2Corner(normal, center, xmax, ymin, zmin);
494 float d010 = getDistance2Corner(normal, center, xmin, ymax, zmin);
495 float d001 = getDistance2Corner(normal, center, xmin, ymin, zmax);
496 float d110 = getDistance2Corner(normal, center, xmax, ymax, zmin);
497 float d101 = getDistance2Corner(normal, center, xmax, ymin, zmax);
498 float d011 = getDistance2Corner(normal, center, xmin, ymax, zmax);
499 float d111 = getDistance2Corner(normal, center, xmax, ymax, zmax);
500 unsigned char farestCorner = getFarestCorner(d000, d100, d010, d001, d110, d101, d011, d111);
502 /* Choose axes for the grid. */
503 float LX1[6], LX2[6], LX3[6]; /* Lines along X direction */
504 float LY1[6], LY2[6], LY3[6]; /* Lines along Y direction */
505 float LZ1[6], LZ2[6], LZ3[6]; /* Lines along Z direction */
506 unsigned char LX1draw, LX2draw, LX3draw; /* Allows drawing of X-line (000 - 100 is forbidden) */
507 unsigned char LY1draw, LY2draw, LY3draw; /* Allows drawing of Y-line (000 - 010 is forbidden) */
508 unsigned char LZ1draw, LZ2draw, LZ3draw; /* Allows drawing of Z-line (000 - 001 is forbidden) */
510 /* The first axis will be used for drawing the text and the values. */
511 switch (farestCorner)
517 LX1[0] = xmin; LX1[1] = ymin; LX1[2] = zmax; LX1[3] = xmax; LX1[4] = ymin; LX1[5] = zmax;
519 LX2draw = 0; /* forbidden! */
520 LX2[0] = xmin; LX2[1] = ymin; LX2[2] = zmin; LX2[3] = xmax; LX2[4] = ymin; LX2[5] = zmin;
523 LX3[0] = xmin; LX3[1] = ymax; LX3[2] = zmin; LX3[3] = xmax; LX3[4] = ymax; LX3[5] = zmin;
527 LY1[0] = xmax; LY1[1] = ymin; LY1[2] = zmin; LY1[3] = xmax; LY1[4] = ymax; LY1[5] = zmin;
529 LY2draw = 0; /* forbidden! */
530 LY2[0] = xmin; LY2[1] = ymin; LY2[2] = zmin; LY2[3] = xmin; LY2[4] = ymax; LY2[5] = zmin;
533 LY3[0] = xmin; LY3[1] = ymin; LY3[2] = zmax; LY3[3] = xmin; LY3[4] = ymax; LY3[5] = zmax;
537 LZ1[0] = xmax; LZ1[1] = ymin; LZ1[2] = zmin; LZ1[3] = xmax; LZ1[4] = ymin; LZ1[5] = zmax;
539 LZ2draw = 0; /* forbidden! */
540 LZ2[0] = xmin; LZ2[1] = ymin; LZ2[2] = zmin; LZ2[3] = xmin; LZ2[4] = ymin; LZ2[5] = zmax;
543 LZ3[0] = xmin; LZ3[1] = ymax; LZ3[2] = zmin; LZ3[3] = xmin; LZ3[4] = ymax; LZ3[5] = zmax;
551 LX1[0] = xmin; LX1[1] = ymin; LX1[2] = zmax; LX1[3] = xmax; LX1[4] = ymin; LX1[5] = zmax;
553 LX2draw = 0; /* forbidden! */
554 LX2[0] = xmin; LX2[1] = ymin; LX2[2] = zmin; LX2[3] = xmax; LX2[4] = ymin; LX2[5] = zmin;
557 LX3[0] = xmin; LX3[1] = ymax; LX3[2] = zmin; LX3[3] = xmax; LX3[4] = ymax; LX3[5] = zmin;
560 LY1draw = 0; /* forbidden! */
561 LY1[0] = xmin; LY1[1] = ymin; LY1[2] = zmin; LY1[3] = xmin; LY1[4] = ymax; LY1[5] = zmin;
564 LY2[0] = xmax; LY2[1] = ymin; LY2[2] = zmin; LY2[3] = xmax; LY2[4] = ymax; LY2[5] = zmin;
567 LY3[0] = xmax; LY3[1] = ymin; LY3[2] = zmax; LY3[3] = xmax; LY3[4] = ymax; LY3[5] = zmax;
570 LZ1draw = 0; /* forbidden! */
571 LZ1[0] = xmin; LZ1[1] = ymin; LZ1[2] = zmin; LZ1[3] = xmin; LZ1[4] = ymin; LZ1[5] = zmax;
574 LZ2[0] = xmax; LZ2[1] = ymin; LZ2[2] = zmin; LZ2[3] = xmax; LZ2[4] = ymin; LZ2[5] = zmax;
577 LZ3[0] = xmax; LZ3[1] = ymax; LZ3[2] = zmin; LZ3[3] = xmax; LZ3[4] = ymax; LZ3[5] = zmax;
584 LX1draw = 0; /* forbidden */
585 LX1[0] = xmin; LX1[1] = ymin; LX1[2] = zmin; LX1[3] = xmax; LX1[4] = ymin; LX1[5] = zmin;
588 LX2[0] = xmin; LX2[1] = ymax; LX2[2] = zmin; LX2[3] = xmax; LX2[4] = ymax; LX2[5] = zmin;
591 LX3[0] = xmin; LX3[1] = ymax; LX3[2] = zmax; LX3[3] = xmax; LX3[4] = ymax; LX3[5] = zmax;
595 LY1[0] = xmax; LY1[1] = ymin; LY1[2] = zmin; LY1[3] = xmax; LY1[4] = ymax; LY1[5] = zmin;
597 LY2draw = 0; /* forbidden */
598 LY2[0] = xmin; LY2[1] = ymin; LY2[2] = zmin; LY2[3] = xmin; LY2[4] = ymax; LY2[5] = zmin;
601 LY3[0] = xmin; LY3[1] = ymin; LY3[2] = zmax; LY3[3] = xmin; LY3[4] = ymax; LY3[5] = zmax;
605 LZ1[0] = xmax; LZ1[1] = ymax; LZ1[2] = zmin; LZ1[3] = xmax; LZ1[4] = ymax; LZ1[5] = zmax;
608 LZ2[0] = xmin; LZ2[1] = ymax; LZ2[2] = zmin; LZ2[3] = xmin; LZ2[4] = ymax; LZ2[5] = zmax;
610 LZ3draw = 0; /* forbidden */
611 LZ3[0] = xmin; LZ3[1] = ymin; LZ3[2] = zmin; LZ3[3] = xmin; LZ3[4] = ymin; LZ3[5] = zmax;
618 LX1draw = 0; /* forbidden */
619 LX1[0] = xmin; LX1[1] = ymin; LX1[2] = zmin; LX1[3] = xmax; LX1[4] = ymin; LX1[5] = zmin;
622 LX2[0] = xmin; LX2[1] = ymin; LX2[2] = zmax; LX2[3] = xmax; LX2[4] = ymin; LX2[5] = zmax;
625 LX3[0] = xmin; LX3[1] = ymax; LX3[2] = zmax; LX3[3] = xmax; LX3[4] = ymax; LX3[5] = zmax;
628 LY1draw = 0; /* forbidden */
629 LY1[0] = xmin; LY1[1] = ymin; LY1[2] = zmin; LY1[3] = xmin; LY1[4] = ymax; LY1[5] = zmin;
632 LY2[0] = xmin; LY2[1] = ymin; LY2[2] = zmax; LY2[3] = xmin; LY2[4] = ymax; LY2[5] = zmax;
635 LY3[0] = xmax; LY3[1] = ymin; LY3[2] = zmax; LY3[3] = xmax; LY3[4] = ymax; LY3[5] = zmax;
639 LZ1[0] = xmax; LZ1[1] = ymin; LZ1[2] = zmin; LZ1[3] = xmax; LZ1[4] = ymin; LZ1[5] = zmax;
641 LZ2draw = 0; /* forbidden */
642 LZ2[0] = xmin; LZ2[1] = ymin; LZ2[2] = zmin; LZ2[3] = xmin; LZ2[4] = ymin; LZ2[5] = zmax;
645 LZ3[0] = xmin; LZ3[1] = ymax; LZ3[2] = zmin; LZ3[3] = xmin; LZ3[4] = ymax; LZ3[5] = zmax;
652 LX1draw = 0; /* forbidden */
653 LX1[0] = xmin; LX1[1] = ymin; LX1[2] = zmin; LX1[3] = xmax; LX1[4] = ymin; LX1[5] = zmin;
656 LX2[0] = xmin; LX2[1] = ymax; LX2[2] = zmin; LX2[3] = xmax; LX2[4] = ymax; LX2[5] = zmin;
659 LX3[0] = xmin; LX3[1] = ymax; LX3[2] = zmax; LX3[3] = xmax; LX3[4] = ymax; LX3[5] = zmax;
662 LY1draw = 0; /* forbidden */
663 LY1[0] = xmin; LY1[1] = ymin; LY1[2] = zmin; LY1[3] = xmin; LY1[4] = ymax; LY1[5] = zmin;
666 LY2[0] = xmax; LY2[1] = ymin; LY2[2] = zmin; LY2[3] = xmax; LY2[4] = ymax; LY2[5] = zmin;
669 LY3[0] = xmax; LY3[1] = ymin; LY3[2] = zmax; LY3[3] = xmax; LY3[4] = ymax; LY3[5] = zmax;
673 LZ1[0] = xmax; LZ1[1] = ymin; LZ1[2] = zmin; LZ1[3] = xmax; LZ1[4] = ymin; LZ1[5] = zmax;
676 LZ2[0] = xmax; LZ2[1] = ymax; LZ2[2] = zmin; LZ2[3] = xmax; LZ2[4] = ymax; LZ2[5] = zmax;
679 LZ3[0] = xmin; LZ3[1] = ymax; LZ3[2] = zmin; LZ3[3] = xmin; LZ3[4] = ymax; LZ3[5] = zmax;
686 LX1draw = 0; /* forbidden */
687 LX1[0] = xmin; LX1[1] = ymin; LX1[2] = zmin; LX1[3] = xmax; LX1[4] = ymin; LX1[5] = zmin;
690 LX2[0] = xmin; LX2[1] = ymin; LX2[2] = zmax; LX2[3] = xmax; LX2[4] = ymin; LX2[5] = zmax;
693 LX3[0] = xmin; LX3[1] = ymax; LX3[2] = zmax; LX3[3] = xmax; LX3[4] = ymax; LX3[5] = zmax;
697 LY1[0] = xmax; LY1[1] = ymin; LY1[2] = zmin; LY1[3] = xmax; LY1[4] = ymax; LY1[5] = zmin;
700 LY2[0] = xmax; LY2[1] = ymin; LY2[2] = zmax; LY2[3] = xmax; LY2[4] = ymax; LY2[5] = zmax;
703 LY3[0] = xmin; LY3[1] = ymin; LY3[2] = zmax; LY3[3] = xmin; LY3[4] = ymax; LY3[5] = zmax;
706 LZ1draw = 0; /* forbidden */
707 LZ1[0] = xmin; LZ1[1] = ymin; LZ1[2] = zmin; LZ1[3] = xmin; LZ1[4] = ymin; LZ1[5] = zmax;
710 LZ2[0] = xmax; LZ2[1] = ymin; LZ2[2] = zmin; LZ2[3] = xmax; LZ2[4] = ymin; LZ2[5] = zmax;
713 LZ3[0] = xmax; LZ3[1] = ymax; LZ3[2] = zmin; LZ3[3] = xmax; LZ3[4] = ymax; LZ3[5] = zmax;
721 LX1[0] = xmin; LX1[1] = ymin; LX1[2] = zmax; LX1[3] = xmax; LX1[4] = ymin; LX1[5] = zmax;
724 LX2[0] = xmin; LX2[1] = ymax; LX2[2] = zmax; LX2[3] = xmax; LX2[4] = ymax; LX2[5] = zmax;
727 LX3[0] = xmin; LX3[1] = ymax; LX3[2] = zmin; LX3[3] = xmax; LX3[4] = ymax; LX3[5] = zmin;
730 LY1draw = 0; /* forbidden */
731 LY1[0] = xmin; LY1[1] = ymin; LY1[2] = zmin; LY1[3] = xmin; LY1[4] = ymax; LY1[5] = zmin;
734 LY2[0] = xmin; LY2[1] = ymin; LY2[2] = zmax; LY2[3] = xmin; LY2[4] = ymax; LY2[5] = zmax;
737 LY3[0] = xmax; LY3[1] = ymin; LY3[2] = zmax; LY3[3] = xmax; LY3[4] = ymax; LY3[5] = zmax;
740 LZ1draw = 0; /* forbidden */
741 LZ1[0] = xmin; LZ1[1] = ymin; LZ1[2] = zmin; LZ1[3] = xmin; LZ1[4] = ymin; LZ1[5] = zmax;
744 LZ2[0] = xmin; LZ2[1] = ymax; LZ2[2] = zmin; LZ2[3] = xmin; LZ2[4] = ymax; LZ2[5] = zmax;
747 LZ3[0] = xmax; LZ3[1] = ymax; LZ3[2] = zmin; LZ3[3] = xmax; LZ3[4] = ymax; LZ3[5] = zmax;
755 LX1[0] = xmin; LX1[1] = ymax; LX1[2] = zmin; LX1[3] = xmax; LX1[4] = ymax; LX1[5] = zmin;
758 LX2[0] = xmin; LX2[1] = ymax; LX2[2] = zmax; LX2[3] = xmax; LX2[4] = ymax; LX2[5] = zmax;
761 LX3[0] = xmin; LX3[1] = ymin; LX3[2] = zmax; LX3[3] = xmax; LX3[4] = ymin; LX3[5] = zmax;
765 LY1[0] = xmax; LY1[1] = ymin; LY1[2] = zmin; LY1[3] = xmax; LY1[4] = ymax; LY1[5] = zmin;
768 LY2[0] = xmax; LY2[1] = ymin; LY2[2] = zmax; LY2[3] = xmax; LY2[4] = ymax; LY2[5] = zmax;
771 LY3[0] = xmin; LY3[1] = ymin; LY3[2] = zmax; LY3[3] = xmin; LY3[4] = ymax; LY3[5] = zmax;
775 LZ1[0] = xmax; LZ1[1] = ymin; LZ1[2] = zmin; LZ1[3] = xmax; LZ1[4] = ymin; LZ1[5] = zmax;
778 LZ2[0] = xmax; LZ2[1] = ymax; LZ2[2] = zmin; LZ2[3] = xmax; LZ2[4] = ymax; LZ2[5] = zmax;
781 LZ3[0] = xmin; LZ3[1] = ymax; LZ3[2] = zmin; LZ3[3] = xmin; LZ3[4] = ymax; LZ3[5] = zmax;
787 /* Draw the graduated trihedron */
788 unsigned int i, j, offset;
790 float step, dx, dy, dz;
795 glColor3fv(data->gridcolor);
797 /* Boundary grid-lines */
800 glVertex3fv(&(LX1[0]));
801 glVertex3fv(&(LX1[3]));
805 glVertex3fv(&(LX2[0]));
806 glVertex3fv(&(LX2[3]));
810 glVertex3fv(&(LX3[0]));
811 glVertex3fv(&(LX3[3]));
815 glVertex3fv(&(LY1[0]));
816 glVertex3fv(&(LY1[3]));
820 glVertex3fv(&(LY2[0]));
821 glVertex3fv(&(LY2[3]));
825 glVertex3fv(&(LY3[0]));
826 glVertex3fv(&(LY3[3]));
830 glVertex3fv(&(LZ1[0]));
831 glVertex3fv(&(LZ1[3]));
835 glVertex3fv(&(LZ2[0]));
836 glVertex3fv(&(LZ2[3]));
840 glVertex3fv(&(LZ3[0]));
841 glVertex3fv(&(LZ3[3]));
845 /* Intermediate grid-lines */
849 i = data->drawaxes ? 1 : 0;
850 step = fabsf(LX1[3] - LX1[0]) / (float) data->nbx;
851 while (i < data->nbx)
853 glBegin(GL_LINE_STRIP);
854 glVertex3f(LX1[0] + i * step, LX1[1], LX1[2]);
855 glVertex3f(LX2[0] + i * step, LX2[1], LX2[2]);
856 glVertex3f(LX3[0] + i * step, LX3[1], LX3[2]);
864 i = data->drawaxes ? 1 : 0;
865 step = fabsf(LY1[4] - LY1[1]) / (float) data->nby;
866 while (i < data->nby)
868 glBegin(GL_LINE_STRIP);
869 glVertex3f(LY1[0], LY1[1] + i * step, LY1[2]);
870 glVertex3f(LY2[0], LY2[1] + i * step, LY2[2]);
871 glVertex3f(LY3[0], LY3[1] + i * step, LY3[2]);
879 i = data->drawaxes ? 1 : 0;
880 step = fabsf(LZ1[5] - LZ1[2]) / (float) data->nbz;
881 while (i < data->nbz)
883 glBegin(GL_LINE_STRIP);
884 glVertex3f(LZ1[0], LZ1[1], LZ1[2] + i * step);
885 glVertex3f(LZ2[0], LZ2[1], LZ2[2] + i * step);
886 glVertex3f(LZ3[0], LZ3[1], LZ3[2] + i * step);
897 glColor3fv(data->xcolor);
898 drawArrow(xmin, ymin, zmin, xmax, ymin, zmin, normal[0], normal[1], normal[2]);
901 glColor3fv(data->ycolor);
902 drawArrow(xmin, ymin, zmin, xmin, ymax, zmin, normal[0], normal[1], normal[2]);
905 glColor3fv(data->zcolor);
906 drawArrow(xmin, ymin, zmin, xmin, ymin, zmax, normal[0], normal[1], normal[2]);
909 /* Names of axes & values */
911 wchar_t wtextValue[128];
913 if (data->xdrawname || data->xdrawvalues)
915 /* Middle point of the first X-axis */
916 m1[0] = 0.5f * (LX1[0] + LX1[3]);
917 m1[1] = 0.5f * (LX1[1] + LX1[4]);
918 m1[2] = 0.5f * (LX1[2] + LX1[5]);
920 /* Middle point of the second X-axis */
921 m2[0] = 0.5f * (LX2[0] + LX2[3]);
922 m2[1] = 0.5f * (LX2[1] + LX2[4]);
923 m2[2] = 0.5f * (LX2[2] + LX2[5]);
925 /* Apply offset to m1 */
927 if (fabsf(dy) > 1.e-7f)
929 dy = (dy > 0.0f)? 1.0f : -1.0f;
932 if (fabsf(dz) > 1.e-7f)
934 dz = (dz > 0.0f)? 1.0f : -1.0f;
942 glColor3fv(data->xnamecolor);
943 offset = data->xaxisoffset + data->xtickmarklength;
944 drawText(data->xname, data->fontOfNames, data->styleOfNames, data->sizeOfNames,
945 m1[0], m1[1] + offset * m2[1], m1[2] + offset * m2[2]);
949 if (data->xdrawvalues && data->nbx > 0)
951 glColor3fv(data->xcolor);
954 step = fabsf(LX1[3] - LX1[0]) / (float) data->nbx;
955 offset = data->xoffset + data->xtickmarklength;
956 while (i <= data->nbx)
958 sprintf(textValue, "%g", LX1[0] + i * step);
959 j = 0; while (wtextValue[j] = textValue[j]) j++;
960 drawText(wtextValue, data->fontOfValues, data->styleOfValues, data->sizeOfValues,
961 LX1[0] + i * step, m1[1] + offset * m2[1], m1[2] + offset * m2[2]);
967 if (data->xdrawtickmarks && data->nbx > 0)
969 glColor3fv(data->gridcolor);
972 step = fabsf(LX1[3] - LX1[0]) / (float) data->nbx;
973 while (i <= data->nbx)
976 glVertex3f(LX1[0] + i * step, m1[1], m1[2]);
977 glVertex3f(LX1[0] + i * step, m1[1] + data->xtickmarklength * m2[1], m1[2] + data->xtickmarklength * m2[2]);
984 if (data->ydrawname || data->ydrawvalues)
986 /* Middle point of the first Y-axis */
987 m1[0] = 0.5f * (LY1[0] + LY1[3]);
988 m1[1] = 0.5f * (LY1[1] + LY1[4]);
989 m1[2] = 0.5f * (LY1[2] + LY1[5]);
991 /* Middle point of the second Y-axis */
992 m2[0] = 0.5f * (LY2[0] + LY2[3]);
993 m2[1] = 0.5f * (LY2[1] + LY2[4]);
994 m2[2] = 0.5f * (LY2[2] + LY2[5]);
996 /* Apply offset to m1 */
998 if (fabsf(dx) > 1.e-7f)
1000 dx = (dx > 0.0f)? 1.0f : -1.0f;
1003 if (fabsf(dz) > 1.e-7f)
1005 dz = (dz > 0.0f)? 1.0f : -1.0f;
1011 /* Name of Y-axis */
1012 if (data->ydrawname)
1014 glColor3fv(data->ynamecolor);
1015 offset = data->yaxisoffset + data->ytickmarklength;
1016 drawText(data->yname, data->fontOfNames, data->styleOfNames, data->sizeOfNames,
1017 m1[0] + offset * m2[0], m1[1], m1[2] + offset * m2[2]);
1021 if (data->ydrawvalues && data->nby > 0)
1023 glColor3fv(data->ycolor);
1026 step = fabsf(LY1[4] - LY1[1]) / (float) data->nby;
1027 offset = data->yoffset + data->ytickmarklength;
1028 while (i <= data->nby)
1030 sprintf(textValue, "%g", LY1[1] + i * step);
1031 j = 0; while (wtextValue[j] = textValue[j]) j++;
1032 drawText(wtextValue, data->fontOfValues, data->styleOfValues, data->sizeOfValues,
1033 m1[0] + offset * m2[0], LY1[1] + i * step, m1[2] + offset * m2[2]);
1039 if (data->ydrawtickmarks && data->nby > 0)
1041 glColor3fv(data->gridcolor);
1044 step = fabsf(LY1[4] - LY1[1]) / (float) data->nby;
1045 while (i <= data->nby)
1048 glVertex3f(m1[0], LY1[1] + i * step, m1[2]);
1049 glVertex3f(m1[0] + data->ytickmarklength * m2[0], LY1[1] + i * step, m1[2] + data->ytickmarklength * m2[2]);
1056 if (data->zdrawname || data->zdrawvalues)
1058 /* Middle point of the first Z-axis */
1059 m1[0] = 0.5f * (LZ1[0] + LZ1[3]);
1060 m1[1] = 0.5f * (LZ1[1] + LZ1[4]);
1061 m1[2] = 0.5f * (LZ1[2] + LZ1[5]);
1063 /* Middle point of the second Z-axis */
1064 m2[0] = 0.5f * (LZ2[0] + LZ2[3]);
1065 m2[1] = 0.5f * (LZ2[1] + LZ2[4]);
1066 m2[2] = 0.5f * (LZ2[2] + LZ2[5]);
1068 /* Apply offset to m1 */
1070 if (fabsf(dx) > 1.e-7f)
1072 dx = (dx > 0.0f)? 1.0f : -1.0f;
1075 if (fabsf(dy) > 1.e-7f)
1077 dy = (dy > 0.0f)? 1.0f : -1.0f;
1083 /* Name of Z-axis */
1084 if (data->zdrawname)
1086 glColor3fv(data->znamecolor);
1087 offset = data->zaxisoffset + data->ztickmarklength;
1088 drawText(data->zname, data->fontOfNames, data->styleOfNames, data->sizeOfNames,
1089 m1[0] + offset * m2[0], m1[1] + offset * m2[1], m1[2]);
1093 if (data->zdrawvalues && data->nbz > 0)
1095 glColor3fv(data->zcolor);
1098 step = fabsf(LZ1[5] - LZ1[2]) / (float) data->nbz;
1099 offset = data->zoffset + data->ztickmarklength;
1100 while (i <= data->nbz)
1102 sprintf(textValue, "%g", LZ1[2] + i * step);
1103 j = 0; while (wtextValue[j] = textValue[j]) j++;
1104 drawText(wtextValue, data->fontOfValues, data->styleOfValues, data->sizeOfValues,
1105 m1[0] + offset * m2[0], m1[1] + offset * m2[1], LZ1[2] + i * step);
1111 if (data->zdrawtickmarks && data->nbz > 0)
1113 glColor3fv(data->gridcolor);
1116 step = fabsf(LZ1[5] - LZ1[2]) / (float) data->nbz;
1117 while (i <= data->nbz)
1120 glVertex3f(m1[0], m1[1], LZ1[2] + i * step);
1121 glVertex3f(m1[0] + data->ztickmarklength * m2[0], m1[1] + data->ztickmarklength * m2[1], LZ1[2] + i * step);
1128 /* Activate the lighting if it was turned off by this method call */
1130 glEnable(GL_LIGHTING);
1135 TStatus call_graduatedtrihedron_minmaxvalues(const float xMin,