1 #include <OpenGl_tgl_all.hxx>
2 #include <OpenGl_graduatedtrihedron.hxx>
12 #include <InterfaceGraphic_Graphic3d.hxx>
13 #include <InterfaceGraphic_Aspect.hxx>
14 #include <InterfaceGraphic_Visual3d.hxx>
16 #include <OpenGl_tgl_funcs.hxx>
17 #include <OpenGl_tgl_subrs.hxx>
18 #include <OpenGl_TextRender.hxx>
27 /* Graduated trihedron data */
28 static int nbWsIds = 0; /* Number of the views (size of the arrays below */
29 static int* WsIds = 0; /* The array contans indices of graduated trihedron data corresponding to the view ID */
30 static CALL_DEF_GRADUATEDTRIHEDRON** graduatedTrihedronData = 0; /* The array contains graduated trihedron data of all views */
33 float xmin = 0.0f, ymin = 0.0f, zmin = 0.0f, xmax = 100.0f, ymax = 100.0f, zmax = 100.0f;
35 static void copyData(CALL_DEF_GRADUATEDTRIHEDRON* fromData, CALL_DEF_GRADUATEDTRIHEDRON* toData)
42 len = strlen(fromData->xname) + 1;
45 toData->xname = (char*) malloc(len * sizeof(char));
47 strcpy(toData->xname, fromData->xname);
49 toData->xname[0] = '\0';
52 len = strlen(fromData->yname) + 1;
55 toData->yname = (char*) malloc(len * sizeof(char));
57 strcpy(toData->yname, fromData->yname);
59 toData->yname[0] = '\0';
62 len = strlen(fromData->zname) + 1;
65 toData->zname = (char*) malloc(len * sizeof(char));
67 strcpy(toData->zname, fromData->zname);
69 toData->zname[0] = '\0';
71 toData->xdrawname = fromData->xdrawname;
72 toData->ydrawname = fromData->ydrawname;
73 toData->zdrawname = fromData->zdrawname;
75 toData->xdrawvalues = fromData->xdrawvalues;
76 toData->ydrawvalues = fromData->ydrawvalues;
77 toData->zdrawvalues = fromData->zdrawvalues;
79 toData->drawgrid = fromData->drawgrid;
81 toData->drawaxes = fromData->drawaxes;
82 /* Number of splits along axes */
83 toData->nbx = fromData->nbx;
84 toData->nby = fromData->nby;
85 toData->nbz = fromData->nbz;
86 /* Offset for drawing values */
87 toData->xoffset = fromData->xoffset;
88 toData->yoffset = fromData->yoffset;
89 toData->zoffset = fromData->zoffset;
90 /* Offset for drawing names of axes */
91 toData->xaxisoffset = fromData->xaxisoffset;
92 toData->yaxisoffset = fromData->yaxisoffset;
93 toData->zaxisoffset = fromData->zaxisoffset;
95 toData->xdrawtickmarks = fromData->xdrawtickmarks;
96 toData->ydrawtickmarks = fromData->ydrawtickmarks;
97 toData->zdrawtickmarks = fromData->zdrawtickmarks;
98 /* Length of tickmarks */
99 toData->xtickmarklength = fromData->xtickmarklength;
100 toData->ytickmarklength = fromData->ytickmarklength;
101 toData->ztickmarklength = fromData->ztickmarklength;
103 memcpy(toData->gridcolor, fromData->gridcolor, 3 * sizeof(float));
105 memcpy(toData->xnamecolor, fromData->xnamecolor, 3 * sizeof(float));
107 memcpy(toData->ynamecolor, fromData->ynamecolor, 3 * sizeof(float));
109 memcpy(toData->znamecolor, fromData->znamecolor, 3 * sizeof(float));
110 /* X color of axis and values */
111 memcpy(toData->xcolor, fromData->xcolor, 3 * sizeof(float));
112 /* Y color of axis and values */
113 memcpy(toData->ycolor, fromData->ycolor, 3 * sizeof(float));
114 /* Z color of axis and values */
115 memcpy(toData->zcolor, fromData->zcolor, 3 * sizeof(float));
116 /* Font name of names of axes: Courier, Arial, ... */
117 if (fromData->fontOfNames)
118 len = strlen(fromData->fontOfNames) + 1;
121 toData->fontOfNames = (char*) malloc(len * sizeof(char));
122 if (fromData->fontOfNames)
123 strcpy(toData->fontOfNames, fromData->fontOfNames);
125 toData->fontOfNames[0] = '\0';
126 /* Style of names of axes: OSD_FA_Regular, OSD_FA_Bold, ... */
127 toData->styleOfNames = fromData->styleOfNames;
128 /* Size of names of axes: 8, 10, 12, 14, ... */
129 toData->sizeOfNames = fromData->sizeOfNames;
130 /* Font name of values: Courier, Arial, ... */
131 if (fromData->fontOfValues)
132 len = strlen(fromData->fontOfValues) + 1;
135 toData->fontOfValues = (char*) malloc(len * sizeof(char));
136 if (fromData->fontOfValues)
137 strcpy(toData->fontOfValues, fromData->fontOfValues);
139 toData->fontOfValues[0] = '\0';
140 /* Style of values: OSD_FA_Regular, OSD_FA_Bold, ... */
141 toData->styleOfValues = fromData->styleOfValues;
142 /* Size of values: 8, 10, 12, 14, ... */
143 toData->sizeOfValues = fromData->sizeOfValues;
144 /* Callback - updater of boundary box */
145 toData->cbCubicAxes = fromData->cbCubicAxes;
146 toData->ptrVisual3dView = fromData->ptrVisual3dView;
149 static void freeGraduatedTrihedronData(CALL_DEF_GRADUATEDTRIHEDRON* data)
160 if (data->fontOfNames)
161 free(data->fontOfNames);
162 if (data->fontOfValues)
163 free(data->fontOfValues);
168 static void freeData()
175 for (i = 0; i < nbWsIds; i++)
177 freeGraduatedTrihedronData(graduatedTrihedronData[i]);
179 free(graduatedTrihedronData);
182 graduatedTrihedronData = 0;
186 static int getGraduatedTrihedronDataIndex(int WsId)
193 for (; i < nbWsIds; i++)
195 if (WsIds[i] == WsId)
202 static unsigned char initView(int WsId)
206 CALL_DEF_GRADUATEDTRIHEDRON** newGraduatedTrihedronData;
208 /* Extend arrays for +1 */
210 newWsIds = (int*) calloc(nbWsIds, sizeof(int));
211 newGraduatedTrihedronData = (CALL_DEF_GRADUATEDTRIHEDRON**) calloc(nbWsIds, sizeof(CALL_DEF_GRADUATEDTRIHEDRON*));
212 for (i = 0; i < nbWsIds; i++)
214 newGraduatedTrihedronData[i] = (CALL_DEF_GRADUATEDTRIHEDRON*) calloc(1, sizeof(CALL_DEF_GRADUATEDTRIHEDRON));
217 /* Copy data from current arrays to the newly created */
220 for (i = 0; i < nbWsIds - 1; i++)
222 newWsIds[i] = WsIds[i];
223 copyData(graduatedTrihedronData[i], newGraduatedTrihedronData[i]);
227 /* Delete the previous used arrays */
228 nbWsIds--; /* Don't delete just created graduated trihedron data */
230 nbWsIds++; /* Return the counter back */
232 /* Switch to new arrays */
234 graduatedTrihedronData = newGraduatedTrihedronData;
237 WsIds[nbWsIds - 1] = WsId;
242 /* Erases the trihedron from the view */
243 static TStatus removeView(int WsId)
247 CALL_DEF_GRADUATEDTRIHEDRON** newGraduatedTrihedronData;
249 index = getGraduatedTrihedronDataIndex(WsId);
251 return TSuccess; /* Nothing to remove */
253 /* If trihedron is displayed only in one view,
254 just free the arrays and set nbWsIds equal to 0. */
262 /* create new arrays with nbWsIds - 1 length. */
264 newWsIds = (int*) calloc(nbWsIds, sizeof(int));
265 newGraduatedTrihedronData = (CALL_DEF_GRADUATEDTRIHEDRON**) calloc(nbWsIds, sizeof(CALL_DEF_GRADUATEDTRIHEDRON*));
266 for (i = 0; i < nbWsIds; i++)
268 newGraduatedTrihedronData[i] = (CALL_DEF_GRADUATEDTRIHEDRON*) calloc(1, sizeof(CALL_DEF_GRADUATEDTRIHEDRON));
271 /* Copy data from current arrays to the newly created */
272 for (i = 0, j = 0; j <= nbWsIds; j++)
276 newWsIds[i] = WsIds[j];
277 copyData(graduatedTrihedronData[j], newGraduatedTrihedronData[i]);
285 /* Normal of the view (not normalized!) */
286 static float getNormal(float* normal)
289 GLdouble model_matrix[16], proj_matrix[16];
290 double x1, y1, z1, x2, y2, z2, x3, y3, z3;
291 double dx1, dy1, dz1, dx2, dy2, dz2, width;
293 glGetDoublev(GL_MODELVIEW_MATRIX, model_matrix);
294 glGetDoublev(GL_PROJECTION_MATRIX, proj_matrix);
295 glGetIntegerv(GL_VIEWPORT, viewport);
297 gluUnProject(viewport[0], viewport[1], 0., model_matrix, proj_matrix, viewport, &x1, &y1, &z1);
298 gluUnProject(viewport[0] + viewport[2], viewport[1], 0., model_matrix, proj_matrix, viewport, &x2, &y2, &z2);
299 gluUnProject(viewport[0], viewport[1] + viewport[3], 0., model_matrix, proj_matrix, viewport, &x3, &y3, &z3);
301 /* Normal out of user is p1p3^p1p2 */
302 dx1 = x3 - x1; dy1 = y3 - y1; dz1 = z3 - z1;
303 dx2 = x2 - x1; dy2 = y2 - y1; dz2 = z2 - z1;
304 normal[0] = (float) (dy1 * dz2 - dz1 * dy2);
305 normal[1] = (float) (dz1 * dx2 - dx1 * dz2);
306 normal[2] = (float) (dx1 * dy2 - dy1 * dx2);
308 /* Distance corresponding to 1 pixel */
309 width = sqrt(dx2 * dx2 + dy2 * dy2 + dz2 * dz2);
310 return (float) width / (float) viewport[2];
313 static float getDistance2Corner(float* normal, float* center, float x, float y, float z)
315 return normal[0] * (x - center[0]) + normal[1] * (y - center[1]) + normal[2] * (z - center[2]);
318 static char getFarestCorner(float d000, float d100, float d010, float d001,
319 float d110, float d101, float d011, float d111)
322 d000 > d100 && d000 > d010 && d000 > d001 && d000 > d110 &&
323 d000 > d101 && d000 > d011 && d000 > d111)
327 else if (d100 > 0.0f &&
328 d100 > d000 && d100 > d010 && d100 > d001 && d100 > d110 &&
329 d100 > d101 && d100 > d011 && d100 > d111)
333 else if (d010 > 0.0f &&
334 d010 > d000 && d010 > d100 && d010 > d001 && d010 > d110 &&
335 d010 > d101 && d010 > d011 && d010 > d111)
339 else if (d001 > 0.0f &&
340 d001 > d000 && d001 > d100 && d001 > d010 && d001 > d110 &&
341 d001 > d101 && d001 > d011 && d001 > d111)
345 else if (d110 > 0.0f &&
346 d110 > d000 && d110 > d100 && d110 > d010 && d110 > d001 &&
347 d110 > d101 && d110 > d011 && d110 > d111)
351 else if (d101 > 0.0f &&
352 d101 > d000 && d101 > d100 && d101 > d010 && d101 > d001 &&
353 d101 > d110 && d101 > d011 && d101 > d111)
357 else if (d011 > 0.0f &&
358 d011 > d000 && d011 > d100 && d011 > d010 && d011 > d001 &&
359 d011 > d110 && d011 > d101 && d011 > d111)
366 static void drawText(char* text, char* font, OSD_FontAspect style, int size, float x, float y, float z)
369 OpenGl_TextRender* textRenderer = OpenGl_TextRender::instance();
370 fontBase = textRenderer->FindFont((Tchar*) font, style, (float) size);
371 textRenderer->RenderText(text, fontBase, 0, x, y, z);
373 /* 4 OCC 6.3.1 and older:
377 fontBase = tXfmsetfont (1.0F, 1.0F);
379 fontBase = WNTSetFont (1.0F, 1.0F);
383 tXfmprstr(text, fontBase, x, y, z);
385 WNTPuts(text, fontBase, 0, x, y, z);
390 static void drawArrow(float x1, float y1, float z1,
391 float x2, float y2, float z2,
392 float xn, float yn, float zn)
398 float xa1, ya1, za1, xa2, ya2, za2;
400 /* Start of arrow: at 10% from the end */
401 x0 = x1 + 0.9f * (x2 - x1); y0 = y1 + 0.9f * (y2 - y1); z0 = z1 + 0.9f * (z2 - z1);
403 /* Base of the arrow */
404 xa = (x2 - x0); ya = (y2 - y0); za = (z2 - z0);
406 /* Height of the arrow */
407 h = sqrtf(xa * xa + ya * ya + za * za);
410 xa = xa / h; ya = ya / h; za = za / h;
412 /* Radial direction to the arrow */
413 xr = ya * zn - za * yn;
414 yr = za * xn - xa * zn;
415 zr = xa * yn - ya * xn;
417 /* Normalize the radial vector */
418 r = sqrtf(xr * xr + yr * yr + zr * zr);
421 xr = xr / r; yr = yr / r; zr = zr / r;
423 /* First point of the base of the arrow */
425 xr = r * xr; yr = r * yr; zr = r * zr;
426 xa1 = x0 + xr; ya1 = y0 + yr; za1 = z0 + zr;
428 /* Second point of the base of the arrow */
429 xa2 = x0 - xr; ya2 = y0 - yr; za2 = z0 - zr;
431 /* Draw a line to the arrow */
433 glVertex3f(x1, y1, z1);
434 glVertex3f(x0, y0, z0);
437 /* Draw a triangle of the arrow */
438 glBegin(GL_LINE_LOOP);
439 glVertex3f(xa1, ya1, za1);
440 glVertex3f(xa2, ya2, za2);
441 glVertex3f(x2, y2, z2);
445 TStatus call_graduatedtrihedron_get(int WsId, CALL_DEF_GRADUATEDTRIHEDRON* data)
449 /* Get index of the view */
450 index = getGraduatedTrihedronDataIndex(WsId);
460 data->xdrawvalues = 1;
461 data->ydrawvalues = 1;
462 data->zdrawvalues = 1;
471 data->xaxisoffset = 30;
472 data->yaxisoffset = 30;
473 data->zaxisoffset = 30;
474 data->xdrawtickmarks = 1;
475 data->ydrawtickmarks = 1;
476 data->zdrawtickmarks = 1;
477 data->xtickmarklength = 10;
478 data->ytickmarklength = 10;
479 data->ztickmarklength = 10;
480 /*Quantity_NOC_WHITE*/;
481 data->gridcolor[0] = 1.0f;
482 data->gridcolor[1] = 1.0f;
483 data->gridcolor[2] = 1.0f;
484 /* Quantity_NOC_RED */
485 data->xnamecolor[0] = 1.0f;
486 data->xnamecolor[1] = 0.0f;
487 data->xnamecolor[2] = 0.0f;
488 /* Quantity_NOC_GREEN */
489 data->ynamecolor[0] = 0.0f;
490 data->ynamecolor[1] = 1.0f;
491 data->ynamecolor[2] = 0.0f;
492 /* Quantity_NOC_BLUE1 */
493 data->znamecolor[0] = 0.0f;
494 data->znamecolor[1] = 0.0f;
495 data->znamecolor[2] = 1.0f;
496 /* Quantity_NOC_RED */
497 data->xcolor[0] = 1.0f;
498 data->xcolor[1] = 0.0f;
499 data->xcolor[2] = 0.0f;
500 /* Quantity_NOC_GREEN */
501 data->ycolor[0] = 0.0f;
502 data->ycolor[1] = 1.0f;
503 data->ycolor[2] = 0.0f;
504 /* Quantity_NOC_BLUE1 */
505 data->zcolor[0] = 0.0f;
506 data->zcolor[1] = 0.0f;
507 data->zcolor[2] = 1.0f;
511 copyData(graduatedTrihedronData[index], data);
516 TStatus call_graduatedtrihedron_display(int WsId, CALL_DEF_GRADUATEDTRIHEDRON* data)
520 /* Initialize data for a new view */
521 index = getGraduatedTrihedronDataIndex(WsId);
525 index = getGraduatedTrihedronDataIndex(WsId);
527 copyData(data, graduatedTrihedronData[index]);
528 return call_graduatedtrihedron_redraw(WsId);
531 TStatus call_graduatedtrihedron_erase(int WsId)
533 return removeView(WsId);
536 TStatus call_graduatedtrihedron_redraw(int WsId)
539 unsigned int i, offset;
540 unsigned char farestCorner;
541 float normal[3], center[3];
542 CALL_DEF_GRADUATEDTRIHEDRON* data;
543 float d000, d100, d010, d001, d110, d101, d011, d111; /* 0 - min, 1 - max */
544 float LX1[6], LX2[6], LX3[6]; /* Lines along X direction */
545 float LY1[6], LY2[6], LY3[6]; /* Lines along Y direction */
546 float LZ1[6], LZ2[6], LZ3[6]; /* Lines along Z direction */
547 unsigned char LX1draw, LX2draw, LX3draw; /* Allows drawing of X-line (000 - 100 is forbidden) */
548 unsigned char LY1draw, LY2draw, LY3draw; /* Allows drawing of Y-line (000 - 010 is forbidden) */
549 unsigned char LZ1draw, LZ2draw, LZ3draw; /* Allows drawing of Z-line (000 - 001 is forbidden) */
551 float step, d, dpix, dx, dy, dz;
555 /* Get index of the trihedron data */
556 index = getGraduatedTrihedronDataIndex(WsId);
559 data = graduatedTrihedronData[index];
561 /* Update boundary box */
562 if (data->cbCubicAxes)
563 data->cbCubicAxes(data->ptrVisual3dView);
565 /* Disable lighting for lines */
566 light = glIsEnabled(GL_LIGHTING);
568 glDisable(GL_LIGHTING);
570 /* Find the farest point of bounding box */
572 /* Get normal of the view out of user. */
573 /* Also, the method return distance corresponding to 1 pixel */
574 dpix = getNormal(normal);
576 /* Normalize normal */
577 d = sqrtf(normal[0] * normal[0] + normal[1] * normal[1] + normal[2] * normal[2]);
578 normal[0] = normal[0] / d;
579 normal[1] = normal[1] / d;
580 normal[2] = normal[2] / d;
582 /* Get central point of bounding box */
583 center[0] = 0.5f * (xmin + xmax);
584 center[1] = 0.5f * (ymin + ymax);
585 center[2] = 0.5f * (zmin + zmax);
587 /* Check distance to corners of bounding box along the normal*/
588 d000 = getDistance2Corner(normal, center, xmin, ymin, zmin);
589 d100 = getDistance2Corner(normal, center, xmax, ymin, zmin);
590 d010 = getDistance2Corner(normal, center, xmin, ymax, zmin);
591 d001 = getDistance2Corner(normal, center, xmin, ymin, zmax);
592 d110 = getDistance2Corner(normal, center, xmax, ymax, zmin);
593 d101 = getDistance2Corner(normal, center, xmax, ymin, zmax);
594 d011 = getDistance2Corner(normal, center, xmin, ymax, zmax);
595 d111 = getDistance2Corner(normal, center, xmax, ymax, zmax);
596 farestCorner = getFarestCorner(d000, d100, d010, d001, d110, d101, d011, d111);
598 /* Choose axes for the grid. */
599 /* The first axis will be used for drawing the text and the values. */
600 switch (farestCorner)
606 LX1[0] = xmin; LX1[1] = ymin; LX1[2] = zmax; LX1[3] = xmax; LX1[4] = ymin; LX1[5] = zmax;
608 LX2draw = 0; /* forbidden! */
609 LX2[0] = xmin; LX2[1] = ymin; LX2[2] = zmin; LX2[3] = xmax; LX2[4] = ymin; LX2[5] = zmin;
612 LX3[0] = xmin; LX3[1] = ymax; LX3[2] = zmin; LX3[3] = xmax; LX3[4] = ymax; LX3[5] = zmin;
616 LY1[0] = xmax; LY1[1] = ymin; LY1[2] = zmin; LY1[3] = xmax; LY1[4] = ymax; LY1[5] = zmin;
618 LY2draw = 0; /* forbidden! */
619 LY2[0] = xmin; LY2[1] = ymin; LY2[2] = zmin; LY2[3] = xmin; LY2[4] = ymax; LY2[5] = zmin;
622 LY3[0] = xmin; LY3[1] = ymin; LY3[2] = zmax; LY3[3] = xmin; LY3[4] = ymax; LY3[5] = zmax;
626 LZ1[0] = xmax; LZ1[1] = ymin; LZ1[2] = zmin; LZ1[3] = xmax; LZ1[4] = ymin; LZ1[5] = zmax;
628 LZ2draw = 0; /* forbidden! */
629 LZ2[0] = xmin; LZ2[1] = ymin; LZ2[2] = zmin; LZ2[3] = xmin; LZ2[4] = ymin; LZ2[5] = zmax;
632 LZ3[0] = xmin; LZ3[1] = ymax; LZ3[2] = zmin; LZ3[3] = xmin; LZ3[4] = ymax; LZ3[5] = zmax;
640 LX1[0] = xmin; LX1[1] = ymin; LX1[2] = zmax; LX1[3] = xmax; LX1[4] = ymin; LX1[5] = zmax;
642 LX2draw = 0; /* forbidden! */
643 LX2[0] = xmin; LX2[1] = ymin; LX2[2] = zmin; LX2[3] = xmax; LX2[4] = ymin; LX2[5] = zmin;
646 LX3[0] = xmin; LX3[1] = ymax; LX3[2] = zmin; LX3[3] = xmax; LX3[4] = ymax; LX3[5] = zmin;
649 LY1draw = 0; /* forbidden! */
650 LY1[0] = xmin; LY1[1] = ymin; LY1[2] = zmin; LY1[3] = xmin; LY1[4] = ymax; LY1[5] = zmin;
653 LY2[0] = xmax; LY2[1] = ymin; LY2[2] = zmin; LY2[3] = xmax; LY2[4] = ymax; LY2[5] = zmin;
656 LY3[0] = xmax; LY3[1] = ymin; LY3[2] = zmax; LY3[3] = xmax; LY3[4] = ymax; LY3[5] = zmax;
659 LZ1draw = 0; /* forbidden! */
660 LZ1[0] = xmin; LZ1[1] = ymin; LZ1[2] = zmin; LZ1[3] = xmin; LZ1[4] = ymin; LZ1[5] = zmax;
663 LZ2[0] = xmax; LZ2[1] = ymin; LZ2[2] = zmin; LZ2[3] = xmax; LZ2[4] = ymin; LZ2[5] = zmax;
666 LZ3[0] = xmax; LZ3[1] = ymax; LZ3[2] = zmin; LZ3[3] = xmax; LZ3[4] = ymax; LZ3[5] = zmax;
673 LX1draw = 0; /* forbidden */
674 LX1[0] = xmin; LX1[1] = ymin; LX1[2] = zmin; LX1[3] = xmax; LX1[4] = ymin; LX1[5] = zmin;
677 LX2[0] = xmin; LX2[1] = ymax; LX2[2] = zmin; LX2[3] = xmax; LX2[4] = ymax; LX2[5] = zmin;
680 LX3[0] = xmin; LX3[1] = ymax; LX3[2] = zmax; LX3[3] = xmax; LX3[4] = ymax; LX3[5] = zmax;
684 LY1[0] = xmax; LY1[1] = ymin; LY1[2] = zmin; LY1[3] = xmax; LY1[4] = ymax; LY1[5] = zmin;
686 LY2draw = 0; /* forbidden */
687 LY2[0] = xmin; LY2[1] = ymin; LY2[2] = zmin; LY2[3] = xmin; LY2[4] = ymax; LY2[5] = zmin;
690 LY3[0] = xmin; LY3[1] = ymin; LY3[2] = zmax; LY3[3] = xmin; LY3[4] = ymax; LY3[5] = zmax;
694 LZ1[0] = xmax; LZ1[1] = ymax; LZ1[2] = zmin; LZ1[3] = xmax; LZ1[4] = ymax; LZ1[5] = zmax;
697 LZ2[0] = xmin; LZ2[1] = ymax; LZ2[2] = zmin; LZ2[3] = xmin; LZ2[4] = ymax; LZ2[5] = zmax;
699 LZ3draw = 0; /* forbidden */
700 LZ3[0] = xmin; LZ3[1] = ymin; LZ3[2] = zmin; LZ3[3] = xmin; LZ3[4] = ymin; LZ3[5] = zmax;
707 LX1draw = 0; /* forbidden */
708 LX1[0] = xmin; LX1[1] = ymin; LX1[2] = zmin; LX1[3] = xmax; LX1[4] = ymin; LX1[5] = zmin;
711 LX2[0] = xmin; LX2[1] = ymin; LX2[2] = zmax; LX2[3] = xmax; LX2[4] = ymin; LX2[5] = zmax;
714 LX3[0] = xmin; LX3[1] = ymax; LX3[2] = zmax; LX3[3] = xmax; LX3[4] = ymax; LX3[5] = zmax;
717 LY1draw = 0; /* forbidden */
718 LY1[0] = xmin; LY1[1] = ymin; LY1[2] = zmin; LY1[3] = xmin; LY1[4] = ymax; LY1[5] = zmin;
721 LY2[0] = xmin; LY2[1] = ymin; LY2[2] = zmax; LY2[3] = xmin; LY2[4] = ymax; LY2[5] = zmax;
724 LY3[0] = xmax; LY3[1] = ymin; LY3[2] = zmax; LY3[3] = xmax; LY3[4] = ymax; LY3[5] = zmax;
728 LZ1[0] = xmax; LZ1[1] = ymin; LZ1[2] = zmin; LZ1[3] = xmax; LZ1[4] = ymin; LZ1[5] = zmax;
730 LZ2draw = 0; /* forbidden */
731 LZ2[0] = xmin; LZ2[1] = ymin; LZ2[2] = zmin; LZ2[3] = xmin; LZ2[4] = ymin; LZ2[5] = zmax;
734 LZ3[0] = xmin; LZ3[1] = ymax; LZ3[2] = zmin; LZ3[3] = xmin; LZ3[4] = ymax; LZ3[5] = zmax;
741 LX1draw = 0; /* forbidden */
742 LX1[0] = xmin; LX1[1] = ymin; LX1[2] = zmin; LX1[3] = xmax; LX1[4] = ymin; LX1[5] = zmin;
745 LX2[0] = xmin; LX2[1] = ymax; LX2[2] = zmin; LX2[3] = xmax; LX2[4] = ymax; LX2[5] = zmin;
748 LX3[0] = xmin; LX3[1] = ymax; LX3[2] = zmax; LX3[3] = xmax; LX3[4] = ymax; LX3[5] = zmax;
751 LY1draw = 0; /* forbidden */
752 LY1[0] = xmin; LY1[1] = ymin; LY1[2] = zmin; LY1[3] = xmin; LY1[4] = ymax; LY1[5] = zmin;
755 LY2[0] = xmax; LY2[1] = ymin; LY2[2] = zmin; LY2[3] = xmax; LY2[4] = ymax; LY2[5] = zmin;
758 LY3[0] = xmax; LY3[1] = ymin; LY3[2] = zmax; LY3[3] = xmax; LY3[4] = ymax; LY3[5] = zmax;
762 LZ1[0] = xmax; LZ1[1] = ymin; LZ1[2] = zmin; LZ1[3] = xmax; LZ1[4] = ymin; LZ1[5] = zmax;
765 LZ2[0] = xmax; LZ2[1] = ymax; LZ2[2] = zmin; LZ2[3] = xmax; LZ2[4] = ymax; LZ2[5] = zmax;
768 LZ3[0] = xmin; LZ3[1] = ymax; LZ3[2] = zmin; LZ3[3] = xmin; LZ3[4] = ymax; LZ3[5] = zmax;
775 LX1draw = 0; /* forbidden */
776 LX1[0] = xmin; LX1[1] = ymin; LX1[2] = zmin; LX1[3] = xmax; LX1[4] = ymin; LX1[5] = zmin;
779 LX2[0] = xmin; LX2[1] = ymin; LX2[2] = zmax; LX2[3] = xmax; LX2[4] = ymin; LX2[5] = zmax;
782 LX3[0] = xmin; LX3[1] = ymax; LX3[2] = zmax; LX3[3] = xmax; LX3[4] = ymax; LX3[5] = zmax;
786 LY1[0] = xmax; LY1[1] = ymin; LY1[2] = zmin; LY1[3] = xmax; LY1[4] = ymax; LY1[5] = zmin;
789 LY2[0] = xmax; LY2[1] = ymin; LY2[2] = zmax; LY2[3] = xmax; LY2[4] = ymax; LY2[5] = zmax;
792 LY3[0] = xmin; LY3[1] = ymin; LY3[2] = zmax; LY3[3] = xmin; LY3[4] = ymax; LY3[5] = zmax;
795 LZ1draw = 0; /* forbidden */
796 LZ1[0] = xmin; LZ1[1] = ymin; LZ1[2] = zmin; LZ1[3] = xmin; LZ1[4] = ymin; LZ1[5] = zmax;
799 LZ2[0] = xmax; LZ2[1] = ymin; LZ2[2] = zmin; LZ2[3] = xmax; LZ2[4] = ymin; LZ2[5] = zmax;
802 LZ3[0] = xmax; LZ3[1] = ymax; LZ3[2] = zmin; LZ3[3] = xmax; LZ3[4] = ymax; LZ3[5] = zmax;
810 LX1[0] = xmin; LX1[1] = ymin; LX1[2] = zmax; LX1[3] = xmax; LX1[4] = ymin; LX1[5] = zmax;
813 LX2[0] = xmin; LX2[1] = ymax; LX2[2] = zmax; LX2[3] = xmax; LX2[4] = ymax; LX2[5] = zmax;
816 LX3[0] = xmin; LX3[1] = ymax; LX3[2] = zmin; LX3[3] = xmax; LX3[4] = ymax; LX3[5] = zmin;
819 LY1draw = 0; /* forbidden */
820 LY1[0] = xmin; LY1[1] = ymin; LY1[2] = zmin; LY1[3] = xmin; LY1[4] = ymax; LY1[5] = zmin;
823 LY2[0] = xmin; LY2[1] = ymin; LY2[2] = zmax; LY2[3] = xmin; LY2[4] = ymax; LY2[5] = zmax;
826 LY3[0] = xmax; LY3[1] = ymin; LY3[2] = zmax; LY3[3] = xmax; LY3[4] = ymax; LY3[5] = zmax;
829 LZ1draw = 0; /* forbidden */
830 LZ1[0] = xmin; LZ1[1] = ymin; LZ1[2] = zmin; LZ1[3] = xmin; LZ1[4] = ymin; LZ1[5] = zmax;
833 LZ2[0] = xmin; LZ2[1] = ymax; LZ2[2] = zmin; LZ2[3] = xmin; LZ2[4] = ymax; LZ2[5] = zmax;
836 LZ3[0] = xmax; LZ3[1] = ymax; LZ3[2] = zmin; LZ3[3] = xmax; LZ3[4] = ymax; LZ3[5] = zmax;
844 LX1[0] = xmin; LX1[1] = ymax; LX1[2] = zmin; LX1[3] = xmax; LX1[4] = ymax; LX1[5] = zmin;
847 LX2[0] = xmin; LX2[1] = ymax; LX2[2] = zmax; LX2[3] = xmax; LX2[4] = ymax; LX2[5] = zmax;
850 LX3[0] = xmin; LX3[1] = ymin; LX3[2] = zmax; LX3[3] = xmax; LX3[4] = ymin; LX3[5] = zmax;
854 LY1[0] = xmax; LY1[1] = ymin; LY1[2] = zmin; LY1[3] = xmax; LY1[4] = ymax; LY1[5] = zmin;
857 LY2[0] = xmax; LY2[1] = ymin; LY2[2] = zmax; LY2[3] = xmax; LY2[4] = ymax; LY2[5] = zmax;
860 LY3[0] = xmin; LY3[1] = ymin; LY3[2] = zmax; LY3[3] = xmin; LY3[4] = ymax; LY3[5] = zmax;
864 LZ1[0] = xmax; LZ1[1] = ymin; LZ1[2] = zmin; LZ1[3] = xmax; LZ1[4] = ymin; LZ1[5] = zmax;
867 LZ2[0] = xmax; LZ2[1] = ymax; LZ2[2] = zmin; LZ2[3] = xmax; LZ2[4] = ymax; LZ2[5] = zmax;
870 LZ3[0] = xmin; LZ3[1] = ymax; LZ3[2] = zmin; LZ3[3] = xmin; LZ3[4] = ymax; LZ3[5] = zmax;
876 /* Draw the graduated trihedron */
881 glColor3fv(data->gridcolor);
883 /* Boundary grid-lines */
886 glVertex3fv(&(LX1[0]));
887 glVertex3fv(&(LX1[3]));
891 glVertex3fv(&(LX2[0]));
892 glVertex3fv(&(LX2[3]));
896 glVertex3fv(&(LX3[0]));
897 glVertex3fv(&(LX3[3]));
901 glVertex3fv(&(LY1[0]));
902 glVertex3fv(&(LY1[3]));
906 glVertex3fv(&(LY2[0]));
907 glVertex3fv(&(LY2[3]));
911 glVertex3fv(&(LY3[0]));
912 glVertex3fv(&(LY3[3]));
916 glVertex3fv(&(LZ1[0]));
917 glVertex3fv(&(LZ1[3]));
921 glVertex3fv(&(LZ2[0]));
922 glVertex3fv(&(LZ2[3]));
926 glVertex3fv(&(LZ3[0]));
927 glVertex3fv(&(LZ3[3]));
931 /* Intermediate grid-lines */
935 i = data->drawaxes ? 1 : 0;
936 step = fabsf(LX1[3] - LX1[0]) / (float) data->nbx;
937 while (i < data->nbx)
939 glBegin(GL_LINE_STRIP);
940 glVertex3f(LX1[0] + i * step, LX1[1], LX1[2]);
941 glVertex3f(LX2[0] + i * step, LX2[1], LX2[2]);
942 glVertex3f(LX3[0] + i * step, LX3[1], LX3[2]);
950 i = data->drawaxes ? 1 : 0;
951 step = fabsf(LY1[4] - LY1[1]) / (float) data->nby;
952 while (i < data->nby)
954 glBegin(GL_LINE_STRIP);
955 glVertex3f(LY1[0], LY1[1] + i * step, LY1[2]);
956 glVertex3f(LY2[0], LY2[1] + i * step, LY2[2]);
957 glVertex3f(LY3[0], LY3[1] + i * step, LY3[2]);
965 i = data->drawaxes ? 1 : 0;
966 step = fabsf(LZ1[5] - LZ1[2]) / (float) data->nbz;
967 while (i < data->nbz)
969 glBegin(GL_LINE_STRIP);
970 glVertex3f(LZ1[0], LZ1[1], LZ1[2] + i * step);
971 glVertex3f(LZ2[0], LZ2[1], LZ2[2] + i * step);
972 glVertex3f(LZ3[0], LZ3[1], LZ3[2] + i * step);
983 glColor3fv(data->xcolor);
984 drawArrow(xmin, ymin, zmin, xmax, ymin, zmin, normal[0], normal[1], normal[2]);
987 glColor3fv(data->ycolor);
988 drawArrow(xmin, ymin, zmin, xmin, ymax, zmin, normal[0], normal[1], normal[2]);
991 glColor3fv(data->zcolor);
992 drawArrow(xmin, ymin, zmin, xmin, ymin, zmax, normal[0], normal[1], normal[2]);
994 /* Names of axes & values*/
996 if (data->xdrawname || data->xdrawvalues)
998 /* Middle point of the first X-axis */
999 m1[0] = 0.5f * (LX1[0] + LX1[3]);
1000 m1[1] = 0.5f * (LX1[1] + LX1[4]);
1001 m1[2] = 0.5f * (LX1[2] + LX1[5]);
1003 /* Middle point of the second X-axis */
1004 m2[0] = 0.5f * (LX2[0] + LX2[3]);
1005 m2[1] = 0.5f * (LX2[1] + LX2[4]);
1006 m2[2] = 0.5f * (LX2[2] + LX2[5]);
1008 /* Apply offset to m1 */
1010 if (fabsf(dy) > 1.e-7f)
1018 if (fabsf(dz) > 1.e-7f)
1029 /* Name of X-axis */
1030 if (data->xdrawname)
1032 glColor3fv(data->xnamecolor);
1033 offset = data->xaxisoffset + data->xtickmarklength;
1034 drawText(data->xname, data->fontOfNames, data->styleOfNames, data->sizeOfNames,
1035 m1[0], m1[1] + offset * m2[1], m1[2] + offset * m2[2]);
1039 if (data->xdrawvalues && data->nbx > 0)
1041 glColor3fv(data->xcolor);
1044 step = fabsf(LX1[3] - LX1[0]) / (float) data->nbx;
1045 offset = data->xoffset + data->xtickmarklength;
1046 while (i <= data->nbx)
1048 sprintf(textValue, "%g", LX1[0] + i * step);
1049 drawText(textValue, data->fontOfValues, data->styleOfValues, data->sizeOfValues,
1050 LX1[0] + i * step, m1[1] + offset * m2[1], m1[2] + offset * m2[2]);
1056 if (data->xdrawtickmarks && data->nbx > 0)
1058 glColor3fv(data->gridcolor);
1061 step = fabsf(LX1[3] - LX1[0]) / (float) data->nbx;
1062 while (i <= data->nbx)
1065 glVertex3f(LX1[0] + i * step, m1[1], m1[2]);
1066 glVertex3f(LX1[0] + i * step, m1[1] + data->xtickmarklength * m2[1], m1[2] + data->xtickmarklength * m2[2]);
1073 if (data->ydrawname || data->ydrawvalues)
1075 /* Middle point of the first Y-axis */
1076 m1[0] = 0.5f * (LY1[0] + LY1[3]);
1077 m1[1] = 0.5f * (LY1[1] + LY1[4]);
1078 m1[2] = 0.5f * (LY1[2] + LY1[5]);
1080 /* Middle point of the second Y-axis */
1081 m2[0] = 0.5f * (LY2[0] + LY2[3]);
1082 m2[1] = 0.5f * (LY2[1] + LY2[4]);
1083 m2[2] = 0.5f * (LY2[2] + LY2[5]);
1085 /* Apply offset to m1 */
1087 if (fabsf(dx) > 1.e-7f)
1095 if (fabsf(dz) > 1.e-7f)
1106 /* Name of Y-axis */
1107 if (data->ydrawname)
1109 glColor3fv(data->ynamecolor);
1110 offset = data->yaxisoffset + data->ytickmarklength;
1111 drawText(data->yname, data->fontOfNames, data->styleOfNames, data->sizeOfNames,
1112 m1[0] + offset * m2[0], m1[1], m1[2] + offset * m2[2]);
1116 if (data->ydrawvalues && data->nby > 0)
1118 glColor3fv(data->ycolor);
1121 step = fabsf(LY1[4] - LY1[1]) / (float) data->nby;
1122 offset = data->yoffset + data->ytickmarklength;
1123 while (i <= data->nby)
1125 sprintf(textValue, "%g", LY1[1] + i * step);
1126 drawText(textValue, data->fontOfValues, data->styleOfValues, data->sizeOfValues,
1127 m1[0] + offset * m2[0], LY1[1] + i * step, m1[2] + offset * m2[2]);
1133 if (data->ydrawtickmarks && data->nby > 0)
1135 glColor3fv(data->gridcolor);
1138 step = fabsf(LY1[4] - LY1[1]) / (float) data->nby;
1139 while (i <= data->nby)
1142 glVertex3f(m1[0], LY1[1] + i * step, m1[2]);
1143 glVertex3f(m1[0] + data->ytickmarklength * m2[0], LY1[1] + i * step, m1[2] + data->ytickmarklength * m2[2]);
1150 if (data->zdrawname || data->zdrawvalues)
1152 /* Middle point of the first Z-axis */
1153 m1[0] = 0.5f * (LZ1[0] + LZ1[3]);
1154 m1[1] = 0.5f * (LZ1[1] + LZ1[4]);
1155 m1[2] = 0.5f * (LZ1[2] + LZ1[5]);
1157 /* Middle point of the second Z-axis */
1158 m2[0] = 0.5f * (LZ2[0] + LZ2[3]);
1159 m2[1] = 0.5f * (LZ2[1] + LZ2[4]);
1160 m2[2] = 0.5f * (LZ2[2] + LZ2[5]);
1162 /* Apply offset to m1 */
1164 if (fabsf(dx) > 1.e-7f)
1172 if (fabsf(dy) > 1.e-7f)
1183 /* Name of Z-axis */
1184 if (data->zdrawname)
1186 glColor3fv(data->znamecolor);
1187 offset = data->zaxisoffset + data->ztickmarklength;
1188 drawText(data->zname, data->fontOfNames, data->styleOfNames, data->sizeOfNames,
1189 m1[0] + offset * m2[0], m1[1] + offset * m2[1], m1[2]);
1193 if (data->zdrawvalues && data->nbz > 0)
1195 glColor3fv(data->zcolor);
1198 step = fabsf(LZ1[5] - LZ1[2]) / (float) data->nbz;
1199 offset = data->zoffset + data->ztickmarklength;
1200 while (i <= data->nbz)
1202 sprintf(textValue, "%g", LZ1[2] + i * step);
1203 drawText(textValue, data->fontOfValues, data->styleOfValues, data->sizeOfValues,
1204 m1[0] + offset * m2[0], m1[1] + offset * m2[1], LZ1[2] + i * step);
1210 if (data->zdrawtickmarks && data->nbz > 0)
1212 glColor3fv(data->gridcolor);
1215 step = fabsf(LZ1[5] - LZ1[2]) / (float) data->nbz;
1216 while (i <= data->nbz)
1219 glVertex3f(m1[0], m1[1], LZ1[2] + i * step);
1220 glVertex3f(m1[0] + data->ztickmarklength * m2[0], m1[1] + data->ztickmarklength * m2[1], LZ1[2] + i * step);
1227 /* Activate the lighting if it was turned off by this method call */
1229 glEnable(GL_LIGHTING);
1234 TStatus call_graduatedtrihedron_minmaxvalues(const float xMin,