Basilisk CFD
Adaptive Cartesian mesh PDE framework
Loading...
Searching...
No Matches
draw.h
Go to the documentation of this file.
1/** @file draw.h
2 */
3/**
4# Drawing functions for [Basilisk View](view.h)
5*/
6
7#include <ctype.h>
8#include "fractions.h"
9#include "gl/font.h"
10
11/**
12# *clear()*: removes all objects previously drawn */
13
14void clear()
15{
16 bview * view = get_view();
17 if (view->active)
18 view->active = false;
19 draw();
20}
21
22/**
23# *view()*: sets up viewing parameters
24
25* *tx*, *ty*: shifts the camera center point.
26* *fov*: changes the field-of-view.
27* *quat[]*: the quaternion defining the camera angles.
28* *sx*, *sy*, *sz*: stretch factors for each axis.
29* *width*, *height*, *samples*: the width and height (in pixels) of
30 the image to render (default is 800 x 800). The image can optionally
31 be generated by first rendering an image with *samples* times more
32 pixels in each direction followed by subsampling. This provides a
33 form of
34 [antialiasing](https://en.wikipedia.org/wiki/Spatial_anti-aliasing). Default
35 is four samples.
36* *bg[]*: an array of red, green, blue values between 0 and 1 which
37 defines the background color.
38* *theta*, *phi*, *psi*: [Euler-like
39 angles](https://en.wikipedia.org/wiki/Euler_angles) (in radians),
40 used (instead of *quat[]*) to define the camera angle.
41* *relative*: whether the *theta* and *phi* angles are absolute or
42 relative to the current position (i.e. increments of the current
43 angles).
44* *tz*, *near*, *far*: an alternative way of specifying the camera,
45 compatible with the camera parameters in interactive Basilisk View.
46* *camera*: predefined camera angles: "left", "right", "top",
47 "bottom", "front", "back" and "iso".
48* *map*: an optional coordinate mapping function.
49* *cache*: the maximum number of cached compiled expressions.
50*/
51
52void view (float tx = 0., float ty = 0.,
53 float fov = 0.,
54 float quat[4] = {0},
55 float sx = 1., float sy = 1., float sz = 1.,
56 unsigned width = 800, unsigned height = 800, unsigned samples = 4,
57 float bg[3] = {0},
58 float theta = 0., float phi = 0., float psi = 0.,
59 bool relative = false,
60 float tz = 0., float near = 0., float far = 0.,
61 float res = 0.,
62 char * camera = NULL,
63 MapFunc map = NULL,
64 int cache = 0,
65 float p1x = 0., float p1y = 0., float p2x = 0., float p2y = 0.,
66 bview * view1 = NULL)
67{
68 bview * v = view1 ? view1 : get_view();
69 if (fov) {
70 if (relative)
71 v->fov += (0.1 + 3.*v->fov)*fov;
72 else
73 v->fov = fov;
74 v->fov = clamp(v->fov,0.01,100.);
75 }
76 for (int i = 0; i < 4; i++)
77 if (quat[i]) {
78 for (int j = 0; j < 4; j++)
79 v->quat[j] = quat[j];
80 break;
81 }
82 v->tx = relative ? v->tx + tx*0.02*(0.01 + 3.*v->fov) : tx;
83 v->ty = relative ? v->ty + ty*0.02*(0.01 + 3.*v->fov) : ty;
84 v->sx = sx;
85 v->sy = sy;
86 v->sz = sz;
87 if (bg[0] || bg[1] || bg[2])
88 for (int i = 0; i < 3; i++)
89 v->bg[i] = bg[i];
90
91 if (camera) {
92 v->gfsview = false;
93 if (strlen(camera) >= 4 &&
94 !strcmp (&camera[strlen(camera) - 4], ".gfv")) {
95 FILE * fp = fopen (camera, "r");
96 if (!fp) {
97 perror (camera);
98 exit (1);
99 }
100 char s[81];
101 float q[4], fov;
102 int nq = 0, nf = 0;
103 while (fgets (s, 81, fp) && (!nq || !nf)) {
104 if (!nq)
105 nq = sscanf (s, " q0 = %f q1 = %f q2 = %f q3 = %f",
106 &q[0], &q[1], &q[2], &q[3]);
107 if (!nf)
108 nf = sscanf (s, " fov = %f", &fov);
109 }
110 if (nq != 4 || nf != 1) {
111 fprintf (stderr, "%s: not a valid gfv file\n", camera);
112 exit (1);
113 }
114 for (int j = 0; j < 4; j++)
115 v->quat[j] = q[j];
116 v->fov = fov;
117 v->gfsview = true;
118 }
119 else if (!strcmp (camera, "left"))
120 gl_axis_to_quat ((float[]){0,1,0}, - pi/2., v->quat);
121 else if (!strcmp (camera, "right"))
122 gl_axis_to_quat ((float[]){0,1,0}, pi/2., v->quat);
123 else if (!strcmp (camera, "top"))
124 gl_axis_to_quat ((float[]){1,0,0}, - pi/2., v->quat);
125 else if (!strcmp (camera, "bottom"))
126 gl_axis_to_quat ((float[]){1,0,0}, pi/2., v->quat);
127 else if (!strcmp (camera, "front"))
128 gl_axis_to_quat ((float[]){0,0,1}, 0., v->quat);
129 else if (!strcmp (camera, "back"))
130 gl_axis_to_quat ((float[]){0,1,0}, pi, v->quat);
131 else if (!strcmp (camera, "iso")) {
132 gl_axis_to_quat ((float[]){0,1,0}, pi/4., v->quat);
133 float q[4];
134 gl_axis_to_quat ((float[]){1,0,0}, - pi/4., q);
135 gl_add_quats(q, v->quat, v->quat);
136 }
137 else {
138 fprintf (stderr, "view(): unknown camera '%s'\n", camera);
139 exit (1);
140 }
141 }
142 else if (theta || phi || psi) {
143 v->gfsview = false;
144 float q[4];
145 gl_axis_to_quat ((float[]){1,0,0}, - phi, q);
146 if (relative) {
147 float q1[4];
148 gl_axis_to_quat ((float[]){0,1,0}, theta, q1);
149 gl_add_quats(q, q1, q1);
150 float q2[4];
151 gl_axis_to_quat ((float[]){0,0,1}, psi, q2);
152 gl_add_quats(q1, q2, q2);
153 gl_add_quats(q2, v->quat, v->quat);
154 }
155 else {
156 gl_axis_to_quat ((float[]){0,1,0}, theta, v->quat);
157 gl_add_quats(q, v->quat, v->quat);
158 gl_axis_to_quat ((float[]){0,0,1}, psi, q);
159 gl_add_quats(q, v->quat, v->quat);
160 }
161 }
162
163 if (map)
164 v->map = map;
165
166 if (p1x || p1y || p2x || p2y) { // trackball
167 float q[4];
169 gl_add_quats (q, v->quat, v->quat);
170 }
171
172 if (far > near) {
173 v->tz = tz;
174 v->far = far;
175 v->near = near;
176 }
177
178 if (res)
179 v->res = res;
180
181 if ((width && width != v->width) ||
182 (height && height != v->height) ||
183 (samples && samples != v->samples)) {
184 v->width = v->width/v->samples;
185 v->height = v->height/v->samples;
186 if (width) v->width = width;
187 if (height) v->height = height;
188 if (samples) v->samples = samples;
189 v->width *= v->samples;
190 v->height *= v->samples;
192
193 /* OpenGL somehow generates floating-point exceptions... turn them off */
195
196 v->fb = framebuffer_new (v->width, v->height);
197 init_gl();
198
200 }
201
202 if (cache > 0) {
203 v->cache = calloc (1, sizeof (cexpr));
204 v->maxlen = cache;
205 }
206
207 clear();
208}
209
210/**
211# *translate()*: translates the origin.
212
213The block following this command will be drawn in a translated
214coordinate system. */
215
216macro translate (float x = 0, float y = 0., float z = 0.)
217{
218 {
219 bview * _view = draw();
221 glPushMatrix();
222 glTranslatef (x, y, z);
224
225 {...}
226
228 glPopMatrix();
230 }
231}
232
233/**
234# *mirror()*: symmetry relative to a plane.
235
236The block following this command will be drawn in a coordinate system
237symmetric relative to the given plane. The plane is given by \f$n\f$ and
238\f$\alpha\f$ as explained in
239[squares()](#squares-displays-colormapped-fields). */
240
241macro mirror (coord n = {0}, double alpha = 0.)
242{
243 {
244 bview * _view = draw();
245 {
247 glPushMatrix();
248 coord m = n;
249 normalize (&m);
250 GLfloat s[16], t[16];
251 s[0] = 1. - 2.*m.x*m.x;
252 s[1] = - 2.*m.x*m.y; s[2] = - 2.*m.x*m.z;
253 s[3] = 0.;
254 s[4] = s[1];
255 s[5] = 1. - 2.*m.y*m.y; s[6] = - 2.*m.y*m.z;
256 s[7] = 0.;
257 s[8] = s[2]; s[9] = s[6]; s[10] = 1. - 2.*m.z*m.z;
258 s[11] = 0.;
259 s[12] = 0.; s[13] = 0.; s[14] = 0.;
260 s[15] = 1.;
261
262 t[0] = 1.; t[1] = 0.; t[2] = 0.; t[3] = 0.;
263 t[4] = 0.; t[5] = 1.; t[6] = 0.; t[7] = 0.;
264 t[8] = 0.; t[9] = 0.; t[10] = 1.; t[11] = 0.;
265 t[12] = - 2.*m.x*alpha;
266 t[13] = - 2.*m.y*alpha;
267 t[14] = - 2.*m.z*alpha;
268 t[15] = 1.;
273 }
274
275 {...}
276
277 {
279 glPopMatrix();
282 }
283 }
284}
285
286/**
287# Utility functions
288
289The tree structure is used to traverse only the cells which are within
290the field of view of the camera. */
291
292static void mapped_position (bview * view, coord * p, double * r)
293{
294 double x = p->x, y = p->y, z = p->z, rm = 0.;
295 view->map (p);
296 for (int i = -1; i <= 1; i += 2)
297 for (int j = -1; j <= 1; j += 2)
298 for (int k = -1; k <= 1; k += 2) {
299 coord q = {x + i**r, y + j**r, z + k**r};
300 view->map (&q);
301 double pq = sq(p->x - q.x) + sq(p->y - q.y) + sq(p->z - q.z);
302 if (pq > rm)
303 rm = pq;
304 }
305 *r = sqrt (rm);
306}
307
309{
310 for (int _i = 0; _i < _N; _i++) /* foreach_cell */ {
312#if dimension == 2
313 double _r = Delta*0.71;
314#else // dimension == 3
315 double _r = Delta*0.87;
316#endif
317 coord _p = {x, y, z};
318 if ((view)->map)
320 if (VertexBuffer.visible &&
321 !sphere_in_frustum (_p.x, _p.y, _p.z, _r, &(view)->frustum))
322 continue;
323 if (is_leaf(cell) || point.level == (view)->maxlevel ||
324 (VertexBuffer.visible &&
325 sphere_diameter (_p.x, _p.y, _p.z, _r/L0, &(view)->frustum) < (view)->res)) {
326 if (is_active(cell) && is_local(cell))
327 {...}
328 continue;
329 }
330 }
331}
332
337
338/**
339A similar technique can be used to traverse the cells which are both
340visible and intersected by a plane defined by
341\f[
342n_x x + n_y y + n_z z = \alpha
343\f]
344*/
345
346#if dimension == 3
347static void glnormal3d (bview * view, double x, double y, double z) {
348 // fixme: mapping? (see glvertex3d)
349 if (view->gfsview || view->reversed)
350 glNormal3d (- x, - y, - z);
351 else
352 glNormal3d (x, y, z);
353}
354
356{
357 {
358 coord _n = {(n1).x, (n1).y, (n1).z};
359 double _alpha = 0.9999999*(alpha1);
360 {
361 double norm = sqrt(sq(_n.x) + sq(_n.y) + sq(_n.z));
362 if (!norm)
363 _n.z = 1.;
364 else
365 _n.x /= norm, _n.y /= norm, _n.z /= norm, _alpha /= norm;
366 }
367 glnormal3d (view, _n.x, _n.y, _n.z); // do not use normal inversion
368 for (int _i = 0; _i < _N; _i++) /* foreach_cell */ {
370 // fixme: coordinate mapping
371 double _r = Delta*0.87, alpha = (_alpha - _n.x*x - _n.y*y - _n.z*z)/Delta;
372 if (fabs(alpha) > 0.87 ||
373 (VertexBuffer.visible &&
374 !sphere_in_frustum (x, y, z, _r, &(view)->frustum)))
375 continue;
376 if (is_leaf(cell) ||
377 (VertexBuffer.visible &&
378 sphere_diameter (x, y, z, _r/L0, &(view)->frustum) < (view)->res)) {
379 if (is_active(cell) && is_local(cell))
380 {...}
381 continue;
382 }
383 }
384 }
385}
386#endif // dimension == 3
387
388macro draw_lines (bview * view, float color[3], float lw)
389{
390 {
392 glPushMatrix();
393 glTranslatef (0., 0., view->lc*view->fov/24.);
394 glColor3f (color[0], color[1], color[2]);
395 glLineWidth (view->samples*(lw > 0. ? lw : 1.));
396 bool _reversed = view->reversed;
397 view->reversed = false;
398 {...}
400 glPopMatrix();
401 view->reversed = _reversed;
402 }
403}
404
405static inline double interp (Point point, coord p, scalar col) {
407 x + p.x*Delta, y + p.y*Delta, z + p.z*Delta);
408}
409
411{
412 assert (n);
413 switch (n->type) {
414 case '1': return n->d.value;
415 case '+': return (evaluate_expression (point, n->e[0]) +
416 evaluate_expression(point, n->e[1]));
417 case '-': return (evaluate_expression (point, n->e[0]) -
418 evaluate_expression(point, n->e[1]));
419 case '*': return (evaluate_expression (point, n->e[0]) *
420 evaluate_expression(point, n->e[1]));
421 case '/': return (evaluate_expression (point, n->e[0]) /
422 evaluate_expression(point, n->e[1]));
423 case '^': return pow (evaluate_expression (point, n->e[0]),
424 evaluate_expression(point, n->e[1]));
425 case '>': return (evaluate_expression (point, n->e[0]) >
426 evaluate_expression(point, n->e[1]));
427 case '<': return (evaluate_expression (point, n->e[0]) <
428 evaluate_expression(point, n->e[1]));
429 case 'L': return (evaluate_expression (point, n->e[0]) <=
430 evaluate_expression(point, n->e[1]));
431 case 'G': return (evaluate_expression (point, n->e[0]) >=
432 evaluate_expression(point, n->e[1]));
433 case '=': return (evaluate_expression (point, n->e[0]) ==
434 evaluate_expression(point, n->e[1]));
435 case 'i': return (evaluate_expression (point, n->e[0]) !=
436 evaluate_expression(point, n->e[1]));
437 case 'O': return (evaluate_expression (point, n->e[0]) ||
438 evaluate_expression(point, n->e[1]));
439 case 'A': return (evaluate_expression (point, n->e[0]) &&
440 evaluate_expression(point, n->e[1]));
441 case '?': return (evaluate_expression (point, n->e[0]) ?
442 evaluate_expression(point, n->e[1]) :
443 evaluate_expression(point, n->e[2]));
444 case 'm': return - evaluate_expression (point, n->e[0]);
445 case 'f': return n->d.func (evaluate_expression (point, n->e[0]));
446 case 'v': {
447 scalar s = {n->s};
448 int k[3] = {0,0,0};
449 for (int i = 0; i < 3; i++)
450 if (n->e[i])
451 k[i] = evaluate_expression (point, n->e[i]);
452 return s[k[0],k[1],k[2]];
453 }
454 case 'D': return Delta;
455 case 'x': return x;
456 case 'y': return y;
457 case 'z': return z;
458 default:
459 fprintf (stderr, "unknown operation type '%c'\n", n->type);
460 assert (false);
461 }
462 return undefined;
463}
464
465static bool assemble_node (Node * n)
466{
467 if (n->type == 'v') {
468 char * id = n->d.id;
469 scalar s = lookup_field (id);
470 if (s.i >= 0)
471 n->s = s.i;
472 else {
473 n->s = -1;
474 if (!strcmp (id, "Delta"))
475 reset_node_type (n, 'D');
476 else if (!strcmp (id, "x"))
477 reset_node_type (n, 'x');
478 else if (!strcmp (id, "y"))
479 reset_node_type (n, 'y');
480 else if (!strcmp (id, "z"))
481 reset_node_type (n, 'z');
482 else {
483 typedef struct { char * name; double val; } Constant;
484 static Constant constants[] = {
485 {"pi", pi },
486 {"nodata", nodata },
487 {"HUGE", HUGE },
488 { NULL },
489 };
490 Constant * p = constants;
491 while (p->name) {
492 if (!strcmp (p->name, id)) {
493 reset_node_type (n, '1');
494 n->d.value = p->val;
495 break;
496 }
497 p++;
498 }
499 if (n->type == 'v') {
500 fprintf (stderr, "unknown identifier '%s'\n", id);
501 return false;
502 }
503 }
504 }
505 }
506 for (int i = 0; i < 3; i++)
507 if (n->e[i] && !assemble_node (n->e[i]))
508 return false;
509 return true;
510}
511
512static scalar compile_expression (char * expr, bool * isexpr)
513{
514 *isexpr = false;
515 if (!expr)
516 return (scalar){-1};
517
518 bview * view = get_view();
519 scalar s;
520 if (view->cache && (s = get_cexpr (view->cache, expr)).i >= 0)
521 return s;
522
523 Node * node = parse_node (expr);
524 if (node == NULL) {
525 fprintf (stderr, "'%s': syntax error\n", expr);
526 return (scalar){-1};
527 }
528 if (!assemble_node (node)) {
529 free_node (node);
530 return (scalar){-1};
531 }
532 if (node->type == 'v' && node->e[0] == NULL) {
533 scalar s = {node->s};
534 if (s.block > 0) {
535 free_node (node);
536 return s;
537 }
538 }
539 s = {0} /* new scalar */;
540 free (s.name);
541 s.name = strdup (expr);
542 for (int _i = 0; _i < _N; _i++) /* foreach */
544 restriction ({s});
545 free_node (node);
546
547 if (view->cache)
548 view->cache = add_cexpr (view->cache, view->maxlen, expr, s);
549 else
550 *isexpr = true;
551 return s;
552}
553
554#define colorize_args() \
555 scalar col = {-1}; \
556 if (color && strcmp (color, "level")) { \
557 col = compile_expression (color, &expr); \
558 if (col.i < 0) \
559 return false; \
560 } \
561 \
562 double cmap[NCMAP][3]; \
563 if (color) { \
564 if (min == 0 && max == 0) { \
565 if (col.i < 0) /* level */ \
566 min = 0, max = depth(); \
567 else { \
568 stats s = statsf (col); \
569 double avg = s.sum/s.volume; \
570 if (spread < 0.) \
571 min = s.min, max = s.max; \
572 else { \
573 if (!spread) spread = 5.; \
574 min = avg - spread*s.stddev; max = avg + spread*s.stddev; \
575 } \
576 } \
577 } \
578 if (!map) \
579 map = jet; \
580 (* map) (cmap); \
581 } \
582 \
583 if ((dimension > 2 || linear) && \
584 !fc[0] && !fc[1] && !fc[2]) \
585 fc[0] = fc[1] = fc[2] = 1.; \
586 \
587 if (cbar) \
588 colorbar (map, size, pos, label, lscale, min, max, \
589 horizontal, border, mid, \
590 lc, lw, fsize, format, levels);
591
592#define color_facet() \
593 if (color && (!linear || col.i < 0)) { \
594 Color b = colormap_color (cmap, col.i < 0 ? \
595 (double) level : val(col,0,0,0), \
596 min, max); \
597 glColor3f (b.r/255., b.g/255., b.b/255.); \
598 }
599
600#define color_vertex(val) \
601 if (color && linear && col.i >= 0) { \
602 if (VertexBuffer.color) { \
603 Color b = colormap_color (cmap, val, min, max); \
604 glColor3f (b.r/255., b.g/255., b.b/255.); \
605 } \
606 else { \
607 double _v = val; \
608 if (max > min) \
609 glTexCoord1d (clamp(((_v) - min)/(max - min), 0., 1.)); \
610 else \
611 glTexCoord1d (0.); \
612 } \
613 }
614
616 double cmap[NCMAP][3], bool use_texture)
617{
618 // do not use textures for vector graphics
619 if (use_texture) {
620 GLfloat texture[3*256];
621 for (int i = 0; i < 256; i++) {
622 Color j = colormap_color (cmap, i/255., 0, 1);
623 texture[3*i] = j.r/255.;
624 texture[3*i + 1] = j.g/255.;
625 texture[3*i + 2] = j.b/255.;
626 }
633 }
634 if (constant_color)
635 glColor3f (fc[0], fc[1], fc[2]);
636
637 {...}
638
640}
641
642#define colorize() colorized (fc, !VertexBuffer.color || !color, \
643 cmap, !VertexBuffer.color && \
644 color && linear && col.i >= 0)
645
646/**
647# *colorbar()*: draws a colorbar.
648
649* *map*: the colormap.
650* *size*: the size.
651* *pos*: the relative screen position (default is lower-left corner).
652* *label*: a label.
653* *lscale*: the label scale factor.
654* *min*, *max*: the range.
655* *horizontal*: true for anb horizontal colorbar.
656* *border*: adds a border.
657* *mid*: adds a mid-value label.
658* *lc*: the line color.
659* *lw*: the line width.
660* *fsize*: another size.
661* *format*: how to format numbers.
662* *levels*: the number of subdivisions.
663
664Note that this cannot be used with [jview](jview/README) (yet) because
665it mixes surface and line rendering. */
666
667trace
668bool colorbar (Colormap map = jet, float size = 15, float pos[2] = {-.95, -.95},
669 char * label = "", double lscale = 1, double min = -HUGE,
670 double max = HUGE, bool horizontal = false, bool border = false,
671 bool mid = false, float lc[3] = {0}, float lw = 3, float fsize = 50,
672 char * format = "%g", int levels = 50)
673{
674 bview * view = draw();
677 glPushMatrix();
680 glPushMatrix();
682
683 float fheight = gl_StrokeHeight();
684 if (!size)
685 size = 15;
686 float width = 2./size;
687 if (levels < 1) levels = 1;
688 float h = 0, height = 4*width, dh = height/levels;
689 glTranslatef (pos[0], pos[1], 0);
690
691 // The colorbar itself
692 double cmap [NCMAP][3];
693 (* map) (cmap);
695 for (int i = 0; i < levels; i++) {
696 Color c = colormap_color (cmap, (float)i/(levels - 1), 0, 1);
697 glColor3f (c.r/255., c.g/255., c.b/255.);
698 if (horizontal) {
699 glVertex2d (h + dh, 0);
700 glVertex2d (h + dh, width);
701 glVertex2d (h, width);
702 glVertex2d (h, 0);
703 } else {
704 glVertex2d (0, h + dh);
705 glVertex2d (width, h + dh);
706 glVertex2d (width, h);
707 glVertex2d (0, h);
708 }
709 h += dh;
710 view->ni++;
711 }
712 glEnd();
713 glLineWidth (view->samples*(lw > 0. ? lw : 1.));
714 glColor3f (lc[0], lc[1], lc[2]);
715
716 // A border around the color scale
717 if (border) {
719 glVertex2f (0, 0);
720 if (horizontal) {
721 glVertex2f (0, width);
722 glVertex2f (height, width);
723 glVertex2f (height, 0);
724 } else {
725 glVertex2f (width, 0);
726 glVertex2f (width, height);
727 glVertex2f (0, height);
728 }
729 glEnd();
730 }
731
732 // Min and max values when specified
733 float fwidth = gl_StrokeWidth ('1');
734 if (!fsize)
735 fsize = 20;
736 float hscale = 2./(fsize*fwidth), vscale = hscale*view->width/view->height;
737 char str[99];
738 glColor3f (lc[0], lc[1], lc[2]);
739 if (horizontal)
740 glTranslatef (0, -(fheight/(view->height)), 0);
741 else
742 glTranslatef (width, -(fheight/(3*view->height)), 0);
743 glScalef (hscale, vscale, 1.);
744 sprintf (str, format, min);
745 if (min > -HUGE) {
746 glPushMatrix();
747 if (horizontal)
748 glTranslatef (-fwidth*(strlen(str) - 1)/2, 0, 0);
749 glScalef (lscale, lscale, 1.);
751 glPopMatrix();
752 }
753 if (horizontal)
755 else
756 glTranslatef (0, height/vscale, 0);
757 sprintf (str, format, max);
758 if (max < HUGE) {
759 glPushMatrix();
760 if (horizontal)
761 glTranslatef (-fwidth*(strlen(str) - 1)/2, 0, 0);
762 glScalef (lscale, lscale, 1.);
764 glPopMatrix();
765 }
766 // Add central value
767 if (mid) {
768 sprintf (str, format, (min + max)/2);
769 glPushMatrix();
770 if (horizontal)
771 glTranslatef (-height/(2*hscale) - fwidth*(strlen(str) - 1)/2,0, 0);
772 else
773 glTranslatef (0, -height/(2*vscale), 0);
774 glScalef (lscale, lscale, 1.);
776 glPopMatrix();
777 }
778 // Add label
779 if (horizontal)
780 glTranslatef (-height/(2*hscale) - lscale*fwidth*(strlen(label) - 1)/2, width/vscale, 0);
781 else
782 glTranslatef (-width/hscale, 0, 0);
783
784 glScalef (lscale, lscale, 1.);
785 glTranslatef (0, fheight, 0);
787
789 glPopMatrix();
791 glPopMatrix();
792 return true;
793}
794
795/**
796Parameters for an (optional) [colorbar](#colorbar). */
797
798#define COLORBAR_PARAMS \
799 bool cbar = false, \
800 float size = 15, float pos[2] = {-.95, -.95}, \
801 char * label = "", double lscale = 1, \
802 bool horizontal = false, bool border = false, \
803 bool mid = false, float fsize = 50, \
804 char * format = "%g", int levels = 50
805
806/**
807The somewhat complicated function below checks whether an interface
808fragment is present within a given cell. The interface is defined by
809the volume fraction field *c*. *cmin* is the threshold below which a
810fragment is considered too small. */
811
812static bool cfilter (Point point, scalar c, double cmin)
813{
814 double cmin1 = 4.*cmin;
815 if (c[] <= cmin) {
816 for (int _d = 0; _d < dimension; _d++)
817 if (c[1] >= 1. - cmin1 || c[-1] >= 1. - cmin1)
818 return true;
819 return false;
820 }
821 if (c[] >= 1. - cmin) {
822 for (int _d = 0; _d < dimension; _d++)
823 if (c[1] <= cmin1 || c[-1] <= cmin1)
824 return true;
825 return false;
826 }
827 int n = 0;
828 double min = HUGE, max = - HUGE;
829 for (int _n = 0; _n < 1; _n++) {
830 if (c[] > cmin && c[] < 1. - cmin && ++n >= (1 << dimension))
831 return true;
832 if (c[] > max) max = c[];
833 if (c[] < min) min = c[];
834 }
835 return max - min > 0.5;
836}
837
838static void glvertex3d (bview * view, double x, double y, double z) {
839 if (view->map) {
840 coord p = {x, y, z};
841 view->map (&p);
842 glVertex3d (p.x, p.y, p.z);
843 }
844 else
845 glVertex3d (x, y, z);
846}
847
848#if dimension <= 2
849static void glvertex2d (bview * view, double x, double y) {
850 if (view->map) {
851 coord p = {x, y, 0.};
852 view->map (&p);
853 glVertex2d (p.x, p.y);
854 }
855 else
856 glVertex2d (x, y);
857}
858
860 double xp, double yp, double zp)
861{
862 coord v = {(xp - x)/Delta, (yp - y)/Delta}, np;
863 for (int _d = 0; _d < dimension; _d++)
864 np.x = - interp (point, v, n.x);
865 glNormal3d (np.x, np.y, 1.);
866 glvertex3d (view, xp, yp, zp);
867}
868#endif // dimension <= 2
869
870/**
871# *draw_vof()*: displays VOF-reconstructed interfaces
872
873* *c*: the name (as a string) of the Volume-Of-Fluid field.
874* *s*: the (optional) name of the face fraction field.
875* *edges*: whether to display the edges or the facets.
876* *larger*: makes each cell larger by this factor. This helps close
877 the gaps in the VOF interface representation. Default is 1.1 in 3D
878 and when edges are not displayed, otherwise it is 1.
879* *filled*: in 2D, whether to fill the inside (1) or outside (-1).
880* *color*: use this field to color each interface fragment.
881* *min*, *max*: the minimum and maximum values to use for color mapping.
882* *spread*: the "spread factor" to use if *min* and *max* are not
883 defined. The maximum and minimum values will be taken as the average
884 plus or minus *spread* times the standard deviation. Default is 5. If
885 negative, the minimum and maximum values of the field are used.
886* *linear*: if *true* the color will be linearly interpolated for each
887 vertex of the facet.
888* *map*: the colormap to use. Default is *jet*.
889* *fc[]*: an array of red, green, blue values between 0 and 1 which
890 defines the facet color.
891* *lc[]*: an array of red, green, blue values between 0 and 1 which
892 defines the line color.
893* *lw*: the line width.
894*/
895
896trace
897bool draw_vof (char * c, char * s = NULL, bool edges = false,
898 double larger = 0., int filled = 0,
899 char * color = NULL,
900 double min = 0, double max = 0, double spread = 0,
901 bool linear = false,
902 Colormap map = jet,
903 float fc[3] = {0}, float lc[3] = {0}, float lw = 1.,
904 bool expr = false,
906{
908 if (d.i < 0) {
909 fprintf (stderr, "draw_vof(): no field named '%s'\n", c);
910 return false;
911 }
913
915
916 double cmin = 1e-3; // do not reconstruct fragments smaller than this
917
918#if TREE
919 // make sure we prolongate properly
920 void (* prolongation) (Point, scalar) = d.prolongation;
921 if (prolongation != fraction_refine)
923#endif // TREE
924
925 bview * view = draw();
926#if dimension == 2
927 if (filled) {
928 glColor3f (fc[0], fc[1], fc[2]);
929 glNormal3d (0, 0, view->reversed ? -1 : 1);
931 if ((filled > 0 && d[] >= 1.) || (filled < 0 && d[] <= 0.)) {
933 glvertex2d (view, x - Delta_x/2., y - Delta_y/2.);
934 glvertex2d (view, x + Delta_x/2., y - Delta_y/2.);
935 glvertex2d (view, x + Delta_x/2., y + Delta_y/2.);
936 glvertex2d (view, x - Delta_x/2., y + Delta_y/2.);
937 glEnd();
938 view->ni++;
939 }
940 else if (d[] > 0. && d[] < 1.) {
941 coord n = facet_normal (point, d, fs), r = {1.,1.};
942 if (filled < 0)
943 for (int _d = 0; _d < dimension; _d++)
944 n.x = - n.x;
945 double alpha = plane_alpha (filled < 0. ? 1. - d[] : d[], n);
946 alpha += (n.x + n.y)/2.;
947 for (int _d = 0; _d < dimension; _d++)
948 if (n.x < 0.) alpha -= n.x, n.x = - n.x, r.x = - 1.;
949 coord v[5];
950 int nv = 0;
951 if (alpha >= 0. && alpha <= n.x) {
952 v[nv].x = alpha/n.x, v[nv++].y = 0.;
953 if (alpha <= n.y)
954 v[nv].x = 0., v[nv++].y = alpha/n.y;
955 else if (alpha >= n.y && alpha - n.y <= n.x) {
956 v[nv].x = (alpha - n.y)/n.x, v[nv++].y = 1.;
957 v[nv].x = 0., v[nv++].y = 1.;
958 }
959 v[nv].x = 0., v[nv++].y = 0.;
960 }
961 else if (alpha >= n.x && alpha - n.x <= n.y) {
962 v[nv].x = 1., v[nv++].y = (alpha - n.x)/n.y;
963 if (alpha >= n.y && alpha - n.y <= n.x) {
964 v[nv].x = (alpha - n.y)/n.x, v[nv++].y = 1.;
965 v[nv].x = 0., v[nv++].y = 1.;
966 }
967 else if (alpha <= n.y)
968 v[nv].x = 0., v[nv++].y = alpha/n.y;
969 v[nv].x = 0., v[nv++].y = 0.;
970 v[nv].x = 1., v[nv++].y = 0.;
971 }
973 if (r.x*r.y < 0.)
974 for (int i = nv - 1; i >= 0; i--)
975 glvertex2d (view, x + r.x*(v[i].x - 0.5)*Delta,
976 y + r.y*(v[i].y - 0.5)*Delta);
977 else
978 for (int i = 0; i < nv; i++)
979 glvertex2d (view, x + r.x*(v[i].x - 0.5)*Delta,
980 y + r.y*(v[i].y - 0.5)*Delta);
981 glEnd ();
982 view->ni++;
983 }
984 }
985 }
986 else // !filled
987 draw_lines (view, lc, lw) {
990 if (cfilter (point, d, cmin)) {
992 double alpha = plane_alpha (d[], n);
993 coord segment[2];
994 if (facets (n, alpha, segment) == 2) {
995 glvertex2d (view, x + segment[0].x*Delta, y + segment[0].y*Delta);
996 glvertex2d (view, x + segment[1].x*Delta, y + segment[1].y*Delta);
997 view->ni++;
998 }
999 }
1000 glEnd ();
1001 }
1002#else // dimension == 3
1003 if (!larger)
1004 larger = edges || (color && !linear) ? 1. : 1.1;
1005 if (edges)
1006 draw_lines (view, lc, lw) {
1008 if (cfilter (point, d, cmin)) {
1009 coord n = facet_normal (point, d, fs);
1010 double alpha = plane_alpha (d[], n);
1011 coord v[12];
1012 int m = facets (n, alpha, v, larger);
1013 if (m > 2) {
1015 for (int i = 0; i < m; i++)
1017 x + v[i].x*Delta, y + v[i].y*Delta, z + v[i].z*Delta);
1018 glEnd ();
1019 view->ni++;
1020 }
1021 }
1022 }
1023 else // !edges
1024 colorize() {
1026 if (cfilter (point, d, cmin)) {
1027 coord n = facet_normal (point, d, fs);
1028 double alpha = plane_alpha (d[], n);
1029 coord v[12];
1030 int m = facets (n, alpha, v, larger);
1031 if (m > 2) {
1033 for (int i = 0; i < m; i++) {
1034 if (linear) {
1035 color_vertex (interp (point, v[i], col));
1036 }
1037 else {
1038 color_facet();
1039 }
1040 glnormal3d (view, n.x, n.y, n.z);
1042 x + v[i].x*Delta, y + v[i].y*Delta, z + v[i].z*Delta);
1043 }
1044 glEnd ();
1045 view->ni++;
1046 }
1047 }
1048 }
1049#endif // dimension == 3
1050
1051#if TREE
1052 // revert prolongation
1053 if (prolongation != fraction_refine)
1054 set_prolongation (d, prolongation);
1055#endif // TREE
1056
1057 if (expr) delete({col});
1058 return true;
1059}
1060
1061/**
1062# *isoline()*: displays isolines
1063
1064Draws a single isoline at *val* of field *phi*, or *n* isolines
1065between *min* and *max* (included).
1066
1067Extra parameters are the same as for
1068[draw_vof()](draw.h#draw_vof-displays-vof-reconstructed-interfaces). */
1069
1070trace
1071bool isoline (char * phi,
1072 double val = 0.,
1073 int n = 1,
1074 bool edges = false,
1075 double larger = 0., int filled = 0,
1076 char * color = NULL,
1077 double min = 0, double max = 0, double spread = 0,
1078 bool linear = false,
1079 Colormap map = jet,
1080 float fc[3] = {0}, float lc[3] = {0}, float lw = 1.,
1081 bool expr = false,
1083{
1084#if dimension == 2
1085 if (!color) color = phi;
1086 colorize_args();
1087 scalar fphi = col, fiso[];
1088 if (!is_vertex_scalar (col)) {
1089 fphi = {0} /* new scalar */;
1090 for (int _i = 0; _i < _N; _i++) /* foreach_vertex */
1091 fphi[] = (col[] + col[-1] + col[0,-1] + col[-1,-1])/4.;
1092 }
1093 vector siso[];
1094 if (n < 2) {
1095 fractions (fphi, fiso, siso, val);
1096 draw_vof ("fiso", "siso", edges, larger, filled, color, min, max, spread,
1097 linear, map, fc, lc, lw, expr);
1098 }
1099 else if (max > min) {
1100 double dv = (max - min)/(n - 1);
1101 for (val = min; val <= max; val += dv) {
1102 fractions (fphi, fiso, siso, val);
1103 draw_vof ("fiso", "siso", edges, larger, filled, color, min, max, spread,
1104 linear, map, fc, lc, lw, expr);
1105 }
1106 }
1107 if (!is_vertex_scalar (col))
1108 delete ({fphi});
1109 if (expr) delete ({col});
1110#else // dimension == 3
1111 assert (false);
1112#endif // dimension == 3
1113 return true;
1114}
1115
1116/**
1117# *cells()*: displays grid cells
1118
1119In 3D the intersections of the cells with a plane are displayed. The
1120default plane is \f$z=0\f$. This can be changed by setting *n* and *alpha*
1121which define the plane
1122\f[
1123n_x x + n_y y + n_z z = \alpha
1124\f]
1125*/
1126
1127trace
1128bool cells (coord n = {0,0,1}, double alpha = 0.,
1129 float lc[3] = {0}, float lw = 1.)
1130{
1131 bview * view = draw();
1132 draw_lines (view, lc, lw) {
1133#if dimension == 2
1136 glvertex2d (view, x - Delta_x/2., y - Delta_y/2.);
1137 glvertex2d (view, x + Delta_x/2., y - Delta_y/2.);
1138 glvertex2d (view, x + Delta_x/2., y + Delta_y/2.);
1139 glvertex2d (view, x - Delta_x/2., y + Delta_y/2.);
1140 glEnd();
1141 view->ni++;
1142 }
1143#else // dimension == 3
1145 coord v[12];
1146 int m = facets (n, alpha, v, 1.);
1147 if (m > 2) {
1149 for (int i = 0; i < m; i++)
1150 glvertex3d (view, x + v[i].x*Delta, y + v[i].y*Delta, z + v[i].z*Delta);
1151 glEnd ();
1152 view->ni++;
1153 }
1154 }
1155#endif // dimension == 3
1156 }
1157 return true;
1158}
1159
1160/**
1161# *vectors()*: displays vector fields
1162
1163The vectors are scaled using the *scale* factor. */
1164
1165trace
1166bool vectors (char * u, double scale = 1, float lc[3] = {0}, float lw = 1., int level = -1)
1167{
1168#if dimension == 2
1169 vector fu;
1170 struct { char x, y, z; } index = {'x', 'y', 'z'};
1171 for (int _d = 0; _d < dimension; _d++) {
1172 char name[80];
1173 sprintf (name, "%s.%c", u, index.x);
1174 fu.x = lookup_field (name);
1175 if (fu.x.i < 0) {
1176 fprintf (stderr, "vectors(): no field named '%s'\n", name);
1177 return false;
1178 }
1179 }
1180 bview * view = draw();
1181 float res = view->res;
1182 if (view->res < 15*view->samples)
1183 view->res = 15*view->samples;
1184 int maxlevel = view->maxlevel;
1185 view->maxlevel = level;
1186 draw_lines (view, lc, lw) {
1187 double fscale = (scale ? scale : 1.)*view->res/view->samples;
1188 glBegin (GL_LINES);
1190 if (fu.x[] != nodata) {
1191 coord f = { fscale*fu.x[], fscale*fu.y[] };
1192 glvertex2d (view, x + f.x - (f.x - f.y/2.)/5.,
1193 y + f.y - (f.x/2. + f.y)/5.);
1194 glvertex2d (view, x + f.x, y + f.y);
1195 glvertex2d (view, x + f.x, y + f.y);
1196 glvertex2d (view, x + f.x - (f.x + f.y/2.)/5.,
1197 y + f.y + (f.x/2. - f.y)/5.);
1198 glvertex2d (view, x, y);
1199 glvertex2d (view, x + f.x, y + f.y);
1200 view->ni++;
1201 }
1202 glEnd();
1203 }
1204 view->res = res;
1205 view->maxlevel = maxlevel;
1206#else // dimension == 3
1207 fprintf (stderr, "vectors() is not implemented in 3D yet\n");
1208#endif // dimension == 3
1209 return true;
1210}
1211
1212/**
1213# *squares()*: displays colormapped fields
1214
1215The field name is given by *color*. The *min*, *max*, *spread*, *map*
1216etc. arguments work as described in
1217[draw_vof()](draw.h#draw_vof-displays-vof-reconstructed-interfaces).
1218
1219In 2D, if *z* is specified, and *linear* is the true, the corresponding
1220expression is used as z-coordinate.
1221
1222In 3D the intersections of the field with a plane are displayed. The
1223default plane is \f$z=0\f$. This can be changed by setting *n* and *alpha*
1224which define the plane
1225\f[
1226n_x x + n_y y + n_z z = \alpha
1227\f]
1228*/
1229
1230trace
1231bool squares (char * color,
1232 char * z = NULL,
1233 double min = 0, double max = 0, double spread = 0,
1234 bool linear = false,
1235 Colormap map = jet,
1236 float fc[3] = {0}, float lc[3] = {0},
1237 bool expr = false,
1238
1239 coord n = {0,0,1},
1240 double alpha = 0,
1241 float lw = 1,
1243{
1244#if dimension == 2
1245 scalar Z = {-1};
1246 vector fn;
1247 bool zexpr = false;
1248 if (z) {
1250 if (Z.i < 0)
1251 return false;
1252 fn = {0} /* new vector */;
1253 for (int _i = 0; _i < _N; _i++) /* foreach */
1254 for (int _d = 0; _d < dimension; _d++)
1255 fn.x[] = (Z[1] - Z[-1])/(2.*Delta_x);
1256 boundary ({fn}); // fixme: necessary because for (int _i = 0; _i < _N; _i++) /* foreach_leaf */ below doesn't do automatic BCs
1257 }
1258#endif
1259 colorize_args();
1260 scalar f = col;
1261 boundary ({f}); // fixme: necessary because for (int _i = 0; _i < _N; _i++) /* foreach_leaf */ below doesn't do automatic BCs
1262 bview * view = draw();
1264 if (linear) {
1265 colorize() {
1266#if dimension == 2
1267 if (Z.i < 0) {
1268 glNormal3d (0, 0, view->reversed ? -1 : 1);
1270 if (f.i < 0 || f[] != nodata) {
1272 color_vertex ((4.*f[] +
1273 2.*(f[1] + f[-1] + f[0,1] + f[0,-1]) +
1274 f[-1,-1] + f[1,1] + f[-1,1] + f[1,-1])/16.);
1275 glvertex2d (view, x, y);
1276 color_vertex ((f[] + f[-1] + f[-1,-1] + f[0,-1])/4.);
1277 glvertex2d (view, x - Delta_x/2., y - Delta_y/2.);
1278 color_vertex ((f[] + f[1] + f[1,-1] + f[0,-1])/4.);
1279 glvertex2d (view, x + Delta_x/2., y - Delta_y/2.);
1280 color_vertex ((f[] + f[1] + f[1,1] + f[0,1])/4.);
1281 glvertex2d (view, x + Delta_x/2., y + Delta_y/2.);
1282 color_vertex ((f[] + f[-1] + f[-1,1] + f[0,1])/4.);
1283 glvertex2d (view, x - Delta_x/2., y + Delta_y/2.);
1284 color_vertex ((f[] + f[-1] + f[-1,-1] + f[0,-1])/4.);
1285 glvertex2d (view, x - Delta_x/2., y - Delta_y/2.);
1286 glEnd();
1287 view->ni++;
1288 }
1289 }
1290 else // Z.i > 0
1291 for (int _i = 0; _i < _N; _i++) /* foreach_leaf */ // fixme: foreach_visible() would be better
1292 if (f.i < 0 || f[] != nodata) {
1294 color_vertex ((4.*f[] +
1295 2.*(f[1] + f[-1] + f[0,1] + f[0,-1]) +
1296 f[-1,-1] + f[1,1] + f[-1,1] + f[1,-1])/16.);
1297 glvertex_normal3d (view, point, fn, x, y, Z[]);
1298 color_vertex ((f[] + f[-1] + f[-1,-1] + f[0,-1])/4.);
1300 (Z[] + Z[-1] + Z[-1,-1] + Z[0,-1])/4.);
1301 color_vertex ((f[] + f[1] + f[1,-1] + f[0,-1])/4.);
1303 (Z[] + Z[1] + Z[1,-1] + Z[0,-1])/4.);
1304 color_vertex ((f[] + f[1] + f[1,1] + f[0,1])/4.);
1306 (Z[] + Z[1] + Z[1,1] + Z[0,1])/4.);
1307 color_vertex ((f[] + f[-1] + f[-1,1] + f[0,1])/4.);
1309 (Z[] + Z[-1] + Z[-1,1] + Z[0,1])/4.);
1310 color_vertex ((f[] + f[-1] + f[-1,-1] + f[0,-1])/4.);
1312 (Z[] + Z[-1] + Z[-1,-1] + Z[0,-1])/4.);
1313 glEnd();
1314 view->ni++;
1315 }
1316#else // dimension == 3
1318 if (f.i < 0 || f[] != nodata) {
1319 coord v[12];
1320 int m = facets (n, alpha, v, 1.);
1321 if (m > 2) {
1322 coord c = {0,0,0};
1323 for (int i = 0; i < m; i++)
1324 for (int _d = 0; _d < dimension; _d++)
1325 c.x += v[i].x/m;
1327 color_vertex (interp (point, c, f));
1328 glvertex3d (view, x + c.x*Delta, y + c.y*Delta, z + c.z*Delta);
1329 for (int i = 0; i < m; i++) {
1330 color_vertex (interp (point, v[i], f));
1332 x + v[i].x*Delta, y + v[i].y*Delta, z + v[i].z*Delta);
1333 }
1334 color_vertex (interp (point, v[0], f));
1336 x + v[0].x*Delta, y + v[0].y*Delta, z + v[0].z*Delta);
1337 glEnd ();
1338 view->ni++;
1339 }
1340 }
1341#endif // dimension == 3
1342 }
1343 }
1344 else { // !linear
1345#if dimension == 2
1346 glNormal3d (0, 0, view->reversed ? -1 : 1);
1347 glBegin (GL_QUADS);
1349 if (f.i < 0 || f[] != nodata) {
1350 color_facet();
1351 glvertex2d (view, x - Delta_x/2., y - Delta_y/2.);
1352 color_facet();
1353 glvertex2d (view, x + Delta_x/2., y - Delta_y/2.);
1354 color_facet();
1355 glvertex2d (view, x + Delta_x/2., y + Delta_y/2.);
1356 color_facet();
1357 glvertex2d (view, x - Delta_x/2., y + Delta_y/2.);
1358 view->ni++;
1359 }
1360 glEnd();
1361#else // dimension == 3
1363 if (f.i < 0 || f[] != nodata) {
1364 coord v[12];
1365 int m = facets (n, alpha, v, 1.);
1366 if (m > 2) {
1368 for (int i = 0; i < m; i++) {
1369 color_facet();
1371 x + v[i].x*Delta, y + v[i].y*Delta, z + v[i].z*Delta);
1372 }
1373 glEnd ();
1374 view->ni++;
1375 }
1376 }
1377#endif // dimension == 3
1378 }
1379 if (expr) delete ({col});
1380#if dimension == 2
1381 if (zexpr) delete ({Z});
1382 if (z) delete ((scalar *){fn});
1383#endif
1384 return true;
1385}
1386
1387/**
1388# *box()*: displays box boundaries and axis coordinates
1389
1390* *notics*: do not draw tick marks (default is false).
1391* *lc[]*: an array of red, green, blue values between 0 and 1 which
1392 defines the line color.
1393* *lw*: the line width.
1394*/
1395
1396trace
1397bool box (bool notics = false, float lc[3] = {0}, float lw = 1.)
1398{
1399 bview * view = draw();
1400 coord box[2] = {
1401 {X0, Y0, Z0},
1402 {X0 + L0,
1404#if dimension > 2
1406#endif
1407 }
1408 };
1409 coord e;
1410 double emin = HUGE;
1411 for (int _d = 0; _d < dimension; _d++) {
1412 e.x = box[1].x - box[0].x;
1413 if (e.x < emin)
1414 emin = e.x;
1415 }
1416 draw_lines (view, lc, lw) {
1417
1418 float height = 0.5*gl_StrokeHeight();
1419 float width = gl_StrokeWidth ('1'), scale = emin/(60.*width), length;
1420 float Z1 = dimension == 2 ? 0. : box[0].z;
1421 char label[80];
1422
1424
1425#if dimension == 2
1427 glvertex2d (view, box[0].x, box[0].y);
1428 glvertex2d (view, box[1].x, box[0].y);
1429 glvertex2d (view, box[1].x, box[1].y);
1430 glvertex2d (view, box[0].x, box[1].y);
1431 glEnd ();
1432 view->ni++;
1433#else // dimension != 2
1434 for (int _l = 0; _l < 0, serial; _l++) {
1435 for (int i = -1; i <= 1; i += 2) {
1437 glvertex3d (view, box[0].x, box[0].y, z + i*Delta/2.); // fixme
1438 glvertex3d (view, box[1].x, box[0].y, z + i*Delta/2.);
1439 glvertex3d (view, box[1].x, box[1].y, z + i*Delta/2.);
1440 glvertex3d (view, box[0].x, box[1].y, z + i*Delta/2.);
1441 glEnd ();
1442 view->ni++;
1443 glBegin (GL_LINES);
1444 for (int j = -1; j <= 1; j += 2) { // fixme
1445 glvertex3d (view, x + i*Delta/2., y + j*Delta/2., z - Delta/2.);
1446 glvertex3d (view, x + i*Delta/2., y + j*Delta/2., z + Delta/2.);
1447 }
1448 glEnd ();
1449 view->ni++;
1450 }
1451 }
1452#endif // dimension != 2
1453
1454 if (!notics) {
1455 int nt = 8;
1456 for (int i = 0; i <= nt; i++) {
1457 glPushMatrix();
1458 glTranslatef (X0 + i*e.x/nt - height/2.*scale,
1459 Y0 - width/3.*scale, Z1);
1460 glRotatef (-90, 0, 0, 1);
1462 sprintf (label, "%g", X0 + i*e.x/nt);
1464 glPopMatrix();
1465
1466 glPushMatrix();
1467 sprintf (label, "%g", Y0 + i*e.y/nt);
1469 glTranslatef (X0 - (length + width/3.)*scale,
1470 Y0 + i*e.y/nt - height/2.*scale, Z1);
1473 glPopMatrix();
1474
1475#if dimension > 2
1476 glPushMatrix();
1477 sprintf (label, "%g", Z0 + i*e.z/nt);
1479 glTranslatef (X0 - (length + width/3.)*scale,
1480 Y0, Z0 + i*e.z/nt + height/2.*scale);
1481 glRotatef (-90, 1, 0, 0);
1484 glPopMatrix();
1485#endif
1486 }
1487
1488 glPushMatrix();
1489 sprintf (label, "%g", X0 + e.x/2.);
1491 glTranslatef (X0 + e.x/2 - height*scale,
1492 Y0 - (length + 4.*width)*scale, Z1);
1493 glScalef (2.*scale, 2.*scale, 2.*scale);
1494 gl_StrokeString ("X");
1495 glPopMatrix();
1496
1497
1498 glPushMatrix();
1499 sprintf (label, "%g", Y0 + e.y/2.);
1501 glTranslatef (X0 - (length + 4.*width)*scale,
1502 Y0 + e.y/2. - height*scale, Z1);
1503 glScalef (2.*scale, 2.*scale, 2.*scale);
1504 gl_StrokeString ("Y");
1505 glPopMatrix();
1506
1507#if dimension > 2
1508 glPushMatrix();
1509 sprintf (label, "%g", Z0 + e.z/2.);
1511 glTranslatef (X0 - (length + 4.*width)*scale,
1512 Y0, Z0 + e.z/2. + height*scale);
1513 glRotatef (-90, 1, 0, 0);
1514 glScalef (2.*scale, 2.*scale, 2.*scale);
1515 gl_StrokeString ("Z");
1516 glPopMatrix();
1517#endif
1518 }
1519 }
1520 return true;
1521}
1522
1523/**
1524# *isosurface()*: displays an isosurface of a field
1525
1526* *f*: the name (as a string) of the field.
1527* *v*: the value of the isosurface.
1528* *edges*: whether to draw the edges of isosurface facets.
1529* *color*: use this field to color each interface fragment.
1530
1531The *min*, *max*, *spread*, *map* etc. arguments work as described in
1532[draw_vof()](draw.h#draw_vof-displays-vof-reconstructed-interfaces). */
1533
1534trace
1535bool isosurface (char * f,
1536 double v,
1537
1538 char * color = NULL,
1539 double min = 0, double max = 0, double spread = 0,
1540 bool linear = false,
1541 Colormap map = jet,
1542 float fc[3] = {0}, float lc[3] = {0}, float lw = 1,
1543 bool expr = false,
1545{
1546#if dimension > 2
1547 if (!f)
1548 return false;
1549
1550 scalar ff = {-1};
1551 bool fexpr;
1552 if (strcmp (f, "level")) {
1554 if (ff.i < 0)
1555 return false;
1556 }
1557
1558 colorize_args();
1559
1560 scalar fv[];
1561 for (int _i = 0; _i < _N; _i++) /* foreach_vertex */
1562 fv[] = (ff[] + ff[-1] + ff[0,-1] + ff[-1,-1] +
1563 ff[0,0,-1] + ff[-1,0,-1] + ff[0,-1,-1] + ff[-1,-1,-1])/8.;
1564
1565 vector n[];
1566 for (int _i = 0; _i < _N; _i++) /* foreach */
1567 for (int _d = 0; _d < dimension; _d++)
1568 n.x[] = center_gradient(ff);
1569
1570 bview * view = draw();
1572 colorize() {
1574 double val[8] = {
1575 fv[0,0,0], fv[1,0,0], fv[1,0,1], fv[0,0,1],
1576 fv[0,1,0], fv[1,1,0], fv[1,1,1], fv[0,1,1]
1577 };
1578 double t[5][3][3];
1579 int nt = polygonize (val, v, t);
1580 for (int i = 0; i < nt; i++) {
1581 color_facet();
1583 for (int j = 0; j < 3; j++) {
1584 coord v = {t[i][j][0], t[i][j][1], t[i][j][2]}, np;
1585 for (int _d = 0; _d < dimension; _d++)
1586 np.x = interp (point, v, n.x);
1587 glnormal3d (view, np.x, np.y, np.z);
1588 if (linear) {
1590 }
1591 else {
1592 color_facet();
1593 }
1594 glvertex3d (view, x + v.x*Delta_x, y + v.y*Delta_y, z + v.z*Delta_z);
1595 }
1596 glEnd ();
1597 view->ni++;
1598 }
1599 }
1600 }
1601 if (expr) delete ({col});
1602 if (fexpr) delete ({ff});
1603#endif // dimension > 2
1604 return true;
1605}
1606
1607/**
1608# *travelling()*: moves the camera to a different viewpoint
1609
1610* *start*: starting time of the camera motion.
1611* *end*: time at which the viewpoint should be reached.
1612* *tx*, *ty*, *quat*, *fov*: definition of the target viewpoint.
1613*/
1614
1615#define interpo(pv, v) \
1616 (!pv ? v : ((t - start)*(pv) + (end - t)*(v))/(end - start))
1617
1618void travelling (double start = 0, double end = 0,
1619 float tx = 0, float ty = 0, float quat[4] = {0}, float fov = 0)
1620{
1621 static float stx, sty, squat[4], sfov;
1622 static double told = -1.;
1623 if (told < start && t >= start) {
1624 bview * view = get_view();
1625 stx = view->tx, sty = view->ty, sfov = view->fov;
1626 for (int i = 0; i < 4; i++)
1627 squat[i] = view->quat[i];
1628 }
1629 if (t >= start && t <= end)
1630 view (tx = interpo (tx, stx), ty = interpo (ty, sty),
1631 fov = interpo (fov, sfov),
1632 quat = {interpo(quat[0], squat[0]), interpo(quat[1], squat[1]),
1633 interpo(quat[2], squat[2]), interpo(quat[3], squat[3])});
1634 if (told < end && t >= end) {
1635 bview * view = get_view();
1636 stx = view->tx, sty = view->ty, sfov = view->fov;
1637 for (int i = 0; i < 4; i++)
1638 squat[i] = view->quat[i];
1639 }
1640 told = t;
1641}
1642
1643#undef interpo
1644
1645/**
1646# *draw_string()*: draws strings on a separate layer (for annotations)
1647
1648* *str*: string to display.
1649* *pos*: position: "0" bottom left, "1" top left, "2" top right
1650 and "3" bottom right (default 0).
1651* *size*: the size of the text, given as the number of characters
1652 which can fit within the width of the screen. Default is 40.
1653* *lc[]*: an array of red, green, blue values between 0 and 1 which
1654 defines the text color.
1655* *lw*: the line width.
1656*/
1657
1658trace
1659bool draw_string (char * str,
1660 int pos = 0,
1661 float size = 40,
1662 float lc[3] = {0}, float lw = 1)
1663
1664{
1665 bview * view = draw();
1666
1668 glPushMatrix();
1670
1672 glPushMatrix();
1674
1675 glColor3f (lc[0], lc[1], lc[2]);
1676 glLineWidth (view->samples*(lw > 0. ? lw : 1.));
1677
1678 float width = gl_StrokeWidth ('1'), height = gl_StrokeHeight();
1679 if (!size)
1680 size = 40;
1681 float hscale = 2./(size*width), vscale = hscale*view->width/view->height;
1682 float vmargin = width/2.*vscale;
1683 if (pos == 0)
1684 glTranslatef (-1., -1. + vmargin, 0.);
1685 else if (pos == 1)
1686 glTranslatef (-1., 1. - height*vscale, 0.);
1687 else if (pos == 2)
1688 glTranslatef (1. - strlen(str)*width*hscale, 1. - height*vscale, 0.);
1689 else
1690 glTranslatef (1. - strlen(str)*width*hscale, -1. + vmargin, 0.);
1691 glScalef (hscale, vscale, 1.);
1693
1695 glPopMatrix();
1697 glPopMatrix();
1698
1699 return true;
1700}
1701
1702/**
1703# *labels()*: displays label fields */
1704
1705trace
1706bool labels (char * f, float lc[3] = {0}, float lw = 1, int level = -1)
1707{
1708#if dimension == 2
1709 bool expr = false;
1710 scalar ff = compile_expression (f, &expr);
1711 if (ff.i < 0)
1712 return false;
1713 bview * view = draw();
1714 float width = gl_StrokeWidth ('1'), height = gl_StrokeHeight();
1715 float res = view->res;
1716 if (view->res < 150*view->samples)
1717 view->res = 150*view->samples;
1718 int maxlevel = view->maxlevel;
1719 view->maxlevel = level;
1720 draw_lines (view, lc, lw) {
1723 if (ff[] != nodata) {
1724 glPushMatrix();
1725 char s[80];
1726 sprintf (s, "%g", ff[]);
1727 float scale = 0.8*Delta_x/(strlen(s)*width);
1728 glTranslatef (x - 0.4*Delta_x, y - scale*height/3., 0.);
1729 glScalef (scale, scale, 1.);
1731 glPopMatrix();
1732 }
1733 }
1734 view->res = res;
1735 view->maxlevel = maxlevel;
1736 if (expr) delete ({ff});
1737 return true;
1738#else // dimension == 3
1739 fprintf (stderr, "labels() is not implemented in 3D yet\n");
1740 return false;
1741#endif // dimension == 3
1742}
1743
1744/**
1745# *lines()*: from a file.
1746
1747* *file*: the gnuplot-formatted file containing the polyline(s).
1748* *lc[]*: an array of red, green, blue values between 0 and 1 which
1749 defines the line color.
1750* *lw*: the line width.
1751*/
1752
1753trace
1754bool lines (char * file, float lc[3] = {0}, float lw = 1.)
1755{
1756#if dimension != 2
1757 assert (false);
1758#else // dimension == 2
1759 if (!file) {
1760 fprintf (stderr, "lines(): file must be specified\n");
1761 return false;
1762 }
1763 FILE * fp = fopen (file, "r");
1764 if (!fp) {
1765 perror (file);
1766 return false;
1767 }
1768 bview * view = draw();
1769 draw_lines (view, lc, lw) {
1770 bool line = false;
1771 int c = fgetc (fp);
1772 while (c != EOF) {
1773 while (c == ' ' || c == '\t') c = fgetc (fp);
1774 if (c == '.' || c == '+' || c == '-' || isdigit (c)) {
1775 ungetc (c, fp);
1776 double x, y;
1777 if (fscanf (fp, "%lf %lf", &x, &y) == 2) {
1778 if (!line) {
1780 line = true;
1781 }
1782 glvertex2d (view, x, y);
1783 while ((c = fgetc(fp)) == ' ' || c == '\t');
1784 if (c == '\n') c = fgetc (fp);
1785 view->ni++;
1786 }
1787 else // ignore the rest of the line
1788 while ((c = fgetc(fp)) != EOF && c != '\n');
1789 }
1790 else if (c == '#')
1791 while ((c = fgetc(fp)) != EOF && c != '\n');
1792 else {
1793 if (line)
1794 glEnd(), line = false;
1795 c = fgetc (fp);
1796 }
1797 }
1798 if (line)
1799 glEnd();
1800 }
1801 fclose (fp);
1802#endif // dimension == 2
1803 return true;
1804}
1805
1806/**
1807# Interface export
1808
1809This is used by [bview](bview/README) to automatically generate the
1810user interface. */
1811
1812#include "draw_json.h"
1813
1814struct {
1815 int (* json) (char * s, int len);
1816} bview_interface[] = {
1817 { _draw_vof_json },
1818 { _squares_json },
1819 { _cells_json },
1820 { _box_json },
1821#if dimension == 2
1822 { _isoline_json },
1823 { _labels_json },
1824 { _vectors_json },
1825 { _lines_json },
1826#else // dimension == 3
1827 { _isosurface_json },
1828#endif
1829 { NULL }
double q2
Definition NASG.h:20
double q1
Definition NASG.h:20
#define u
Definition advection.h:30
vector q[]
The primitive variables are the momentum , pressure , density , (face) specific volume ,...
Definition all-mach.h:44
const vector alpha
Definition all-mach.h:47
scalar h[]
Definition atmosphere.h:6
if TRASH define &&NewPid *& val(newpid, 0, 0, 0)) -> pid > 0) @else @ define is_newpid()(((NewPid *)&val(newpid, 0, 0, 0)) ->pid > 0) @endif Array *linear_tree(size_t size, scalar newpid)
Definition balance.h:13
int min
Definition balance.h:192
#define dimension
Definition bitree.h:3
define k
#define boundary(...)
define double double char flags
static double interpolate_linear(Point point, scalar v, double xp=0., double yp=0., double zp=0.)
define double double char Reduce reductions
define m((k)==0 &&(l)==0 &&(m)==0) macro2 foreach_point(double _x=0.
free(list1)
void spread
Definition centered.h:199
int y
Definition common.h:76
int x
Definition common.h:76
int z
Definition common.h:76
#define pi
Definition common.h:4
double Z0
Definition common.h:34
#define nodata
Definition common.h:7
void normalize(coord *n)
Definition common.h:98
#define HUGE
Definition common.h:6
ivec Dimensions
Definition common.h:173
double L0
Definition common.h:36
static number sq(number x)
Definition common.h:11
static number clamp(number x, number a, number b)
Definition common.h:15
double X0
Definition common.h:34
#define norm(v)
Definition common.h:91
#define center_gradient(a)
Definition common.h:407
static bool is_vertex_scalar(scalar s)
Definition common.h:334
#define dv()
Definition common.h:92
double Y0
Definition common.h:34
scalar f[]
The primary fields are:
Definition two-phase.h:56
vector * vectors
#define p
Definition tree.h:320
else define undefined((double) DBL_MAX) @ define enable_fpe(flags) @ define disable_fpe(flags) static void set_fpe(void)
Definition config.h:615
if __APPLE__ include< stdint.h > include fp_osx h endif if _GPU define enable_fpe(flags) @else @ define enable_fpe(flags) feenableexcept(flags) @endif @ define disable_fpe(flags) fedisableexcept(flags) static void set_fpe(void)
Definition config.h:603
define sysmalloc malloc define syscalloc calloc define sysrealloc realloc define sysfree free define systrdup strdup define line calloc(n, s) @ define prealloc(p
define sysmalloc malloc define syscalloc calloc define sysrealloc realloc define sysfree free define systrdup strdup define file
Definition config.h:120
#define assert(a)
Definition config.h:107
define sysmalloc malloc define syscalloc calloc define sysrealloc realloc define sysfree free define systrdup strdup define line line line line strdup(s) @ define tracing(...) @ define end_tracing(...) @define tid() 0 @define pid() 0 @define npe() 1 @define mpi_all_reduce(v
Point point
Definition conserving.h:86
return hxx pow(1.+sq(hx), 3/2.)
double pos
Definition curvature.h:674
else return n
Definition curvature.h:101
trace bool isoline(char *phi, double val=0., int n=1, bool edges=false, double larger=0., int filled=0, char *color=NULL, double min=0, double max=0, double spread=0, bool linear=false, Colormap map=jet, float fc[3]={0}, float lc[3]={0}, float lw=1., bool expr=false, bool cbar=false, float size=15, float pos[2]={-.95, -.95}, char *label="", double lscale=1, bool horizontal=false, bool border=false, bool mid=false, float fsize=50, char *format="%g", int levels=50)
Definition draw.h:1071
struct @2 bview_interface[]
trace bool squares(char *color, char *z=NULL, double min=0, double max=0, double spread=0, bool linear=false, Colormap map=jet, float fc[3]={0}, float lc[3]={0}, bool expr=false, coord n={0, 0, 1}, double alpha=0, float lw=1, bool cbar=false, float size=15, float pos[2]={-.95, -.95}, char *label="", double lscale=1, bool horizontal=false, bool border=false, bool mid=false, float fsize=50, char *format="%g", int levels=50)
Definition draw.h:1231
macro2 foreach_visible_stencil(bview *view, char flags, Reduce reductions)
Definition draw.h:333
static bool cfilter(Point point, scalar c, double cmin)
The somewhat complicated function below checks whether an interface fragment is present within a give...
Definition draw.h:812
static void glvertex3d(bview *view, double x, double y, double z)
Definition draw.h:838
#define COLORBAR_PARAMS
Parameters for an (optional) colorbar.
Definition draw.h:798
#define interpo(pv, v)
Definition draw.h:1615
void view(float tx=0., float ty=0., float fov=0., float quat[4]={0}, float sx=1., float sy=1., float sz=1., unsigned width=800, unsigned height=800, unsigned samples=4, float bg[3]={0}, float theta=0., float phi=0., float psi=0., bool relative=false, float tz=0., float near=0., float far=0., float res=0., char *camera=NULL, MapFunc map=NULL, int cache=0, float p1x=0., float p1y=0., float p2x=0., float p2y=0., bview *view1=NULL)
Definition draw.h:52
trace bool labels(char *f, float lc[3]={0}, float lw=1, int level=-1)
Definition draw.h:1706
int(* json)(char *s, int len)
Definition draw.h:1815
static void mapped_position(bview *view, coord *p, double *r)
Definition draw.h:292
static void glvertex2d(bview *view, double x, double y)
Definition draw.h:849
trace bool isosurface(char *f, double v, char *color=NULL, double min=0, double max=0, double spread=0, bool linear=false, Colormap map=jet, float fc[3]={0}, float lc[3]={0}, float lw=1, bool expr=false, bool cbar=false, float size=15, float pos[2]={-.95, -.95}, char *label="", double lscale=1, bool horizontal=false, bool border=false, bool mid=false, float fsize=50, char *format="%g", int levels=50)
Definition draw.h:1535
trace bool draw_vof(char *c, char *s=NULL, bool edges=false, double larger=0., int filled=0, char *color=NULL, double min=0, double max=0, double spread=0, bool linear=false, Colormap map=jet, float fc[3]={0}, float lc[3]={0}, float lw=1., bool expr=false, bool cbar=false, float size=15, float pos[2]={-.95, -.95}, char *label="", double lscale=1, bool horizontal=false, bool border=false, bool mid=false, float fsize=50, char *format="%g", int levels=50)
Definition draw.h:897
#define colorize()
Definition draw.h:642
#define color_facet()
Definition draw.h:592
macro translate(float x=0, float y=0., float z=0.)
Definition draw.h:216
static double evaluate_expression(Point point, Node *n)
Definition draw.h:410
trace bool box(bool notics=false, float lc[3]={0}, float lw=1.)
Definition draw.h:1397
trace bool cells(coord n={0, 0, 1}, double alpha=0., float lc[3]={0}, float lw=1.)
Definition draw.h:1128
macro mirror(coord n={0}, double alpha=0.)
Definition draw.h:241
static void glvertex_normal3d(bview *view, Point point, vector n, double xp, double yp, double zp)
Definition draw.h:859
#define color_vertex(val)
Definition draw.h:600
static double interp(Point point, coord p, scalar col)
Definition draw.h:405
trace bool draw_string(char *str, int pos=0, float size=40, float lc[3]={0}, float lw=1)
Definition draw.h:1659
void travelling(double start=0, double end=0, float tx=0, float ty=0, float quat[4]={0}, float fov=0)
Definition draw.h:1618
trace bool colorbar(Colormap map=jet, float size=15, float pos[2]={-.95, -.95}, char *label="", double lscale=1, double min=-HUGE, double max=HUGE, bool horizontal=false, bool border=false, bool mid=false, float lc[3]={0}, float lw=3, float fsize=50, char *format="%g", int levels=50)
Definition draw.h:668
void clear()
Definition draw.h:14
static scalar compile_expression(char *expr, bool *isexpr)
Definition draw.h:512
macro2 foreach_visible(bview *view, char flags=0, Reduce reductions=None)
Definition draw.h:308
static bool assemble_node(Node *n)
Definition draw.h:465
#define colorize_args()
Definition draw.h:554
macro colorized(float fc[3], bool constant_color, double cmap[NCMAP][3], bool use_texture)
Definition draw.h:615
macro draw_lines(bview *view, float color[3], float lw)
A similar technique can be used to traverse the cells which are both visible and intersected by a pla...
Definition draw.h:388
int _isosurface_json(char *s, int len)
Definition draw_json.h:208
int _draw_vof_json(char *s, int len)
Definition draw_json.h:62
int _cells_json(char *s, int len)
Definition draw_json.h:132
int _labels_json(char *s, int len)
Definition draw_json.h:274
int _vectors_json(char *s, int len)
Definition draw_json.h:148
int _squares_json(char *s, int len)
Definition draw_json.h:166
int _box_json(char *s, int len)
Definition draw_json.h:194
int _isoline_json(char *s, int len)
Definition draw_json.h:96
int _lines_json(char *s, int len)
Definition draw_json.h:290
scalar phi[]
The electric potential and the volume charge density are scalars while the permittivity and conductiv...
Definition implicit.h:34
scalar s
Definition embed-tree.h:56
*cs[i, 0, 0] a *[i -1, 0, 0] j
Definition embed.h:88
double v[2]
Definition embed.h:383
vector fs[]
Definition embed.h:22
double d[2]
Definition embed.h:383
scalar int i
Definition embed.h:74
static int line
Definition errors.c:754
double t
Definition events.h:24
void fraction_refine(Point point, scalar c)
Definition fractions.h:42
coord facet_normal(Point point, scalar c, vector s)
Definition fractions.h:426
trace void fractions(scalar Phi, scalar c, vector s={0}, double val=0.)
Definition fractions.h:123
#define plane_alpha
Definition geometry.h:133
int facets(coord n, double alpha, coord p[2])
From the interface definition, it is also possible to compute the coordinates of the segment in 2D,...
Definition geometry.h:294
#define glVertex2f
Definition glad.h:2404
#define glColor3f
Definition glad.h:2059
#define GL_TEXTURE_MIN_FILTER
Definition glad.h:307
#define glBegin
Definition glad.h:2041
#define GL_TEXTURE_WRAP_S
Definition glad.h:308
#define GL_QUADS
Definition glad.h:150
#define glNormal3d
Definition glad.h:2182
#define glEnable
Definition glad.h:1942
#define GL_TRIANGLE_FAN
Definition glad.h:149
#define glTranslatef
Definition glad.h:2791
#define GL_LINEAR
Definition glad.h:301
#define GL_LINE_STRIP
Definition glad.h:146
#define glPopMatrix
Definition glad.h:2770
#define GL_LINES
Definition glad.h:144
#define GL_SMOOTH
Definition glad.h:531
#define glTexParameteri
Definition glad.h:1903
#define glMultMatrixf
Definition glad.h:2761
#define GL_RGB
Definition glad.h:287
#define GL_FLOAT
Definition glad.h:258
khronos_float_t GLfloat
Definition glad.h:104
#define GL_PROJECTION
Definition glad.h:522
#define GL_MODELVIEW
Definition glad.h:521
#define glTexImage1D
Definition glad.h:1909
#define glMatrixMode
Definition glad.h:2758
#define glRotatef
Definition glad.h:2779
#define glScalef
Definition glad.h:2785
#define glVertex2d
Definition glad.h:2398
#define GL_POLYGON
Definition glad.h:330
#define glPushMatrix
Definition glad.h:2773
#define GL_TEXTURE_WRAP_T
Definition glad.h:309
#define glShadeModel
Definition glad.h:2530
#define glLineWidth
Definition glad.h:1885
#define GL_TEXTURE_MAG_FILTER
Definition glad.h:306
#define GL_LINE_LOOP
Definition glad.h:145
#define glEnd
Definition glad.h:2149
#define glVertex3d
Definition glad.h:2422
#define glDisable
Definition glad.h:1939
#define GL_TEXTURE_1D
Definition glad.h:244
#define GL_CLAMP_TO_EDGE
Definition glad.h:692
#define glLoadIdentity
Definition glad.h:2749
#define GL_LIGHTING
Definition glad.h:388
macro2 foreach_stencil(char flags, Reduce reductions, int _parallel, External *_externals, const char *_kernel)
Definition gpu.h:288
#define str(a)
Definition grid.h:406
double dh
Definition heights.h:331
static double height(double H)
Definition heights.h:31
static int
Definition include.c:978
static void relative(const KdtRect rect, double *o, double *h)
Definition kdt.c:389
static float length(const KdtRect rect)
Definition kdt.c:444
macro
We also redefine the "per field" (inner) traversal.
Definition layers.h:18
size_t max
Definition mtrace.h:8
FILE * fp
Definition mtrace.h:7
void(* restriction)(Point, scalar)
void set_prolongation(scalar s, void(*prolongation)(Point, scalar))
size_t size
int int int level
define is_active() cell(true) @define is_leaf(cell)(point.level
#define NCMAP
Definition output.h:194
void(* Colormap)(double cmap[127][3])
Definition output.h:196
Color colormap_color(double cmap[127][3], double val, double min, double max)
Definition output.h:308
void jet(double cmap[127][3])
Definition output.h:198
def _i
Definition stencils.h:405
scalar psi[]
Definition stream.h:39
Given a colormap and a minimum and maximum value, this function returns the red/green/blue triplet co...
Definition output.h:304
Definition kdt.c:344
Definition linear.h:21
int level
Definition linear.h:23
Definition view.h:141
bool reversed
Definition view.h:148
Frustum frustum
Definition view.h:159
Definition view.h:73
Definition common.h:78
double x
Definition common.h:79
double y
Definition common.h:79
int y
Definition common.h:142
int x
Definition common.h:140
Definition utils.h:138
int i
Definition common.h:44
scalar x
Definition common.h:47
scalar y
Definition common.h:49
scalar nt
Definition terrain.h:17
define n n define n n macro POINT_VARIABLES(Point point=point)
Definition tree.h:322
@ border
Definition tree.h:61
#define Z
Definition tribox3.h:23
vector lookup_vector(const char *name)
Definition utils.h:330
scalar lookup_field(const char *name)
These functions return the scalar/vector fields called name, or -1 if they don't exist.
Definition utils.h:321
double theta
This is the generalised minmod limiter.
Definition utils.h:223
int lines
struct @17 VertexBuffer
Array * index
Array * color
static bview * _view
For the moment there is a single (static) current view.
Definition view.h:225
bview * draw()
This is called by graphics primitives before drawing.
Definition view.h:302
static cexpr * add_cexpr(cexpr *cache, int maxlen, const char *expr, scalar s)
Definition view.h:96
bview * get_view()
Definition view.h:238
static scalar get_cexpr(cexpr *cache, const char *expr)
Definition view.h:78
void(* MapFunc)(coord *)
Definition view.h:139
scalar c
Definition vof.h:57