gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
drawGlyph.cpp
Go to the documentation of this file.
1 // Gmsh - Copyright (C) 1997-2022 C. Geuzaine, J.-F. Remacle
2 //
3 // See the LICENSE.txt file in the Gmsh root directory for license information.
4 // Please report all issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
5 
6 #include <string.h>
7 #include "drawContext.h"
8 #include "GmshDefines.h"
9 #include "Numeric.h"
10 #include "StringUtils.h"
11 #include "Context.h"
12 #include "gl2ps.h"
13 #include "SVector3.h"
14 #include "GModel.h"
15 
16 void drawContext::drawString(const std::string &s, double x, double y, double z,
17  const std::string &font_name, int font_enum,
18  int font_size, int align, int line_num)
19 {
20  if(s.empty()) return;
21  if(CTX::instance()->printing && !CTX::instance()->print.text) return;
22 
23  if(s.size() > 8 && s.substr(0, 7) == "file://") {
24  drawImage(s.substr(7), x, y, z, align);
25  return;
26  }
27 
28  glRasterPos3d(x, y, z);
29  GLboolean valid;
30  glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &valid);
31  if(valid == GL_FALSE) return; // the primitive is culled
32 
33  if(align > 0 || line_num) {
34  GLdouble pos[4];
35  glGetDoublev(GL_CURRENT_RASTER_POSITION, pos);
36  double x[3], w[3] = {pos[0], pos[1], pos[2]};
37  drawContext::global()->setFont(font_enum, font_size);
38  double width = drawContext::global()->getStringWidth(s.c_str());
39  double height = drawContext::global()->getStringHeight();
40  // width and height must here be computed in true pixel coordinates, because
41  // viewport2world uses the actual, pixel-sized (not FLTK-sized) viewport
42  width *= highResolutionPixelFactor();
43  height *= highResolutionPixelFactor();
44  // alignment for TeX is handled directly by gl2ps
45  if(!CTX::instance()->printing ||
46  CTX::instance()->print.fileFormat != FORMAT_TEX) {
47  switch(align) {
48  case 1:
49  w[0] -= width / 2.;
50  break; // bottom center
51  case 2:
52  w[0] -= width;
53  break; // bottom right
54  case 3:
55  w[1] -= height;
56  break; // top left
57  case 4:
58  w[0] -= width / 2.;
59  w[1] -= height;
60  break; // top center
61  case 5:
62  w[0] -= width;
63  w[1] -= height;
64  break; // top right
65  case 6:
66  w[1] -= height / 2.;
67  break; // center left
68  case 7:
69  w[0] -= width / 2.;
70  w[1] -= height / 2.;
71  break; // center center
72  case 8:
73  w[0] -= width;
74  w[1] -= height / 2.;
75  break; // center right
76  default: break;
77  }
78  }
79  // treat line number also for TeX
80  if(line_num) w[1] -= line_num * (1.1 * height);
81  viewport2World(w, x);
82  glRasterPos3d(x[0], x[1], x[2]);
83  }
84 
85  if(!CTX::instance()->printing) {
86  drawContext::global()->setFont(font_enum, font_size);
87  drawContext::global()->drawString(s.c_str());
88  }
89  else {
90  if(CTX::instance()->print.fileFormat == FORMAT_TEX) {
91  std::string tmp =
93  int opt;
94  switch(align) {
95  case 1:
96  opt = GL2PS_TEXT_B;
97  break; // bottom center
98  case 2:
99  opt = GL2PS_TEXT_BR;
100  break; // bottom right
101  case 3:
102  opt = GL2PS_TEXT_TL;
103  break; // top left
104  case 4:
105  opt = GL2PS_TEXT_T;
106  break; // top center
107  case 5:
108  opt = GL2PS_TEXT_TR;
109  break; // top right
110  case 6:
111  opt = GL2PS_TEXT_CL;
112  break; // center left
113  case 7:
114  opt = GL2PS_TEXT_C;
115  break; // center center
116  case 8:
117  opt = GL2PS_TEXT_CR;
118  break; // center right
119  default:
120  opt = GL2PS_TEXT_BL;
121  break; // bottom left
122  }
123  gl2psTextOpt(tmp.c_str(), font_name.c_str(), font_size, opt, 0.);
124  }
125  else if(CTX::instance()->print.epsQuality &&
131  gl2psText(s.c_str(), font_name.c_str(), font_size);
132  }
133  else {
134  drawContext::global()->setFont(font_enum, font_size);
135  drawContext::global()->drawString(s.c_str());
136  }
137  }
138 }
139 
140 void drawContext::drawString(const std::string &s, double x, double y, double z,
141  int line_num)
142 {
143  drawString(s, x, y, z, CTX::instance()->glFont, CTX::instance()->glFontEnum,
144  CTX::instance()->glFontSize, 0, line_num);
145 }
146 
147 void drawContext::drawStringCenter(const std::string &s, double x, double y,
148  double z, int line_num)
149 {
150  drawString(s, x, y, z, CTX::instance()->glFont, CTX::instance()->glFontEnum,
151  CTX::instance()->glFontSize, 1, line_num);
152 }
153 
154 void drawContext::drawStringRight(const std::string &s, double x, double y,
155  double z, int line_num)
156 {
157  drawString(s, x, y, z, CTX::instance()->glFont, CTX::instance()->glFontEnum,
158  CTX::instance()->glFontSize, 2, line_num);
159 }
160 
161 void drawContext::drawString(const std::string &s, double x, double y, double z,
162  double style, int line_num)
163 {
164  unsigned int bits = (unsigned int)style;
165 
166  if(!bits) { // use defaults
167  drawString(s, x, y, z, line_num);
168  }
169  else {
170  int size = (bits & 0xff);
171  int font = (bits >> 8 & 0xff);
172  int align = (bits >> 16 & 0xff);
173  int font_enum = drawContext::global()->getFontEnum(font);
174  std::string font_name = drawContext::global()->getFontName(font);
175  if(!size) size = CTX::instance()->glFontSize;
176  drawString(s, x, y, z, font_name, font_enum, size, align, line_num);
177  }
178 }
179 
180 void drawContext::drawImage(const std::string &name, double x, double y,
181  double z, int align)
182 {
183  // format can be "@wxh" or "@wxh,wx,wy,wz,hx,hy,hz", where w and h are the
184  // width and height (in model coordinates for T3 or in pixels for T2) of the
185  // image, wx,wy,wz is the direction of the bottom edge of the image and
186  // hx,hy,hz is the direction of the left edge of the image.
187  size_t p = name.find_last_of('@');
188  std::string file = name, format;
189  if(p != std::string::npos) {
190  format = name.substr(p + 1);
191  file = name.substr(0, p);
192  }
193  double w = 0., h = 0., wx = 1., wy = 0., wz = 0., hx = 0., hy = 1., hz = 0.;
194  bool billboard = false;
195  if(format.size()) {
196  bool ok;
197  if(format.find(',') != std::string::npos)
198  ok = (sscanf(format.c_str(), "%lfx%lf,%lf,%lf,%lf,%lf,%lf,%lf", &w, &h,
199  &wx, &wy, &wz, &hx, &hy, &hz) == 8);
200  else
201  ok = (sscanf(format.c_str(), "%lfx%lf", &w, &h) == 2);
202  if(!ok)
203  Msg::Warning("Bad image format: use `@wxh' or `@wxh,wx,wy,wz,hx,hy,hz'");
204  if(format.find('#') != std::string::npos)
205  billboard = true; // texture will always face camera
206  }
207 
208  imgtex *img;
209  if(!_imageTextures.count(file)) {
210  img = &_imageTextures[file];
211  file = FixRelativePath(GModel::current()->getFileName(), file);
212  if(!generateTextureForImage(file, 1, img->tex, img->w, img->h)) {
213  return;
214  }
215  }
216  else {
217  img = &_imageTextures[file];
218  }
219  if(!img->tex) {
220  Msg::Debug("No texture for image - skipping image draw");
221  return;
222  }
223 
224  if(w == 0 && h == 0) {
225  w = img->w;
226  h = img->h;
227  }
228  else if(h == 0) {
229  h = w * img->h / img->w;
230  }
231  else if(w == 0) {
232  w = h * img->w / img->h;
233  }
234 
235  GLboolean valid = GL_TRUE;
236  GLint matrixMode = 0;
237  if(billboard) {
238  glRasterPos3d(x, y, z);
239  GLfloat pos[4];
240  glGetFloatv(GL_CURRENT_RASTER_POSITION, pos);
241  glGetIntegerv(GL_MATRIX_MODE, &matrixMode);
242  glMatrixMode(GL_PROJECTION);
243  glPushMatrix();
244  glLoadIdentity();
245  glMatrixMode(GL_MODELVIEW);
246  glPushMatrix();
247  glLoadIdentity();
248  double fact = highResolutionPixelFactor();
249  glOrtho((double)viewport[0], (double)viewport[2] * fact,
250  (double)viewport[1], (double)viewport[3] * fact, -1, 1);
251  x = pos[0];
252  y = pos[1];
253  z = 0;
254  w *= fact * s[0] / pixel_equiv_x;
255  h *= fact * s[1] / pixel_equiv_y;
256  glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &valid);
257  }
258  if(valid == GL_TRUE) {
259  switch(align) {
260  case 1:
261  x -= w / 2.;
262  break; // bottom center
263  case 2:
264  x -= w;
265  break; // bottom right
266  case 3:
267  y -= h;
268  break; // top left
269  case 4:
270  x -= w / 2.;
271  y -= h;
272  break; // top center
273  case 5:
274  x -= w;
275  y -= h;
276  break; // top right
277  case 6:
278  y -= h / 2.;
279  break; // center left
280  case 7:
281  x -= w / 2.;
282  y -= h / 2.;
283  break; // center center
284  case 8:
285  x -= w;
286  y -= h / 2.;
287  break; // center right
288  default: break;
289  }
290  glEnable(GL_BLEND);
291  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
292  glEnable(GL_TEXTURE_2D);
293  glBindTexture(GL_TEXTURE_2D, img->tex);
294  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
295  glBegin(GL_QUADS);
296  glTexCoord2f(1.0f, 1.0f);
297  glVertex3d(x + wx * w, y + wy * w, z + wz * w);
298  glTexCoord2f(1.0f, 0.0f);
299  glVertex3d(x + wx * w + hx * h, y + wy * w + hy * h, z + wz * w + hz * h);
300  glTexCoord2f(0.0f, 0.0f);
301  glVertex3d(x + hx * h, y + hy * h, z + hz * h);
302  glTexCoord2f(0.0f, 1.0f);
303  glVertex3d(x, y, z);
304  glEnd();
305  glDisable(GL_TEXTURE_2D);
306  glDisable(GL_BLEND);
307  }
308  if(billboard) {
309  glPopMatrix();
310  glMatrixMode(GL_PROJECTION);
311  glPopMatrix();
312  glMatrixMode(matrixMode);
313  }
314 }
315 
316 void drawContext::drawCube(double x, double y, double z, double val[9],
317  int light)
318 {
319  double d0[3] = {val[0], val[1], val[2]};
320  double d1[3] = {val[3], val[4], val[5]};
321  double d2[3] = {val[6], val[7], val[8]};
322 
323  double x0[3] = {x + d1[0] + d1[0] + d2[0], x + d0[1] + d1[1] + d2[1],
324  z + d0[2] + d1[2] + d2[2]};
325  double x1[3] = {x - d1[0] + d1[0] + d2[0], x - d0[1] + d1[1] + d2[1],
326  z - d0[2] + d1[2] + d2[2]};
327  double x2[3] = {x - d1[0] - d1[0] + d2[0], x - d0[1] - d1[1] + d2[1],
328  z - d0[2] - d1[2] + d2[2]};
329  double x3[3] = {x + d1[0] - d1[0] + d2[0], x + d0[1] - d1[1] + d2[1],
330  z + d0[2] - d1[2] + d2[2]};
331 
332  double x4[3] = {x + d1[0] + d1[0] - d2[0], x + d0[1] + d1[1] - d2[1],
333  z + d0[2] + d1[2] - d2[2]};
334  double x5[3] = {x - d1[0] + d1[0] - d2[0], x - d0[1] + d1[1] - d2[1],
335  z - d0[2] + d1[2] - d2[2]};
336  double x6[3] = {x - d1[0] - d1[0] - d2[0], x - d0[1] - d1[1] - d2[1],
337  z - d0[2] - d1[2] - d2[2]};
338  double x7[3] = {x + d1[0] - d1[0] - d2[0], x + d0[1] - d1[1] - d2[1],
339  z + d0[2] - d1[2] - d2[2]};
340 
341  if(light) glEnable(GL_LIGHTING);
342  glPushMatrix();
343 
344  glBegin(GL_POLYGON);
345  glColor3f(x0[0], x0[1], x0[2]);
346  glColor3f(x1[0], x1[1], x1[2]);
347  glColor3f(x2[0], x2[1], x2[2]);
348  glColor3f(x3[0], x3[1], x3[2]);
349  glEnd();
350 
351  glBegin(GL_POLYGON);
352  glColor3f(x4[0], x4[1], x4[2]);
353  glColor3f(x7[0], x7[1], x7[2]);
354  glColor3f(x6[0], x6[1], x6[2]);
355  glColor3f(x5[0], x5[1], x5[2]);
356  glEnd();
357 
358  glBegin(GL_POLYGON);
359  glColor3f(x0[0], x0[1], x0[2]);
360  glColor3f(x3[0], x3[1], x3[2]);
361  glColor3f(x7[0], x7[1], x7[2]);
362  glColor3f(x4[0], x4[1], x4[2]);
363  glEnd();
364 
365  glBegin(GL_POLYGON);
366  glColor3f(x1[0], x1[1], x1[2]);
367  glColor3f(x5[0], x5[1], x5[2]);
368  glColor3f(x6[0], x6[1], x6[2]);
369  glColor3f(x2[0], x2[1], x2[2]);
370  glEnd();
371 
372  glBegin(GL_POLYGON);
373  glColor3f(x0[0], x0[1], x0[2]);
374  glColor3f(x4[0], x4[1], x4[2]);
375  glColor3f(x5[0], x5[1], x5[2]);
376  glColor3f(x1[0], x1[1], x1[2]);
377  glEnd();
378 
379  glBegin(GL_POLYGON);
380  glColor3f(x3[0], x3[1], x3[2]);
381  glColor3f(x2[0], x2[1], x2[2]);
382  glColor3f(x6[0], x6[1], x6[2]);
383  glColor3f(x7[0], x7[1], x7[2]);
384  glEnd();
385 
386  glPopMatrix();
387  glDisable(GL_LIGHTING);
388 }
389 
390 void drawContext::drawSphere(double R, double x, double y, double z, int n1,
391  int n2, int light)
392 {
393  if(light) glEnable(GL_LIGHTING);
394  glPushMatrix();
395  glTranslated(x, y, z);
396  gluSphere(_quadric, R, n1, n2);
397  glPopMatrix();
398  glDisable(GL_LIGHTING);
399 }
400 
401 void drawContext::drawEllipse(double x, double y, double z, float v0[3],
402  float v1[3], int light)
403 {
404  if(light) glEnable(GL_LIGHTING);
405  glPushMatrix();
406  GLfloat m[16] = {v0[0],
407  v0[1],
408  v0[2],
409  .0f,
410  v1[0],
411  v1[1],
412  v1[2],
413  .0f,
414  v0[1] * v1[2] - v0[2] * v1[1],
415  v0[2] * v1[0] - v0[0] * v1[2],
416  v0[0] * v1[1] - v0[1] * v1[0],
417  .0f,
418  (GLfloat)x,
419  (GLfloat)y,
420  (GLfloat)z,
421  1.f};
422  glMultMatrixf(m);
423  glCallList(_displayLists + 2);
424  glPopMatrix();
425  glDisable(GL_LIGHTING);
426 }
427 
428 void drawContext::drawEllipsoid(double x, double y, double z, float v0[3],
429  float v1[3], float v2[3], int light)
430 {
431  if(light) glEnable(GL_LIGHTING);
432  glPushMatrix();
433  GLfloat m[16] = {v0[0], v0[1], v0[2], .0f, v1[0], v1[1],
434  v1[2], .0f, v2[0], v2[1], v2[2], .0f,
435  (GLfloat)x, (GLfloat)y, (GLfloat)z, 1.f};
436  glMultMatrixf(m);
437  glCallList(_displayLists + 0);
438  glPopMatrix();
439  glDisable(GL_LIGHTING);
440 }
441 
442 void drawContext::drawSphere(double size, double x, double y, double z,
443  int light)
444 {
445  double ss = size * pixel_equiv_x / s[0]; // size is in pixels
446  if(light) glEnable(GL_LIGHTING);
447  glPushMatrix();
448  glTranslated(x, y, z);
449  glScaled(ss, ss, ss);
450  glCallList(_displayLists + 0);
451  glPopMatrix();
452  glDisable(GL_LIGHTING);
453 }
454 
455 void drawContext::drawTaperedCylinder(double width, double val1, double val2,
456  double ValMin, double ValMax, double *x,
457  double *y, double *z, int light)
458 {
459  if(light) glEnable(GL_LIGHTING);
460 
461  double dx = x[1] - x[0];
462  double dy = y[1] - y[0];
463  double dz = z[1] - z[0];
464  double const length = std::sqrt(dx * dx + dy * dy + dz * dz);
465  double fact = width * pixel_equiv_x / s[0] / (ValMax - ValMin);
466  double radius1 = (val1 - ValMin) * fact;
467  double radius2 = (val2 - ValMin) * fact;
468  double zdir[3] = {0., 0., 1.};
469  double vdir[3] = {dx / length, dy / length, dz / length};
470  double axis[3], phi;
471  prodve(zdir, vdir, axis);
472  double const cosphi = prosca(zdir, vdir);
473  if(!norme(axis)) {
474  axis[0] = 0.;
475  axis[1] = 1.;
476  axis[2] = 0.;
477  }
478  phi = 180. * myacos(cosphi) / M_PI;
479 
480  glPushMatrix();
481  glTranslated(x[0], y[0], z[0]);
482  glRotated(phi, axis[0], axis[1], axis[2]);
483  gluCylinder(_quadric, radius1, radius2, length,
484  CTX::instance()->quadricSubdivisions, 1);
485  glPopMatrix();
486 
487  glDisable(GL_LIGHTING);
488 }
489 
490 void drawContext::drawCylinder(double width, double *x, double *y, double *z,
491  int light)
492 {
493  if(light) glEnable(GL_LIGHTING);
494 
495  double dx = x[1] - x[0];
496  double dy = y[1] - y[0];
497  double dz = z[1] - z[0];
498  double const length = std::sqrt(dx * dx + dy * dy + dz * dz);
499  double radius = width * pixel_equiv_x / s[0];
500  double zdir[3] = {0., 0., 1.};
501  double vdir[3] = {dx / length, dy / length, dz / length};
502  double axis[3], phi;
503  prodve(zdir, vdir, axis);
504  double const cosphi = prosca(zdir, vdir);
505  if(!norme(axis)) {
506  axis[0] = 0.;
507  axis[1] = 1.;
508  axis[2] = 0.;
509  }
510  phi = 180. * myacos(cosphi) / M_PI;
511 
512  glPushMatrix();
513  glTranslated(x[0], y[0], z[0]);
514  glRotated(phi, axis[0], axis[1], axis[2]);
515  gluCylinder(_quadric, radius, radius, length,
516  CTX::instance()->quadricSubdivisions, 1);
517  glPopMatrix();
518 
519  glDisable(GL_LIGHTING);
520 }
521 
522 static void drawSimpleVector(int arrow, int fill, double x, double y, double z,
523  double dx, double dy, double dz, double d,
524  int light)
525 {
526  double n[3], t[3], u[3];
527 
528  n[0] = dx / d;
529  n[1] = dy / d;
530  n[2] = dz / d;
531 
532  if((fabs(n[0]) >= fabs(n[1]) && fabs(n[0]) >= fabs(n[2])) ||
533  (fabs(n[1]) >= fabs(n[0]) && fabs(n[1]) >= fabs(n[2]))) {
534  t[0] = n[1];
535  t[1] = -n[0];
536  t[2] = 0.;
537  }
538  else {
539  t[0] = 0.;
540  t[1] = n[2];
541  t[2] = -n[1];
542  }
543 
544  double l = sqrt(t[0] * t[0] + t[1] * t[1] + t[2] * t[2]);
545  t[0] /= l;
546  t[1] /= l;
547  t[2] /= l;
548 
549  u[0] = n[1] * t[2] - n[2] * t[1];
550  u[1] = n[2] * t[0] - n[0] * t[2];
551  u[2] = n[0] * t[1] - n[1] * t[0];
552 
553  l = sqrt(u[0] * u[0] + u[1] * u[1] + u[2] * u[2]);
554  u[0] /= l;
555  u[1] /= l;
556  u[2] /= l;
557 
558  double b = CTX::instance()->arrowRelHeadRadius * d;
559 
560  if(arrow) {
561  double f1 = CTX::instance()->arrowRelStemLength;
562  double f2 = (1 - 2. * CTX::instance()->arrowRelStemRadius) * f1; // hack :-)
563 
564  if(fill) {
565  glBegin(GL_LINES);
566  glVertex3d(x, y, z);
567  glVertex3d(x + f1 * dx, y + f1 * dy, z + f1 * dz);
568  glEnd();
569 
570  if(light && fill) glEnable(GL_LIGHTING);
571  glBegin(GL_TRIANGLES);
572  if(light) glNormal3dv(u);
573  glVertex3d(x + dx, y + dy, z + dz);
574  glVertex3d(x + f2 * dx + b * (t[0]), y + f2 * dy + b * (t[1]),
575  z + f2 * dz + b * (t[2]));
576  glVertex3d(x + f1 * dx, y + f1 * dy, z + f1 * dz);
577 
578  glVertex3d(x + f1 * dx, y + f1 * dy, z + f1 * dz);
579  glVertex3d(x + f2 * dx + b * (-t[0]), y + f2 * dy + b * (-t[1]),
580  z + f2 * dz + b * (-t[2]));
581  glVertex3d(x + dx, y + dy, z + dz);
582 
583  if(light) glNormal3dv(t);
584  glVertex3d(x + dx, y + dy, z + dz);
585  glVertex3d(x + f2 * dx + b * (-u[0]), y + f2 * dy + b * (-u[1]),
586  z + f2 * dz + b * (-u[2]));
587  glVertex3d(x + f1 * dx, y + f1 * dy, z + f1 * dz);
588 
589  glVertex3d(x + f1 * dx, y + f1 * dy, z + f1 * dz);
590  glVertex3d(x + f2 * dx + b * (u[0]), y + f2 * dy + b * (u[1]),
591  z + f2 * dz + b * (u[2]));
592  glVertex3d(x + dx, y + dy, z + dz);
593  glEnd();
594  glDisable(GL_LIGHTING);
595  }
596  else {
597  glBegin(GL_LINE_STRIP);
598  glVertex3d(x, y, z);
599  glVertex3d(x + dx, y + dy, z + dz);
600  glVertex3d(x + f2 * dx + b * (t[0]), y + f2 * dy + b * (t[1]),
601  z + f2 * dz + b * (t[2]));
602  glVertex3d(x + f1 * dx, y + f1 * dy, z + f1 * dz);
603  glVertex3d(x + f2 * dx + b * (-t[0]), y + f2 * dy + b * (-t[1]),
604  z + f2 * dz + b * (-t[2]));
605  glVertex3d(x + dx, y + dy, z + dz);
606  glVertex3d(x + f2 * dx + b * (-u[0]), y + f2 * dy + b * (-u[1]),
607  z + f2 * dz + b * (-u[2]));
608  glVertex3d(x + f1 * dx, y + f1 * dy, z + f1 * dz);
609  glVertex3d(x + f2 * dx + b * (u[0]), y + f2 * dy + b * (u[1]),
610  z + f2 * dz + b * (u[2]));
611  glVertex3d(x + dx, y + dy, z + dz);
612  glEnd();
613  }
614  }
615  else { // simple pyramid
616  if(fill) {
617  double top[3] = {x + dx, y + dy, z + dz};
618  double tp[3] = {x + b * t[0], y + b * t[1], z + b * t[2]};
619  double tm[3] = {x - b * t[0], y - b * t[1], z - b * t[2]};
620  double up[3] = {x + b * u[0], y + b * u[1], z + b * u[2]};
621  double um[3] = {x - b * u[0], y - b * u[1], z - b * u[2]};
622  double nn[3];
623 
624  if(light && fill) glEnable(GL_LIGHTING);
625  glBegin(GL_TRIANGLES);
626  if(light) {
627  normal3points(tm[0], tm[1], tm[2], um[0], um[1], um[2], top[0], top[1],
628  top[2], nn);
629  glNormal3dv(nn);
630  }
631  glVertex3d(tm[0], tm[1], tm[2]);
632  glVertex3d(um[0], um[1], um[2]);
633  glVertex3d(top[0], top[1], top[2]);
634 
635  if(light) {
636  normal3points(um[0], um[1], um[2], tp[0], tp[1], tp[2], top[0], top[1],
637  top[2], nn);
638  glNormal3dv(nn);
639  }
640  glVertex3d(um[0], um[1], um[2]);
641  glVertex3d(tp[0], tp[1], tp[2]);
642  glVertex3d(top[0], top[1], top[2]);
643 
644  if(light) {
645  normal3points(tp[0], tp[1], tp[2], up[0], up[1], up[2], top[0], top[1],
646  top[2], nn);
647  glNormal3dv(nn);
648  }
649  glVertex3d(tp[0], tp[1], tp[2]);
650  glVertex3d(up[0], up[1], up[2]);
651  glVertex3d(top[0], top[1], top[2]);
652 
653  if(light) {
654  normal3points(up[0], up[1], up[2], tm[0], tm[1], tm[2], top[0], top[1],
655  top[2], nn);
656  glNormal3dv(nn);
657  }
658  glVertex3d(up[0], up[1], up[2]);
659  glVertex3d(tm[0], tm[1], tm[2]);
660  glVertex3d(top[0], top[1], top[2]);
661  glEnd();
662  glDisable(GL_LIGHTING);
663  }
664  else {
665  glBegin(GL_LINE_LOOP);
666  glVertex3d(x + b * (t[0]), y + b * (t[1]), z + b * (t[2]));
667  glVertex3d(x + b * (-u[0]), y + b * (-u[1]), z + b * (-u[2]));
668  glVertex3d(x + b * (-t[0]), y + b * (-t[1]), z + b * (-t[2]));
669  glVertex3d(x + b * (u[0]), y + b * (u[1]), z + b * (u[2]));
670  glEnd();
671 
672  glBegin(GL_LINES);
673  glVertex3d(x + b * (t[0]), y + b * (t[1]), z + b * (t[2]));
674  glVertex3d(x + dx, y + dy, z + dz);
675 
676  glVertex3d(x + b * (-u[0]), y + b * (-u[1]), z + b * (-u[2]));
677  glVertex3d(x + dx, y + dy, z + dz);
678 
679  glVertex3d(x + b * (-t[0]), y + b * (-t[1]), z + b * (-t[2]));
680  glVertex3d(x + dx, y + dy, z + dz);
681 
682  glVertex3d(x + b * (u[0]), y + b * (u[1]), z + b * (u[2]));
683  glVertex3d(x + dx, y + dy, z + dz);
684  glEnd();
685  }
686  }
687 }
688 
689 void drawContext::drawArrow3d(double x, double y, double z, double dx,
690  double dy, double dz, double length, int light)
691 {
692  double zdir[3] = {0., 0., 1.};
693  double vdir[3] = {dx / length, dy / length, dz / length};
694  double axis[3];
695  prodve(zdir, vdir, axis);
696  double const cosphi = prosca(zdir, vdir);
697  if(!norme(axis)) {
698  axis[0] = 0.;
699  axis[1] = 1.;
700  axis[2] = 0.;
701  }
702  double phi = 180. * myacos(cosphi) / M_PI;
703 
704  if(light) glEnable(GL_LIGHTING);
705  glPushMatrix();
706  glTranslated(x, y, z);
707  glScaled(length, length, length);
708  glRotated(phi, axis[0], axis[1], axis[2]);
709  glCallList(_displayLists + 1);
710  glPopMatrix();
711  glDisable(GL_LIGHTING);
712 }
713 
714 void drawContext::drawVector(int Type, int Fill, double x, double y, double z,
715  double dx, double dy, double dz, int light)
716 {
717  double length = sqrt(dx * dx + dy * dy + dz * dz);
718 
719  if(length == 0.0) return;
720 
721  switch(Type) {
722  case 1:
723  glBegin(GL_LINES);
724  glVertex3d(x, y, z);
725  glVertex3d(x + dx, y + dy, z + dz);
726  glEnd();
727  break;
728  case 6:
729  if(CTX::instance()->arrowRelHeadRadius) {
730  glBegin(GL_POINTS);
731  glVertex3d(x + dx, y + dy, z + dz);
732  glEnd();
733  }
734  glBegin(GL_LINES);
735  glVertex3d(x + dx, y + dy, z + dz);
736  // color gradient
737  glColor4ubv((GLubyte *)&CTX::instance()->color.bg);
738  glVertex3d(x, y, z);
739  glEnd();
740  break;
741  case 2: drawSimpleVector(1, Fill, x, y, z, dx, dy, dz, length, light); break;
742  case 3: drawSimpleVector(0, Fill, x, y, z, dx, dy, dz, length, light); break;
743  case 4:
744  default: drawArrow3d(x, y, z, dx, dy, dz, length, light); break;
745  }
746 }
747 
748 namespace {
749 class point {
750 public:
751  double x, y, z;
752  bool valid;
753  point() : x(0.), y(0.), z(0.), valid(false) {}
754  point(double xi, double yi, double zi) : x(xi), y(yi), z(zi), valid(true) {}
755 };
756 
757 class plane {
758 private:
759  double _a, _b, _c, _d;
760 
761 public:
762  plane(double a, double b, double c, double d) : _a(a), _b(b), _c(c), _d(d) {}
763  double val(point &p) { return _a * p.x + _b * p.y + _c * p.z + _d; };
764  point intersect(point &p1, point &p2)
765  {
766  double v1 = val(p1), v2 = val(p2);
767  if(fabs(v1) < 1.e-12) {
768  if(fabs(v2) < 1.e-12)
769  return point();
770  else
771  return point(p1.x, p1.y, p1.z);
772  }
773  else if(fabs(v2) < 1.e-12) {
774  return point(p2.x, p2.y, p2.z);
775  }
776  else if(v1 * v2 < 0.) {
777  double coef = -v1 / (v2 - v1);
778  return point(coef * (p2.x - p1.x) + p1.x, coef * (p2.y - p1.y) + p1.y,
779  coef * (p2.z - p1.z) + p1.z);
780  }
781  else
782  return point();
783  }
784 };
785 }
786 
787 void drawContext::drawBox(double xmin, double ymin, double zmin, double xmax,
788  double ymax, double zmax, bool labels)
789 {
790  glBegin(GL_LINE_LOOP);
791  glVertex3d(xmin, ymin, zmin);
792  glVertex3d(xmax, ymin, zmin);
793  glVertex3d(xmax, ymax, zmin);
794  glVertex3d(xmin, ymax, zmin);
795  glEnd();
796  glBegin(GL_LINE_LOOP);
797  glVertex3d(xmin, ymin, zmax);
798  glVertex3d(xmax, ymin, zmax);
799  glVertex3d(xmax, ymax, zmax);
800  glVertex3d(xmin, ymax, zmax);
801  glEnd();
802  glBegin(GL_LINES);
803  glVertex3d(xmin, ymin, zmin);
804  glVertex3d(xmin, ymin, zmax);
805  glVertex3d(xmax, ymin, zmin);
806  glVertex3d(xmax, ymin, zmax);
807  glVertex3d(xmax, ymax, zmin);
808  glVertex3d(xmax, ymax, zmax);
809  glVertex3d(xmin, ymax, zmin);
810  glVertex3d(xmin, ymax, zmax);
811  glEnd();
812  if(labels) {
813  char label[256];
814  double offset = 0.3 * CTX::instance()->glFontSize * pixel_equiv_x;
815  sprintf(label, "(%g,%g,%g)", xmin, ymin, zmin);
816  drawString(label, xmin + offset / s[0], ymin + offset / s[1],
817  zmin + offset / s[2]);
818  sprintf(label, "(%g,%g,%g)", xmax, ymax, zmax);
819  drawString(label, xmax + offset / s[0], ymax + offset / s[1],
820  zmax + offset / s[2]);
821  }
822 }
823 
824 void drawContext::drawPlaneInBoundingBox(double xmin, double ymin, double zmin,
825  double xmax, double ymax, double zmax,
826  double a, double b, double c, double d,
827  int shade)
828 {
829  plane pl(a, b, c, d);
830  point p1(xmin, ymin, zmin), p2(xmax, ymin, zmin);
831  point p3(xmax, ymax, zmin), p4(xmin, ymax, zmin);
832  point p5(xmin, ymin, zmax), p6(xmax, ymin, zmax);
833  point p7(xmax, ymax, zmax), p8(xmin, ymax, zmax);
834 
835  point edge[12];
836  edge[0] = pl.intersect(p1, p2);
837  edge[1] = pl.intersect(p1, p4);
838  edge[2] = pl.intersect(p1, p5);
839  edge[3] = pl.intersect(p2, p3);
840  edge[4] = pl.intersect(p2, p6);
841  edge[5] = pl.intersect(p3, p4);
842  edge[6] = pl.intersect(p3, p7);
843  edge[7] = pl.intersect(p4, p8);
844  edge[8] = pl.intersect(p5, p6);
845  edge[9] = pl.intersect(p5, p8);
846  edge[10] = pl.intersect(p6, p7);
847  edge[11] = pl.intersect(p7, p8);
848 
849  int face[6][4] = {{0, 2, 4, 8}, {0, 1, 3, 5}, {1, 2, 7, 9},
850  {3, 4, 6, 10}, {5, 6, 7, 11}, {8, 9, 10, 11}};
851 
852  double n[3] = {a, b, c}, ll = 50;
853  norme(n);
854  if(CTX::instance()->arrowRelStemRadius)
856  n[0] *= ll * pixel_equiv_x / s[0];
857  n[1] *= ll * pixel_equiv_x / s[1];
858  n[2] *= ll * pixel_equiv_x / s[2];
859  double length = sqrt(n[0] * n[0] + n[1] * n[1] + n[2] * n[2]);
860 
861  int n_shade = 0;
862  point p_shade[24];
863 
864  for(int i = 0; i < 6; i++) {
865  int nb = 0;
866  point p[4];
867  for(int j = 0; j < 4; j++) {
868  if(edge[face[i][j]].valid == true) p[nb++] = edge[face[i][j]];
869  }
870  if(nb > 1) {
871  for(int j = 1; j < nb; j++) {
872  double xx[2] = {p[j].x, p[j - 1].x};
873  double yy[2] = {p[j].y, p[j - 1].y};
874  double zz[2] = {p[j].z, p[j - 1].z};
875  drawCylinder(CTX::instance()->lineWidth, xx, yy, zz, 1);
876  }
877  for(int j = 0; j < nb; j++) {
878  drawArrow3d(p[j].x, p[j].y, p[j].z, n[0], n[1], n[2], length, 1);
879  if(shade) {
880  p_shade[n_shade].x = p[j].x;
881  p_shade[n_shade].y = p[j].y;
882  p_shade[n_shade].z = p[j].z;
883  n_shade++;
884  }
885  }
886  }
887  }
888 
889  if(shade) {
890  // disable two-side lighting beacuse polygon can overlap itself
891  GLboolean twoside;
892  glGetBooleanv(GL_LIGHT_MODEL_TWO_SIDE, &twoside);
893  glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
894  glEnable(GL_LIGHTING);
895  glBegin(GL_POLYGON);
896  glNormal3d(n[0], n[1], n[2]);
897  for(int j = 0; j < n_shade; j++) {
898  glVertex3d(p_shade[j].x, p_shade[j].y, p_shade[j].z);
899  }
900  glEnd();
901  glDisable(GL_LIGHTING);
902  glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, twoside);
903  }
904 }
drawContext::pixel_equiv_y
double pixel_equiv_y
Definition: drawContext.h:141
CTX::texAsEquation
int texAsEquation
Definition: Context.h:343
gl2ps.h
drawContext::highResolutionPixelFactor
double highResolutionPixelFactor()
Definition: drawContext.cpp:73
drawContext::viewport2World
void viewport2World(double vp[3], double xyz[3])
Definition: drawContext.cpp:861
drawContext::generateTextureForImage
bool generateTextureForImage(const std::string &name, int page, GLuint &imageTexture, GLuint &imageW, GLuint &imageH)
Definition: drawContext.cpp:402
CTX::epsQuality
int epsQuality
Definition: Context.h:339
GL2PS_TEXT_BR
#define GL2PS_TEXT_BR
Definition: gl2ps.h:173
CTX::fileFormat
int fileFormat
Definition: Context.h:319
drawContext::drawStringCenter
void drawStringCenter(const std::string &s, double x, double y, double z, int line_num=0)
Definition: drawGlyph.cpp:147
Msg::Debug
static void Debug(const char *fmt,...)
Definition: GmshMessage.cpp:752
GL2PS_TEXT_CL
#define GL2PS_TEXT_CL
Definition: gl2ps.h:169
c
static double c(int i, int j, fullMatrix< double > &CA, const std::vector< SPoint3 > &P, const std::vector< SPoint3 > &Q)
Definition: discreteFrechetDistance.cpp:15
drawContext::_imageTextures
std::map< std::string, imgtex > _imageTextures
Definition: drawContext.h:130
Msg::Warning
static void Warning(const char *fmt,...)
Definition: GmshMessage.cpp:543
drawContext::_quadric
GLUquadricObj * _quadric
Definition: drawContext.h:124
drawContextGlobal::getFontName
virtual const char * getFontName(int index)
Definition: drawContext.h:101
drawContext::drawString
void drawString(const std::string &s, double x, double y, double z, const std::string &font_name, int font_enum, int font_size, int align, int line_num=0)
Definition: drawGlyph.cpp:16
GL2PS_TEXT_BL
#define GL2PS_TEXT_BL
Definition: gl2ps.h:172
LegendrePolynomials::f
void f(int n, double u, double *val)
Definition: orthogonalBasis.cpp:77
imgtex::w
GLuint w
Definition: drawContext.h:116
drawContextGlobal::setFont
virtual void setFont(int fontid, int fontsize)
Definition: drawContext.h:104
point::point
point(double *x, double *y, double *z, int numNodes=0)
Definition: shapeFunctions.h:307
SVector3.h
CTX::text
int text
Definition: Context.h:343
SanitizeTeXString
std::string SanitizeTeXString(const char *in, int equation)
Definition: StringUtils.cpp:39
drawContext::drawVector
void drawVector(int Type, int Fill, double x, double y, double z, double dx, double dy, double dz, int light)
Definition: drawGlyph.cpp:714
FORMAT_PS
#define FORMAT_PS
Definition: GmshDefines.h:13
drawContext::global
static drawContextGlobal * global()
Definition: drawContext.cpp:85
drawContext::drawEllipsoid
void drawEllipsoid(double x, double y, double z, float v0[3], float v1[3], float v2[3], int light)
Definition: drawGlyph.cpp:428
drawContext::s
double s[3]
Definition: drawContext.h:135
drawContext::drawTaperedCylinder
void drawTaperedCylinder(double width, double val1, double val2, double ValMin, double ValMax, double *x, double *y, double *z, int light)
Definition: drawGlyph.cpp:455
drawContext::drawPlaneInBoundingBox
void drawPlaneInBoundingBox(double xmin, double ymin, double zmin, double xmax, double ymax, double zmax, double a, double b, double c, double d, int shade=0)
Definition: drawGlyph.cpp:824
CTX::bg
unsigned int bg
Definition: Context.h:358
FORMAT_PDF
#define FORMAT_PDF
Definition: GmshDefines.h:30
CTX::instance
static CTX * instance()
Definition: Context.cpp:122
FixRelativePath
std::string FixRelativePath(const std::string &reference, const std::string &in)
Definition: StringUtils.cpp:77
FORMAT_SVG
#define FORMAT_SVG
Definition: GmshDefines.h:35
gl2psTextOpt
GL2PSDLL_API GLint gl2psTextOpt(const char *str, const char *fontname, GLshort fontsize, GLint alignment, GLfloat angle)
Definition: gl2ps.cpp:6315
drawContext::drawStringRight
void drawStringRight(const std::string &s, double x, double y, double z, int line_num=0)
Definition: drawGlyph.cpp:154
intersect
static int intersect(PolyMesh::Vertex *v0, PolyMesh::Vertex *v1, PolyMesh::Vertex *b0, PolyMesh::Vertex *b1)
Definition: meshTriangulation.cpp:416
Numeric.h
GL2PS_TEXT_T
#define GL2PS_TEXT_T
Definition: gl2ps.h:174
GL2PS_TEXT_CR
#define GL2PS_TEXT_CR
Definition: gl2ps.h:170
imgtex::h
GLuint h
Definition: drawContext.h:116
GmshDefines.h
prosca
double prosca(double const a[3], double const b[3])
Definition: Numeric.h:112
drawSimpleVector
static void drawSimpleVector(int arrow, int fill, double x, double y, double z, double dx, double dy, double dz, double d, int light)
Definition: drawGlyph.cpp:522
drawContext::_displayLists
GLuint _displayLists
Definition: drawContext.h:125
FORMAT_TIKZ
#define FORMAT_TIKZ
Definition: GmshDefines.h:54
CTX::arrowRelStemRadius
double arrowRelStemRadius
Definition: Context.h:288
prodve
void prodve(double a[3], double b[3], double c[3])
Definition: Numeric.h:105
drawContext::drawBox
void drawBox(double xmin, double ymin, double zmin, double xmax, double ymax, double zmax, bool labels=true)
Definition: drawGlyph.cpp:787
GL2PS_TEXT_TL
#define GL2PS_TEXT_TL
Definition: gl2ps.h:175
CTX::print
struct CTX::@2 print
length
double length(Quaternion &q)
Definition: Camera.cpp:346
StringUtils.h
drawContextGlobal::getStringHeight
virtual int getStringHeight()
Definition: drawContext.h:106
drawContextGlobal::getStringWidth
virtual double getStringWidth(const char *str)
Definition: drawContext.h:105
FORMAT_EPS
#define FORMAT_EPS
Definition: GmshDefines.h:26
CTX::arrowRelHeadRadius
double arrowRelHeadRadius
Definition: Context.h:288
Context.h
drawContext::drawArrow3d
void drawArrow3d(double x, double y, double z, double dx, double dy, double dz, double length, int light)
Definition: drawGlyph.cpp:689
gl2psText
GL2PSDLL_API GLint gl2psText(const char *str, const char *fontname, GLshort fontsize)
Definition: gl2ps.cpp:6321
z
const double z
Definition: GaussQuadratureQuad.cpp:56
FORMAT_TEX
#define FORMAT_TEX
Definition: GmshDefines.h:24
drawContext::viewport
int viewport[4]
Definition: drawContext.h:137
CTX::glFontSize
int glFontSize
Definition: Context.h:267
myacos
double myacos(double a)
Definition: Numeric.cpp:28
GL2PS_TEXT_TR
#define GL2PS_TEXT_TR
Definition: gl2ps.h:176
GL2PS_TEXT_C
#define GL2PS_TEXT_C
Definition: gl2ps.h:168
normal3points
void normal3points(double x0, double y0, double z0, double x1, double y1, double z1, double x2, double y2, double z2, double n[3])
Definition: Numeric.cpp:76
drawContextGlobal::getFontEnum
virtual int getFontEnum(int index)
Definition: drawContext.h:100
drawContext::drawCylinder
void drawCylinder(double width, double *x, double *y, double *z, int light)
Definition: drawGlyph.cpp:490
drawContext::pixel_equiv_x
double pixel_equiv_x
Definition: drawContext.h:141
GModel.h
imgtex
Definition: drawContext.h:114
drawContextGlobal::drawString
virtual void drawString(const char *str)
Definition: drawContext.h:108
CTX::lineWidth
double lineWidth
Definition: Context.h:271
norme
double norme(double a[3])
Definition: Numeric.h:123
drawContext::drawImage
void drawImage(const std::string &s, double x, double y, double z, int align=0)
Definition: drawGlyph.cpp:180
imgtex::tex
GLuint tex
Definition: drawContext.h:116
GL2PS_TEXT_B
#define GL2PS_TEXT_B
Definition: gl2ps.h:171
drawContext::drawSphere
void drawSphere(double R, double x, double y, double z, int n1, int n2, int light)
Definition: drawGlyph.cpp:390
drawContext::drawEllipse
void drawEllipse(double x, double y, double z, float v0[3], float v1[3], int light)
Definition: drawGlyph.cpp:401
drawContext::drawCube
void drawCube(double x, double y, double z, double val[9], int light)
Definition: drawGlyph.cpp:316
GModel::current
static GModel * current(int index=-1)
Definition: GModel.cpp:136
CTX::arrowRelStemLength
double arrowRelStemLength
Definition: Context.h:288
drawContext.h