GRASS 8 Programmer's Manual  8.5.0dev(2025)-c070206eb1
gsd_objs.c
Go to the documentation of this file.
1 /*!
2  \file lib/ogsf/gsd_objs.c
3 
4  \brief OGSF library - objects management (lower level functions)
5 
6  GRASS OpenGL gsurf OGSF Library
7 
8  (C) 1999-2008 by the GRASS Development Team
9 
10  This program is free software under the
11  GNU General Public License (>=v2).
12  Read the file COPYING that comes with GRASS
13  for details.
14 
15  \author Bill Brown USACERL (October 1993)
16  \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
17  */
18 
19 #include <stdlib.h>
20 #include <string.h>
21 
22 #include <grass/gis.h>
23 #include <grass/ogsf.h>
24 
25 #include "gsget.h"
26 #include "math.h"
27 #include "rowcol.h"
28 
29 static void init_stuff(void);
30 
31 /**
32  * @brief vertices for octahedron
33  */
34 float Octo[6][3] = {{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0},
35  {-1.0, 0.0, 0.0}, {0.0, -1.0, 0.0}, {0.0, 0.0, -1.0}};
36 
37 #define ONORM .57445626
38 
39 /**
40  * @brief normals for flat-shaded octahedron
41  */
42 float OctoN[8][3] = {
43  {ONORM, ONORM, ONORM}, {-ONORM, ONORM, ONORM}, {ONORM, -ONORM, ONORM},
44  {-ONORM, -ONORM, ONORM}, {ONORM, ONORM, -ONORM}, {-ONORM, ONORM, -ONORM},
45  {ONORM, -ONORM, -ONORM}, {-ONORM, -ONORM, -ONORM},
46 };
47 
48 /*!
49  ???? not sure if any of these are needed for correct lighting.
50  float CubeNormals[6][3] = {
51  {ONORM, 0, 0},
52  {-ONORM, 0, 0},
53  {0, ONORM, 0},
54  {0, -ONORM, 0},
55  {0, 0, ONORM},
56  {0, 0, -ONORM}
57  };
58  */
59 
60 float CubeNormals[3][3] = {{0, -ONORM, 0}, {0, 0, ONORM}, {ONORM, 0, 0}};
61 
62 float CubeVertices[8][3] = {
63  {-1.0, -1.0, -1.0}, {1.0, -1.0, -1.0}, {1.0, 1.0, -1.0}, {-1.0, 1.0, -1.0},
64  {-1.0, -1.0, 1.0}, {1.0, -1.0, 1.0}, {1.0, 1.0, 1.0}, {-1.0, 1.0, 1.0}};
65 
66 float origin[3] = {0.0, 0.0, 0.0};
67 
68 #define UP_NORM Octo[2]
69 #define DOWN_NORM Octo[5]
70 #define ORIGIN origin
71 
72 /**
73  * @brief vertices & normals for octagon in xy plane
74  */
75 float ogverts[8][3];
76 
77 /**
78  * @brief vertices for octagon in xy plane, z=1
79  */
80 float ogvertsplus[8][3];
81 
82 float Pi;
83 
84 static void init_stuff(void)
85 {
86  float cos45;
87  int i;
88  static int first = 1;
89 
90  if (first) {
91  first = 0;
92 
93  cos45 = cos(atan(1.0));
94 
95  for (i = 0; i < 8; i++) {
96  ogverts[i][Z] = 0.0;
97  ogvertsplus[i][Z] = 1.0;
98  }
99 
100  ogverts[0][X] = ogvertsplus[0][X] = 1.0;
101  ogverts[0][Y] = ogvertsplus[0][Y] = 0.0;
102  ogverts[1][X] = ogvertsplus[1][X] = cos45;
103  ogverts[1][Y] = ogvertsplus[1][Y] = cos45;
104  ogverts[2][X] = ogvertsplus[2][X] = 0.0;
105  ogverts[2][Y] = ogvertsplus[2][Y] = 1.0;
106  ogverts[3][X] = ogvertsplus[3][X] = -cos45;
107  ogverts[3][Y] = ogvertsplus[3][Y] = cos45;
108  ogverts[4][X] = ogvertsplus[4][X] = -1.0;
109  ogverts[4][Y] = ogvertsplus[4][Y] = 0.0;
110  ogverts[5][X] = ogvertsplus[5][X] = -cos45;
111  ogverts[5][Y] = ogvertsplus[5][Y] = -cos45;
112  ogverts[6][X] = ogvertsplus[6][X] = 0.0;
113  ogverts[6][Y] = ogvertsplus[6][Y] = -1.0;
114  ogverts[7][X] = ogvertsplus[7][X] = cos45;
115  ogverts[7][Y] = ogvertsplus[7][Y] = -cos45;
116 
117  Pi = 4.0 * atan(1.0);
118  }
119 
120  return;
121 }
122 
123 /**
124  * @brief Draws a plus sign symbol at the specified center location.
125  *
126  * This function renders a plus sign ('+') symbol at the given center
127  * coordinates with the specified color and size.
128  *
129  * @param center Pointer to a float array representing the (x, y, z) coordinates
130  * of the center point.
131  * @param colr Integer representing the color to use for drawing the symbol.
132  * @param siz Size of the symbol.
133  */
134 void gsd_plus(float *center, int colr, float siz)
135 {
136  float v1[3], v2[3];
137 
138  gsd_color_func(colr);
139  siz *= .5;
140 
141  v1[Z] = v2[Z] = center[Z];
142 
143  v1[X] = v2[X] = center[X];
144  v1[Y] = center[Y] - siz;
145  v2[Y] = center[Y] + siz;
146  gsd_bgnline();
147  gsd_vert_func(v1);
148  gsd_vert_func(v2);
149  gsd_endline();
150 
151  v1[Y] = v2[Y] = center[Y];
152  v1[X] = center[X] - siz;
153  v2[X] = center[X] + siz;
154  gsd_bgnline();
155  gsd_vert_func(v1);
156  gsd_vert_func(v2);
157  gsd_endline();
158 
159  return;
160 }
161 
162 /**
163  * @brief Line on surface, fix z-values
164  *
165  * @todo remove fudge, instead fudge the Z buffer
166  *
167  * @param gs surface (geosurf)
168  * @param v1 first point (X,Y)
169  * @param v2 second point (X,Y)
170  */
171 void gsd_line_onsurf(geosurf *gs, float *v1, float *v2)
172 {
173  int i, np;
174  Point3 *pts;
175  float fudge;
176 
177  pts = gsdrape_get_segments(gs, v1, v2, &np);
178  if (pts) {
179  fudge = FUDGE(gs);
180  gsd_bgnline();
181 
182  for (i = 0; i < np; i++) {
183  /* ACS */
184  /* reverting back, as it broke displaying X symbol and query line */
185  pts[i][Z] += fudge;
186  /*pts[i][Z] *= fudge; */
187  gsd_vert_func(pts[i]);
188  }
189 
190  gsd_endline();
191 
192  /* fix Z values? */
193  v1[Z] = pts[0][Z];
194  v2[Z] = pts[np - 1][Z];
195  }
196 
197  return;
198 }
199 
200 /**
201  * @brief Multiline on surface, fix z-values
202  *
203  * @todo remove fudge, instead fudge the Z buffer
204  *
205  * Like above, except only draws first n points of line, or np,
206  * whichever is less. Returns number of points used. Fills
207  * pt with last pt drawn.
208  *
209  * @param gs surface (geosurf)
210  * @param v1 Pointer to a float array representing the first point as a vector.
211  * @param v2 Pointer to a float array representing the second point as a vector.
212  * @param[out] pt
213  * @param[in] n number of segments
214  * @return int
215  */
216 int gsd_nline_onsurf(geosurf *gs, float *v1, float *v2, float *pt, int n)
217 {
218  int i, np, pdraw;
219  Point3 *pts;
220  float fudge;
221 
222  pts = gsdrape_get_segments(gs, v1, v2, &np);
223 
224  if (pts) {
225  pdraw = n < np ? n : np;
226  fudge = FUDGE(gs);
227  gsd_bgnline();
228 
229  for (i = 0; i < pdraw; i++) {
230  pts[i][Z] += fudge;
231  gsd_vert_func(pts[i]);
232  }
233 
234  gsd_endline();
235 
236  pt[X] = pts[i - 1][X];
237  pt[Y] = pts[i - 1][Y];
238 
239  /* fix Z values? */
240  v1[Z] = pts[0][Z];
241  v2[Z] = pts[np - 1][Z];
242 
243  return (i);
244  }
245 
246  return (0);
247 }
248 
249 /**
250  * @brief Draws a X symbol at the specified center location.
251  *
252  * This function renders a x ('X') symbol at the given center
253  * coordinates with the specified color and size.
254  *
255  * Note gs: NULL if flat
256  *
257  * @param gs surface (geosurf)
258  * @param center Pointer to a float array representing the (x, y, z) coordinates
259  * of the center point.
260  * @param colr Integer representing the color to use for drawing the symbol.
261  * @param siz Size of the symbol.
262  */
263 void gsd_x(geosurf *gs, float *center, int colr, float siz)
264 {
265  float v1[3], v2[3];
266 
267  gsd_color_func(colr);
268  siz *= .5;
269 
270  v1[Z] = v2[Z] = center[Z];
271 
272  v1[X] = center[X] - siz;
273  v2[X] = center[X] + siz;
274  v1[Y] = center[Y] - siz;
275  v2[Y] = center[Y] + siz;
276 
277  if (gs) {
278  gsd_line_onsurf(gs, v1, v2);
279  }
280  else {
281  gsd_bgnline();
282  gsd_vert_func(v1);
283  gsd_vert_func(v2);
284  gsd_endline();
285  }
286 
287  v1[X] = center[X] - siz;
288  v2[X] = center[X] + siz;
289  v1[Y] = center[Y] + siz;
290  v2[Y] = center[Y] - siz;
291 
292  if (gs) {
293  gsd_line_onsurf(gs, v1, v2);
294  }
295  else {
296  gsd_bgnline();
297  gsd_vert_func(v1);
298  gsd_vert_func(v2);
299  gsd_endline();
300  }
301 
302  return;
303 }
304 
305 /**
306  * @brief Draws a diamond symbol at the specified center location.
307  *
308  * This function renders a diamond symbol at the given center
309  * coordinates with the specified color and size.
310  *
311  * @param center Pointer to a float array representing the (x, y, z) coordinates
312  * of the center point.
313  * @param colr Integer representing the color to use for drawing the symbol.
314  * @param siz Size of the symbol.
315  */
316 void gsd_diamond(float *center, unsigned long colr, float siz)
317 {
318  int preshade;
319 
320  /* seems right, but isn't
321  siz *= .5;
322  */
323 
324  gsd_pushmatrix();
325  gsd_translate(center[X], center[Y], center[Z]);
326  gsd_scale(siz, siz, siz);
327  preshade = gsd_getshademodel();
328  gsd_shademodel(0); /* want flat shading */
329 
330  gsd_bgnpolygon();
331  gsd_litvert_func(OctoN[0], colr, Octo[0]);
332  gsd_litvert_func(OctoN[0], colr, Octo[1]);
333  gsd_litvert_func(OctoN[0], colr, Octo[2]);
334  gsd_endpolygon();
335 
336  gsd_bgnpolygon();
337  gsd_litvert_func(OctoN[1], colr, Octo[2]);
338  gsd_litvert_func(OctoN[1], colr, Octo[1]);
339  gsd_litvert_func(OctoN[1], colr, Octo[3]);
340  gsd_endpolygon();
341 
342  gsd_bgnpolygon();
343  gsd_litvert_func(OctoN[2], colr, Octo[2]);
344  gsd_litvert_func(OctoN[2], colr, Octo[4]);
345  gsd_litvert_func(OctoN[2], colr, Octo[0]);
346  gsd_endpolygon();
347 
348  gsd_bgnpolygon();
349  gsd_litvert_func(OctoN[3], colr, Octo[2]);
350  gsd_litvert_func(OctoN[3], colr, Octo[3]);
351  gsd_litvert_func(OctoN[3], colr, Octo[4]);
352  gsd_endpolygon();
353 
354  gsd_bgnpolygon();
355  gsd_litvert_func(OctoN[4], colr, Octo[0]);
356  gsd_litvert_func(OctoN[4], colr, Octo[5]);
357  gsd_litvert_func(OctoN[4], colr, Octo[1]);
358  gsd_endpolygon();
359 
360  gsd_bgnpolygon();
361  gsd_litvert_func(OctoN[5], colr, Octo[1]);
362  gsd_litvert_func(OctoN[5], colr, Octo[5]);
363  gsd_litvert_func(OctoN[5], colr, Octo[3]);
364  gsd_endpolygon();
365 
366  gsd_bgnpolygon();
367  gsd_litvert_func(OctoN[6], colr, Octo[5]);
368  gsd_litvert_func(OctoN[6], colr, Octo[0]);
369  gsd_litvert_func(OctoN[6], colr, Octo[4]);
370  gsd_endpolygon();
371 
372  gsd_bgnpolygon();
373  gsd_litvert_func(OctoN[7], colr, Octo[5]);
374  gsd_litvert_func(OctoN[7], colr, Octo[4]);
375  gsd_litvert_func(OctoN[7], colr, Octo[3]);
376  gsd_endpolygon();
377 
378 #ifdef OCT_SHADED
379  {
380  gsd_bgntmesh();
381  gsd_litvert_func(Octo[0], colr, Octo[0]);
382  gsd_litvert_func(Octo[1], colr, Octo[1]);
383  gsd_swaptmesh();
384  gsd_litvert_func(Octo[2], colr, Octo[2]);
385  gsd_swaptmesh();
386  gsd_litvert_func(Octo[4], colr, Octo[4]);
387  gsd_swaptmesh();
388  gsd_litvert_func(Octo[5], colr, Octo[5]);
389  gsd_swaptmesh();
390  gsd_litvert_func(Octo[1], colr, Octo[1]);
391  gsd_litvert_func(Octo[3], colr, Octo[3]);
392  gsd_litvert_func(Octo[2], colr, Octo[2]);
393  gsd_swaptmesh();
394  gsd_litvert_func(Octo[4], colr, Octo[4]);
395  gsd_swaptmesh();
396  gsd_litvert_func(Octo[5], colr, Octo[5]);
397  gsd_swaptmesh();
398  gsd_litvert_func(Octo[1], colr, Octo[1]);
399  gsd_endtmesh();
400  }
401 #endif
402 
403  gsd_popmatrix();
404  gsd_shademodel(preshade);
405 
406  return;
407 }
408 
409 /**
410  * @brief Draws a cube symbol at the specified center location.
411  *
412  * This function renders a cube symbol at the given center
413  * coordinates with the specified color and size.
414  *
415  * Added by Hamish Bowman Nov 2005
416  *
417  * @param center Pointer to a float array representing the (x, y, z) coordinates
418  * of the center point.
419  * @param colr Integer representing the color to use for drawing the symbol.
420  * @param siz Size of the symbol.
421  */
422 void gsd_cube(float *center, unsigned long colr, float siz)
423 {
424  int preshade;
425 
426  /* see gsd_diamond() "seems right, but isn't" */
427  siz *= .5;
428 
429  gsd_pushmatrix();
430  gsd_translate(center[X], center[Y], center[Z]);
431  gsd_scale(siz, siz, siz);
432  preshade = gsd_getshademodel();
433  gsd_shademodel(0); /* want flat shading */
434 
435  /* N wall: */
436  gsd_bgnpolygon();
441  gsd_endpolygon();
442 
443  /* S wall: */
444  gsd_bgnpolygon();
449  gsd_endpolygon();
450 
451  /* E wall: */
452  gsd_bgnpolygon();
457  gsd_endpolygon();
458 
459  /* W wall: */
460  gsd_bgnpolygon();
465  gsd_endpolygon();
466 
467  /* lower wall: */
468  gsd_bgnpolygon();
473  gsd_endpolygon();
474 
475  /* top wall: */
476  gsd_bgnpolygon();
481  gsd_endpolygon();
482 
483  gsd_popmatrix();
484  gsd_shademodel(preshade);
485 
486  return;
487 }
488 
489 /**
490  * @brief Draws a box symbol at the specified center location.
491  *
492  * This function renders a box symbol at the given center
493  * coordinates with the specified color and size.
494  *
495  * Added by Hamish Bowman Nov 2005
496  *
497  * @param center Pointer to a float array representing the (x, y, z) coordinates
498  * of the center point.
499  * @param colr Integer representing the color to use for drawing the symbol.
500  * @param siz Size of the symbol.
501  */
502 void gsd_draw_box(float *center, unsigned long colr, float siz)
503 {
504 
505  /* see gsd_diamond() "seems right, but isn't" */
506  siz *= .5;
507 
508  gsd_pushmatrix();
509  gsd_translate(center[X], center[Y], center[Z]);
510  gsd_scale(siz, siz, siz);
511  gsd_color_func(colr);
512 
513  gsd_bgnline(); /* N wall */
519  gsd_endline();
520 
521  gsd_bgnline(); /* S wall */
527  gsd_endline();
528 
529  gsd_bgnline();
532  gsd_endline();
533 
534  gsd_bgnline();
537  gsd_endline();
538 
539  gsd_bgnline();
542  gsd_endline();
543 
544  gsd_bgnline();
547  gsd_endline();
548 
549  gsd_popmatrix();
550 
551  return;
552 }
553 
554 /**
555  * @brief Draws a sphere at the specified center location.
556  *
557  * This function renders a sphere at the given center
558  * coordinates with the specified color and size.
559  *
560  * @param center Pointer to a float array representing the (x, y, z) coordinates
561  * of the center point.
562  * @param colr Integer representing the color to use for drawing the sphere.
563  * @param siz Size of the sphere.
564  */
565 void gsd_drawsphere(float *center, unsigned long colr, float siz)
566 {
567  siz *= .5; /* siz is diameter, gsd_sphere uses radius */
568  gsd_color_func(colr);
569  gsd_sphere(center, siz);
570 
571  return;
572 }
573 
574 /*!
575  \brief Draw diamond lines
576  */
578 {
579  gsd_bgnline();
580  gsd_vert_func(Octo[0]);
581  gsd_vert_func(Octo[3]);
582  gsd_endline();
583 
584  gsd_bgnline();
585  gsd_vert_func(Octo[1]);
586  gsd_vert_func(Octo[4]);
587  gsd_endline();
588 
589  gsd_bgnline();
590  gsd_vert_func(Octo[2]);
591  gsd_vert_func(Octo[5]);
592  gsd_endline();
593 
594  return;
595 }
596 
597 /**
598  * @brief Draws an asterisk symbol at the specified center location.
599  *
600  * This function renders an asterisk symbol at the given center
601  * coordinates with the specified color and size.
602  *
603  * @param center Pointer to a float array representing the (x, y, z) coordinates
604  * of the center point.
605  * @param colr Integer representing the color to use for drawing the symbol.
606  * @param siz Size of the symbol.
607  */
608 void gsd_draw_asterisk(float *center, unsigned long colr, float siz)
609 {
610  float angle;
611 
612  angle = 45.; /* degrees */
613 
614  gsd_pushmatrix();
615  gsd_translate(center[X], center[Y], center[Z]);
616  gsd_scale(siz, siz, siz);
617  gsd_color_func(colr);
618 
620 
621  gsd_pushmatrix();
622  gsd_rot(angle, 'x');
624  gsd_popmatrix();
625 
626  gsd_pushmatrix();
627  gsd_rot(-angle, 'x');
629  gsd_popmatrix();
630 
631  gsd_pushmatrix();
632  gsd_rot(angle, 'y');
634  gsd_popmatrix();
635 
636  gsd_pushmatrix();
637  gsd_rot(-angle, 'y');
639  gsd_popmatrix();
640 
641  gsd_pushmatrix();
642  gsd_rot(angle, 'z');
644  gsd_popmatrix();
645 
646  gsd_pushmatrix();
647  gsd_rot(-angle, 'z');
649  gsd_popmatrix();
650 
651  gsd_popmatrix();
652 
653  return;
654 }
655 
656 /**
657  * @brief Draws a gyro symbol at the specified center location.
658  *
659  * This function renders a gyro symbol at the given center
660  * coordinates with the specified color and size.
661  *
662  * @param center Pointer to a float array representing the (x, y, z) coordinates
663  * of the center point.
664  * @param colr Integer representing the color to use for drawing the symbol.
665  * @param siz Size of the symbol.
666  */
667 void gsd_draw_gyro(float *center, unsigned long colr, float siz)
668 {
669  int i;
670 
671  gsd_pushmatrix();
672  gsd_translate(center[X], center[Y], center[Z]);
673  gsd_scale(siz, siz, siz);
674  gsd_color_func(colr);
675 
676  /* vert axis */
677  gsd_bgnline();
678  gsd_vert_func(Octo[2]);
679  gsd_vert_func(Octo[5]);
680  gsd_endline();
681 
682  /* spokes */
683  gsd_pushmatrix();
684 
685  for (i = 0; i < 6; i++) {
686  gsd_rot(30., 'z');
687  gsd_bgnline();
688  gsd_vert_func(Octo[0]);
689  gsd_vert_func(Octo[3]);
690  gsd_endline();
691  }
692 
693  gsd_popmatrix();
694 
695  gsd_color_func(colr);
696 
697  gsd_circ(0., 0., 1.);
698 
699  gsd_pushmatrix();
700  gsd_rot(90., 'x');
701  gsd_circ(0., 0., 1.);
702  gsd_popmatrix();
703 
704  gsd_pushmatrix();
705  gsd_rot(90., 'y');
706  gsd_circ(0., 0., 1.);
707  gsd_popmatrix();
708 
709  gsd_popmatrix();
710 
711  return;
712 }
713 
714 /**
715  * @brief Draw 3d cursor
716  *
717  * @param[in] pt point
718  */
719 void gsd_3dcursor(float *pt)
720 {
721  float big, vert[3];
722 
723  big = 10000.;
724 
725  gsd_bgnline();
726  vert[X] = pt[X];
727  vert[Y] = pt[Y];
728  vert[Z] = big;
729  gsd_vert_func(vert);
730  vert[Z] = -big;
731  gsd_vert_func(vert);
732  gsd_endline();
733 
734  gsd_bgnline();
735  vert[X] = pt[X];
736  vert[Z] = pt[Z];
737  vert[Y] = big;
738  gsd_vert_func(vert);
739  vert[Y] = -big;
740  gsd_vert_func(vert);
741  gsd_endline();
742 
743  gsd_bgnline();
744  vert[Y] = pt[Y];
745  vert[Z] = pt[Z];
746  vert[X] = big;
747  gsd_vert_func(vert);
748  vert[X] = -big;
749  gsd_vert_func(vert);
750  gsd_endline();
751 
752  return;
753 }
754 
755 /**
756  * @brief Converts a direction vector to slope and aspect angles.
757  *
758  * Given a 3D direction vector, this function computes the slope and aspect
759  * angles corresponding to the vector. The aspect is the compass direction
760  * (azimuth) of the projection of the vector onto the XY plane, and the slope
761  * is the angle between the vector and the vertical axis (Z).
762  *
763  * @param[in] dir Pointer to an array of 3 floats representing the
764  * direction vector [dx, dy, dz].
765  * @param[out] slope Pointer to a float where the computed slope angle will be
766  * stored (in radians or degrees).
767  * @param[out] aspect Pointer to a float where the computed aspect angle will
768  * be stored (in radians or degrees).
769  * @param[in] degrees If non-zero, the output angles are converted to degrees;
770  * otherwise, they are in radians.
771  *
772  * The function handles edge cases where the direction vector is vertical or
773  * horizontal. Aspect is set to 0 if the vector has no horizontal component.
774  * Slope is negative for upward-pointing vectors, positive for downward.
775  */
776 void dir_to_slope_aspect(float *dir, float *slope, float *aspect, int degrees)
777 {
778  float dx, dy, dz;
779  float costheta, theta, adjacent;
780 
781  dx = dir[X];
782  dy = dir[Y];
783  dz = dir[Z];
784 
785  /* project vector <dx,dy,dz> onto plane of constant z containing
786  * final value should be 0.0 to 3600.0 */
787  if (dx == 0 && dy == 0) {
788  *aspect = 0.;
789  }
790  else {
791  if (dx == 0) {
792  theta = 90.0;
793  }
794  else {
795  costheta = dx / sqrt(dx * dx + dy * dy);
796  theta = acos(costheta);
797  }
798 
799  if (dy < 0) {
800  theta = (2 * Pi) - theta;
801  }
802 
803  *aspect = theta;
804  }
805 
806  /* project vector <dx,dy,dz> onto plane of constant y containing
807  * final value should be -900.0 (looking up) to 900.0 (looking down) */
808  if (dz == 0) {
809  theta = 0.0;
810  }
811  else if (dx == 0 && dy == 0) {
812  theta = Pi / 2.;
813  }
814  else {
815  adjacent = sqrt(dx * dx + dy * dy);
816  costheta = adjacent / sqrt(adjacent * adjacent + dz * dz);
817  theta = acos(costheta);
818  }
819 
820  if (dz > 0) {
821  theta = -theta;
822  }
823 
824  *slope = theta;
825 
826  if (degrees) {
827  *aspect = *aspect * (180. / Pi);
828  *slope = *slope * (180. / Pi);
829  }
830 
831  return;
832 }
833 
834 /**
835  * @brief Draw North Arrow
836  *
837  * Takes OpenGL coords and size
838  *
839  * @param pos2 Pointer to a float array representing the position as a
840  * 3D vector (X,Y,Z).
841  * @param len
842  * @param fontbase
843  * @param arw_clr north arrow color
844  * @param text_clr text color
845  *
846  * @return 1
847  *
848  * @todo Store arrow somewhere to enable it's removal/change.
849  * @todo Add option to specify north text and font.
850  */
851 int gsd_north_arrow(float *pos2, float len, GLuint fontbase,
852  unsigned long arw_clr, unsigned long text_clr)
853 {
854  const char *txt;
855  float v[4][3];
856  float base[3][3];
857  float Ntop[] = {0.0, 0.0, 1.0};
858 
859  base[0][Z] = base[1][Z] = base[2][Z] = pos2[Z];
860  v[0][Z] = v[1][Z] = v[2][Z] = v[3][Z] = pos2[Z];
861 
862  base[0][X] = pos2[X] - len / 16.;
863  base[1][X] = pos2[X] + len / 16.;
864  base[0][Y] = base[1][Y] = pos2[Y] - len / 2.;
865  base[2][X] = pos2[X];
866  base[2][Y] = pos2[Y] + .45 * len;
867 
868  v[0][X] = v[2][X] = pos2[X];
869  v[1][X] = pos2[X] + len / 8.;
870  v[3][X] = pos2[X] - len / 8.;
871  v[0][Y] = pos2[Y] + .2 * len;
872  v[1][Y] = v[3][Y] = pos2[Y] + .1 * len;
873  v[2][Y] = pos2[Y] + .5 * len;
874 
875  /* make sure we are drawing in front buffer */
877 
878  gsd_pushmatrix();
879  gsd_do_scale(1);
880 
881  glNormal3fv(Ntop);
882  gsd_color_func(arw_clr);
883 
884  gsd_bgnpolygon();
885  glVertex3fv(base[0]);
886  glVertex3fv(base[1]);
887  glVertex3fv(base[2]);
888  gsd_endpolygon();
889 
890  gsd_bgnpolygon();
891  glVertex3fv(v[0]);
892  glVertex3fv(v[1]);
893  glVertex3fv(v[2]);
894  glVertex3fv(v[0]);
895  gsd_endpolygon();
896 
897  gsd_bgnpolygon();
898  glVertex3fv(v[0]);
899  glVertex3fv(v[2]);
900  glVertex3fv(v[3]);
901  glVertex3fv(v[0]);
902  gsd_endpolygon();
903 
904  /* draw N for North */
905  /* Need to pick a nice generic font */
906  /* TODO -- project text position off arrow
907  * bottom along azimuth
908  */
909 
910  gsd_color_func(text_clr);
911  txt = "North";
912  /* adjust position of N text */
913  base[0][X] -= gsd_get_txtwidth(txt, 18) - 20.;
914  base[0][Y] -= gsd_get_txtheight(18) - 20.;
915 
916  glRasterPos3fv(base[0]);
917  glListBase(fontbase);
918  glCallLists(strlen(txt), GL_UNSIGNED_BYTE, (const GLvoid *)txt);
919  GS_done_draw();
920 
921  gsd_popmatrix();
922  gsd_flush();
923 
924  return (1);
925 }
926 
927 /**
928  * @brief Draws an arrow
929  *
930  * siz is height, sz is global exag to correct for.
931  *
932  * If onsurf in non-null, z component of dir is dropped and
933  * line-on-suf is used, resulting in length of arrow being proportional
934  * to slope.
935  *
936  * @param center Pointer to a float array representing the (x, y, z) coordinates
937  * of the center point.
938  * @param colr Integer representing the color to use for drawing the arrow.
939  * @param siz Size of the arrow.
940  * @param dir Direction of the arrow. Pointer to a float array representing the
941  * 3D vector (X,Y,Z).
942  * @param sz height, sz is global exag to correct for.
943  * @param onsurf surface (geosurf).
944  *
945  * @return 1 no surface given
946  * @return 0 on surface
947  */
948 int gsd_arrow(float *center, unsigned long colr, float siz, float *dir,
949  float sz, geosurf *onsurf)
950 {
951  float slope, aspect;
952  float tmp[3];
953  static int first = 1;
954 
955  if (first) {
956  init_stuff();
957  first = 0;
958  }
959 
960  dir[Z] /= sz;
961 
962  GS_v3norm(dir);
963 
964  if (NULL != onsurf) {
965  float base[3], tip[3], len;
966 
967  base[X] = center[X];
968  base[Y] = center[Y];
969 
970  /* project dir to surface, after zexag */
971  len = GS_P2distance(ORIGIN, dir); /* in case dir isn't normalized */
972  tip[X] = center[X] + dir[X] * len * siz;
973  tip[Y] = center[Y] + dir[Y] * len * siz;
974 
975  return gsd_arrow_onsurf(base, tip, colr, 2, onsurf);
976  }
977 
978  dir_to_slope_aspect(dir, &slope, &aspect, 1);
979 
980  gsd_pushmatrix();
981  gsd_translate(center[X], center[Y], center[Z]);
982  gsd_scale(1.0, 1.0, 1.0 / sz);
983  gsd_rot(aspect + 90, 'z');
984  gsd_rot(slope + 90., 'x');
985  gsd_scale(siz, siz, siz);
986  gsd_color_func(colr);
987 
988  tmp[X] = 0.2;
989  tmp[Y] = 0.0;
990  tmp[Z] = 0.65;
991 
992  gsd_bgnline();
995  gsd_endline();
996 
997  gsd_bgnline();
998  gsd_vert_func(tmp);
1000  tmp[X] = -0.2;
1001  gsd_vert_func(tmp);
1002  gsd_endline();
1003 
1004  gsd_popmatrix();
1005 
1006  return (1);
1007 }
1008 
1009 /**
1010  * @brief Draw north arrow on surface
1011  *
1012  * @param base Pointer to a float array representing the base as a
1013  * 2D vector (X,Y).
1014  * @param tip Pointer to a float array representing the tip as a
1015  * 2D vector (X,Y).
1016  * @param colr Integer representing the color to use for drawing the arrow.
1017  * @param wid Line width (see \ref gsd_linewidth)
1018  * @param gs surface (geosurf)
1019  *
1020  * @return 0
1021  */
1022 int gsd_arrow_onsurf(float *base, float *tip, unsigned long colr, int wid,
1023  geosurf *gs)
1024 {
1025  static int first = 1;
1026 
1027  if (first) {
1028  init_stuff();
1029  first = 0;
1030  }
1031 
1032  gsd_linewidth(wid);
1033  gsd_color_func(colr);
1034 
1035  G_debug(3, "gsd_arrow_onsurf");
1036  G_debug(3, " %f %f -> %f %f", base[X], base[Y], tip[X], tip[Y]);
1037 
1038  gsd_line_onsurf(gs, base, tip);
1039 
1040 #ifdef DO_SPHERE_BASE
1041  {
1042  GS_v3dir(tip, base, dir0);
1043  GS_v3mag(dir0, &len);
1044  gsd_disc(base[X], base[Y], len / 10.);
1045  }
1046 #endif
1047 
1048 #ifdef ARROW_READY
1049  {
1050  base[Z] = tip[Z] = 0.0;
1051  GS_v3dir(tip, base, dir0);
1052 
1053  G_debug(3, " dir0: %f %f %f", dir0[X], dir0[Y], dir0[Z]);
1054 
1055  /* rotate this direction 90 degrees */
1056  GS_v3cross(dir0, UP_NORM, dir2);
1057  GS_v3mag(dir0, &len);
1058  GS_v3eq(dir1, dir0);
1059 
1060  G_debug(3, " len: %f", len);
1061  G_debug(3, " a-dir1: %f %f %f", dir1[X], dir1[Y], dir1[Z]);
1062  G_debug(3, " a-dir2: %f %f %f", dir2[X], dir2[Y], dir2[Z]);
1063 
1064  dim1 = len * .7;
1065  dim2 = len * .2;
1066  GS_v3mult(dir1, dim1);
1067  GS_v3mult(dir2, dim2);
1068 
1069  G_debug(3, " b-dir1: %f %f %f", dir1[X], dir1[Y], dir1[Z]);
1070  G_debug(3, " b-dir2: %f %f %f", dir2[X], dir2[Y], dir2[Z]);
1071 
1072  GS_v3eq(tmp, base);
1073  GS_v3add(tmp, dir1);
1074  GS_v3add(tmp, dir2);
1075 
1076  G_debug(3, " %f %f -> ", tmp[X], tmp[Y]);
1077 
1078  gsd_line_onsurf(gs, tmp, tip);
1079 
1080  GS_v3cross(dir0, DOWN_NORM, dir2);
1081  GS_v3mult(dir2, dim2);
1082  GS_v3eq(tmp, base);
1083 
1084  G_debug(3, " dir1: %f %f %f", dir1[X], dir1[Y], dir1[Z]);
1085  G_debug(3, " dir2: %f %f %f", dir2[X], dir2[Y], dir2[Z]);
1086 
1087  GS_v3add(tmp, dir1);
1088  GS_v3add(tmp, dir2);
1089 
1090  G_debug(3, " %f %f", tmp[X], tmp[Y]);
1091 
1092  gsd_line_onsurf(gs, tip, tmp);
1093  }
1094 #endif
1095 
1096  return (0);
1097 }
1098 
1099 /**
1100  * @brief Draw 3d north arrow
1101  *
1102  * @param center Pointer to a float array representing the (x, y, z) coordinates
1103  * of the center point.
1104  * @param colr Integer representing the color to use for drawing the arrow.
1105  * @param siz1 size
1106  * @param siz2 size
1107  * @param dir Direction of the arrow. Pointer to a float array representing the
1108  * 3D vector (X,Y,Z).
1109  * @param sz height
1110  */
1111 void gsd_3darrow(float *center, unsigned long colr, float siz1, float siz2,
1112  float *dir, float sz)
1113 {
1114  float slope, aspect;
1115  int preshade;
1116  static int first = 1;
1117  static int list;
1118  static int debugint = 1;
1119 
1120  dir[Z] /= sz;
1121 
1122  GS_v3norm(dir);
1123  dir_to_slope_aspect(dir, &slope, &aspect, 1);
1124 
1125  if (debugint > 100) {
1126  G_debug(3, "gsd_3darrow()");
1127  G_debug(3, " pt: %f,%f,%f dir: %f,%f,%f slope: %f aspect: %f",
1128  center[X], center[Y], center[Z], dir[X], dir[Y], dir[Z], slope,
1129  aspect);
1130  debugint = 1;
1131  }
1132  debugint++;
1133 
1134  preshade = gsd_getshademodel();
1135 
1136  /*
1137  gsd_shademodel(0);
1138  want flat shading? */
1139  gsd_pushmatrix();
1140  gsd_translate(center[X], center[Y], center[Z]);
1141  gsd_scale(1.0, 1.0, 1.0 / sz);
1142  gsd_rot(aspect + 90, 'z');
1143  gsd_rot(slope + 90., 'x');
1144  gsd_scale(siz2, siz2, siz1);
1145  gsd_color_func(colr);
1146 
1147  if (first) {
1148  /* combine these into an object */
1149  first = 0;
1150  list = gsd_makelist();
1151  gsd_bgnlist(list, 1);
1152  gsd_backface(1);
1153 
1154  gsd_pushmatrix();
1155  gsd_scale(.10, .10, .75); /* narrow cyl */
1156  primitive_cylinder(colr, 0);
1157  gsd_popmatrix();
1158 
1159  gsd_pushmatrix();
1160  gsd_translate(0.0, 0.0, .60);
1161  gsd_scale(0.3, 0.3, 0.4); /* cone */
1162  primitive_cone(colr);
1163  gsd_popmatrix();
1164 
1165  gsd_backface(0);
1166  gsd_endlist();
1167  }
1168  else {
1169  gsd_calllist(list);
1170  }
1171 
1172  gsd_popmatrix();
1173  gsd_shademodel(preshade);
1174 
1175  return;
1176 }
1177 
1178 /**
1179  * @brief Draw Scalebar takes OpenGL coords and size
1180  *
1181  * Adapted from gsd_north_arrow Hamish Bowman Dec 2006
1182  *
1183  * @param pos2 Pointer to a float array representing the scalebar position as a
1184  * 3D vector (X,Y,Z).
1185  * @param len
1186  * @param fontbase font-base
1187  * @param bar_clr barscale color.
1188  * Integer representing the color to use for the barscale.
1189  * @param text_clr test color.
1190  * Integer representing the color to use for the text.
1191  * @return 1
1192  */
1193 int gsd_scalebar(float *pos2, float len, GLuint fontbase, unsigned long bar_clr,
1194  unsigned long text_clr)
1195 {
1196  char txt[100];
1197  float base[4][3];
1198  float Ntop[] = {0.0, 0.0, 1.0};
1199 
1200  base[0][Z] = base[1][Z] = base[2][Z] = base[3][Z] = pos2[Z];
1201 
1202  /* simple 1:8 rectangle */ /* bump to X/20. for a 1:10 narrower bar? */
1203  base[0][X] = base[1][X] = pos2[X] - len / 2.;
1204  base[2][X] = base[3][X] = pos2[X] + len / 2.;
1205 
1206  base[0][Y] = base[3][Y] = pos2[Y] - len / 16.;
1207  base[1][Y] = base[2][Y] = pos2[Y] + len / 16.;
1208 
1209  /* make sure we are drawing in front buffer */
1211 
1212  gsd_pushmatrix();
1213  gsd_do_scale(1); /* get map scale factor */
1214 
1215  glNormal3fv(Ntop);
1216 
1217  gsd_color_func(bar_clr);
1218 
1219  gsd_bgnpolygon();
1220  glVertex3fv(base[0]);
1221  glVertex3fv(base[1]);
1222  glVertex3fv(base[2]);
1223  glVertex3fv(base[3]);
1224  glVertex3fv(base[0]);
1225  gsd_endpolygon();
1226 
1227  /* draw units */
1228  /* Need to pick a nice generic font */
1229  /* TODO -- project text position off bar bottom along azimuth */
1230 
1231  gsd_color_func(text_clr);
1232 
1233  /* format text in a nice way */
1234  if (strcmp("meters", G_database_unit_name(TRUE)) == 0) {
1235  if (len > 2500)
1236  snprintf(txt, sizeof(txt), "%g km", len / 1000);
1237  else
1238  snprintf(txt, sizeof(txt), "%g meters", len);
1239  }
1240  else if (strcmp("feet", G_database_unit_name(TRUE)) == 0) {
1241  if (len > 5280)
1242  snprintf(txt, sizeof(txt), "%g miles", len / 5280);
1243  else if (len == 5280)
1244  snprintf(txt, sizeof(txt), "1 mile");
1245  else
1246  snprintf(txt, sizeof(txt), "%g feet", len);
1247  }
1248  else {
1249  snprintf(txt, sizeof(txt), "%g %s", len, G_database_unit_name(TRUE));
1250  }
1251 
1252  /* adjust position of text (In map units?!) */
1253  base[0][X] -= gsd_get_txtwidth(txt, 18) - 20.;
1254  base[0][Y] -= gsd_get_txtheight(18) - 20.;
1255 
1256  glRasterPos3fv(base[0]);
1257  glListBase(fontbase);
1258  glCallLists(strlen(txt), GL_BYTE, (GLubyte *)txt);
1259  GS_done_draw();
1260 
1261  gsd_popmatrix();
1262  gsd_flush();
1263 
1264  return (1);
1265 }
1266 
1267 /**
1268  * @brief Draw Scalebar (as lines)
1269  *
1270  * Adapted from gsd_scalebar A.Kratochvilova 2011
1271  *
1272  * @param pos Pointer to a float array representing the scalebar position as a
1273  * 3D vector (X,Y,Z).
1274  * @param len
1275  * @param fontbase font-base (unused)
1276  * @param bar_clr barscale color.
1277  * Integer representing the color to use for the barscale.
1278  * @param text_clr Text color (unused).
1279  * Integer representing the color to use for the text.
1280  * @return 1
1281  */
1282 int gsd_scalebar_v2(float *pos, float len, GLuint fontbase UNUSED,
1283  unsigned long bar_clr, unsigned long text_clr UNUSED)
1284 {
1285  float base[6][3];
1286  float Ntop[] = {0.0, 0.0, 1.0};
1287 
1288  base[0][Z] = base[1][Z] = base[2][Z] = pos[Z];
1289  base[3][Z] = base[4][Z] = base[5][Z] = pos[Z];
1290 
1291  /* simple scalebar: |------| */
1292  base[0][X] = base[2][X] = base[3][X] = pos[X] - len / 2.;
1293  base[1][X] = base[4][X] = base[5][X] = pos[X] + len / 2.;
1294  base[0][Y] = base[1][Y] = pos[Y];
1295  base[2][Y] = base[4][Y] = pos[Y] - len / 12;
1296  base[3][Y] = base[5][Y] = pos[Y] + len / 12;
1297 
1298  /* make sure we are drawing in front buffer */
1300 
1301  gsd_pushmatrix();
1302  gsd_do_scale(1); /* get map scale factor */
1303 
1304  glNormal3fv(Ntop);
1305 
1306  gsd_color_func(bar_clr);
1307 
1308  gsd_linewidth(3); /* could be optional */
1309 
1310  /* ------- */
1311  gsd_bgnline();
1312  gsd_vert_func(base[0]);
1313  gsd_vert_func(base[1]);
1314  gsd_endline();
1315 
1316  /* |------- */
1317  gsd_bgnline();
1318  gsd_vert_func(base[2]);
1319  gsd_vert_func(base[3]);
1320  gsd_endline();
1321 
1322  /* |-------| */
1323  gsd_bgnline();
1324  gsd_vert_func(base[4]);
1325  gsd_vert_func(base[5]);
1326  gsd_endline();
1327 
1328  /* TODO -- draw units */
1329 
1330  GS_done_draw();
1331 
1332  gsd_popmatrix();
1333  gsd_flush();
1334 
1335  return 1;
1336 }
1337 
1338 /**
1339  * @brief Primitives only called after transforms
1340  *
1341  * Center is actually center at base of 8 sided cone
1342  *
1343  * @param colr Integer representing the color to use for drawing the cone.
1344  */
1345 void primitive_cone(unsigned long colr)
1346 {
1347  float tip[3];
1348  static int first = 1;
1349 
1350  if (first) {
1351  init_stuff();
1352  first = 0;
1353  }
1354 
1355  tip[X] = tip[Y] = 0.0;
1356  tip[Z] = 1.0;
1357 
1358  gsd_bgntfan();
1359  gsd_litvert_func2(UP_NORM, colr, tip);
1360  gsd_litvert_func2(ogverts[0], colr, ogverts[0]);
1361  gsd_litvert_func2(ogverts[1], colr, ogverts[1]);
1362  gsd_litvert_func2(ogverts[2], colr, ogverts[2]);
1363  gsd_litvert_func2(ogverts[3], colr, ogverts[3]);
1364  gsd_litvert_func2(ogverts[4], colr, ogverts[4]);
1365  gsd_litvert_func2(ogverts[5], colr, ogverts[5]);
1366  gsd_litvert_func2(ogverts[6], colr, ogverts[6]);
1367  gsd_litvert_func2(ogverts[7], colr, ogverts[7]);
1368  gsd_litvert_func2(ogverts[0], colr, ogverts[0]);
1369  gsd_endtfan();
1370 
1371  return;
1372 }
1373 
1374 /**
1375  * @brief Primitives only called after transforms
1376  *
1377  * Center is actually center at base of 8 sided cylinder
1378  *
1379  * @param colr Integer representing the color to use for drawing the cylinder.
1380  * @param caps If non zero, draw caps at the bottom and top of the cylinder.
1381  */
1382 void primitive_cylinder(unsigned long colr, int caps)
1383 {
1384  static int first = 1;
1385 
1386  if (first) {
1387  init_stuff();
1388  first = 0;
1389  }
1390 
1391  gsd_bgnqstrip();
1392  gsd_litvert_func2(ogverts[0], colr, ogvertsplus[0]);
1393  gsd_litvert_func2(ogverts[0], colr, ogverts[0]);
1394  gsd_litvert_func2(ogverts[1], colr, ogvertsplus[1]);
1395  gsd_litvert_func2(ogverts[1], colr, ogverts[1]);
1396  gsd_litvert_func2(ogverts[2], colr, ogvertsplus[2]);
1397  gsd_litvert_func2(ogverts[2], colr, ogverts[2]);
1398  gsd_litvert_func2(ogverts[3], colr, ogvertsplus[3]);
1399  gsd_litvert_func2(ogverts[3], colr, ogverts[3]);
1400  gsd_litvert_func2(ogverts[4], colr, ogvertsplus[4]);
1401  gsd_litvert_func2(ogverts[4], colr, ogverts[4]);
1402  gsd_litvert_func2(ogverts[5], colr, ogvertsplus[5]);
1403  gsd_litvert_func2(ogverts[5], colr, ogverts[5]);
1404  gsd_litvert_func2(ogverts[6], colr, ogvertsplus[6]);
1405  gsd_litvert_func2(ogverts[6], colr, ogverts[6]);
1406  gsd_litvert_func2(ogverts[7], colr, ogvertsplus[7]);
1407  gsd_litvert_func2(ogverts[7], colr, ogverts[7]);
1408  gsd_litvert_func2(ogverts[0], colr, ogvertsplus[0]);
1409  gsd_litvert_func2(ogverts[0], colr, ogverts[0]);
1410  gsd_endqstrip();
1411 
1412  if (caps) {
1413  /* draw top */
1414  gsd_bgntfan();
1425  gsd_endtfan();
1426 
1427  /* draw bottom */
1428  gsd_bgntfan();
1430  gsd_litvert_func2(DOWN_NORM, colr, ogverts[0]);
1431  gsd_litvert_func2(DOWN_NORM, colr, ogverts[1]);
1432  gsd_litvert_func2(DOWN_NORM, colr, ogverts[2]);
1433  gsd_litvert_func2(DOWN_NORM, colr, ogverts[3]);
1434  gsd_litvert_func2(DOWN_NORM, colr, ogverts[4]);
1435  gsd_litvert_func2(DOWN_NORM, colr, ogverts[5]);
1436  gsd_litvert_func2(DOWN_NORM, colr, ogverts[6]);
1437  gsd_litvert_func2(DOWN_NORM, colr, ogverts[7]);
1438  gsd_litvert_func2(DOWN_NORM, colr, ogverts[0]);
1439  gsd_endtfan();
1440  }
1441 
1442  return;
1443 }
1444 
1445 /*** ACS_MODIFY_BEGIN - sites_attribute management
1446  * ********************************/
1447 /*
1448  Draws boxes that are used for histograms by \ref gpd_obj function in gpd.c
1449  for site_attribute management
1450  */
1451 
1452 /**
1453  * @brief Vertices for box
1454  */
1455 float Box[8][3] = {{1.0, 1.0, -1.0}, {-1.0, 1.0, -1.0}, {-1.0, 1.0, 1.0},
1456  {1.0, 1.0, 1.0}, {1.0, -1.0, -1.0}, {-1.0, -1.0, -1.0},
1457  {-1.0, -1.0, 1.0}, {1.0, -1.0, 1.0}};
1458 
1459 float BoxN[6][3] = {{0, 0, -ONORM}, {0, 0, ONORM}, {0, ONORM, 0},
1460  {0, -ONORM, 0}, {ONORM, 0, 0}, {-ONORM, 0, 0}};
1461 
1462 /**
1463  * @brief Draws a box at the specified center location.
1464  *
1465  * This function renders a box at the given center
1466  * coordinates with the specified color and size.
1467  *
1468  * @warning siz is an array (we need it for scale only Z in histograms)
1469  *
1470  * @param center Pointer to a float array representing the (x, y, z) coordinates
1471  * of the center point.
1472  * @param colr Integer representing the color to use for drawing the symbol.
1473  * @param siz Size of the symbol.
1474  */
1475 void gsd_box(float *center, int colr, float *siz)
1476 {
1477  int preshade;
1478 
1479  gsd_pushmatrix();
1480  gsd_translate(center[X], center[Y], center[Z] + siz[2]);
1481  gsd_scale(siz[0], siz[1], siz[2]);
1482  preshade = gsd_getshademodel();
1483  gsd_shademodel(0); /* want flat shading */
1484 
1485  /* Top */
1486  gsd_bgnpolygon();
1487  gsd_litvert_func(BoxN[2], colr, Box[0]);
1488  gsd_litvert_func(BoxN[2], colr, Box[1]);
1489  gsd_litvert_func(BoxN[2], colr, Box[2]);
1490  gsd_litvert_func(BoxN[2], colr, Box[3]);
1491  gsd_endpolygon();
1492 
1493  /* Bottom */
1494  gsd_bgnpolygon();
1495  gsd_litvert_func(BoxN[3], colr, Box[7]);
1496  gsd_litvert_func(BoxN[3], colr, Box[6]);
1497  gsd_litvert_func(BoxN[3], colr, Box[5]);
1498  gsd_litvert_func(BoxN[3], colr, Box[4]);
1499  gsd_endpolygon();
1500 
1501  /* Right */
1502  gsd_bgnpolygon();
1503  gsd_litvert_func(BoxN[4], colr, Box[0]);
1504  gsd_litvert_func(BoxN[4], colr, Box[3]);
1505  gsd_litvert_func(BoxN[4], colr, Box[7]);
1506  gsd_litvert_func(BoxN[4], colr, Box[4]);
1507  gsd_endpolygon();
1508 
1509  /* Left */
1510  gsd_bgnpolygon();
1511  gsd_litvert_func(BoxN[5], colr, Box[1]);
1512  gsd_litvert_func(BoxN[5], colr, Box[5]);
1513  gsd_litvert_func(BoxN[5], colr, Box[6]);
1514  gsd_litvert_func(BoxN[5], colr, Box[2]);
1515  gsd_endpolygon();
1516 
1517  /* Front */
1518  gsd_bgnpolygon();
1519  gsd_litvert_func(BoxN[0], colr, Box[0]);
1520  gsd_litvert_func(BoxN[0], colr, Box[4]);
1521  gsd_litvert_func(BoxN[0], colr, Box[5]);
1522  gsd_litvert_func(BoxN[0], colr, Box[1]);
1523  gsd_endpolygon();
1524 
1525  /* Back */
1526  gsd_bgnpolygon();
1527  gsd_litvert_func(BoxN[1], colr, Box[3]);
1528  gsd_litvert_func(BoxN[1], colr, Box[2]);
1529  gsd_litvert_func(BoxN[1], colr, Box[6]);
1530  gsd_litvert_func(BoxN[1], colr, Box[7]);
1531  gsd_endpolygon();
1532 
1533  gsd_popmatrix();
1534  gsd_shademodel(preshade);
1535  return;
1536 }
1537 
1538 /*** ACS_MODIFY_END - sites_attribute management
1539  * ********************************/
#define NULL
Definition: ccmath.h:32
const char * G_database_unit_name(int)
Get units (localized) name for the current location.
Definition: proj3.c:53
int G_debug(int, const char *,...) __attribute__((format(printf
void gsd_endlist(void)
End list.
Definition: gsd_prim.c:1140
int GS_v3norm(float *)
Change v1 so that it is a unit vector (3D)
Definition: gs_util.c:246
void GS_v3mult(float *, float)
Multiple vectors.
Definition: gs_util.c:229
void gsd_endtfan(void)
ADD.
Definition: gsd_prim.c:347
void gsd_endtmesh(void)
ADD.
Definition: gsd_prim.c:307
void gsd_swaptmesh(void)
ADD.
Definition: gsd_prim.c:357
void gsd_pushmatrix(void)
Push the current matrix stack.
Definition: gsd_prim.c:511
void gsd_backface(int)
ADD.
Definition: gsd_prim.c:254
void GS_set_draw(int)
Sets which buffer to draw to.
Definition: gs2.c:2461
void gsd_scale(float, float, float)
Multiply the current matrix by a general scaling matrix.
Definition: gsd_prim.c:525
void gsd_do_scale(int)
Set current scale.
Definition: gsd_views.c:355
void gsd_bgnqstrip(void)
ADD.
Definition: gsd_prim.c:277
void GS_v3mag(float *, float *)
Magnitude of vector.
Definition: gs_util.c:418
void gsd_shademodel(int)
Set shaded model.
Definition: gsd_prim.c:419
float GS_P2distance(float *, float *)
Calculate distance in plane.
Definition: gs_util.c:160
void gsd_sphere(float *, float)
ADD.
Definition: gsd_prim.c:207
void gsd_circ(float, float, float)
ADD.
Definition: gsd_prim.c:167
void gsd_bgnpolygon(void)
Delimit the vertices of a primitive or a group of like primitives.
Definition: gsd_prim.c:372
void GS_v3add(float *, float *)
Sum vectors.
Definition: gs_util.c:195
void gsd_bgnlist(int, int)
ADD.
Definition: gsd_prim.c:1125
int gsd_getshademodel(void)
Get shaded model.
Definition: gsd_prim.c:438
int gsd_makelist(void)
ADD.
Definition: gsd_prim.c:1094
void gsd_calllist(int)
ADD.
Definition: gsd_prim.c:1173
void GS_v3eq(float *, float *)
Copy vector values.
Definition: gs_util.c:178
int gsd_get_txtwidth(const char *, int)
Get text width.
Definition: gsd_fonts.c:36
void gsd_endqstrip(void)
ADD.
Definition: gsd_prim.c:287
int gsd_get_txtheight(int size)
Get text height.
Definition: gsd_fonts.c:53
void gsd_color_func(unsigned int)
Set current color.
Definition: gsd_prim.c:698
Point3 * gsdrape_get_segments(geosurf *, float *, float *, int *)
ADD.
Definition: gsdrape.c:350
void gsd_translate(float, float, float)
Multiply the current matrix by a translation matrix.
Definition: gsd_prim.c:539
void gsd_popmatrix(void)
Pop the current matrix stack.
Definition: gsd_prim.c:501
void gsd_flush(void)
Mostly for flushing drawing commands across a network.
Definition: gsd_prim.c:84
void GS_v3cross(float *, float *, float *)
Get the cross product v3 = v1 cross v2.
Definition: gs_util.c:403
void gsd_linewidth(short)
Set width of rasterized lines.
Definition: gsd_prim.c:267
void gsd_endline(void)
End line.
Definition: gsd_prim.c:407
void gsd_bgntfan(void)
ADD.
Definition: gsd_prim.c:337
void gsd_disc(float, float, float, float)
ADD.
Definition: gsd_prim.c:187
int GS_v3dir(float *, float *, float *)
Get a normalized direction from v1 to v2, store in v3.
Definition: gs_util.c:351
void gsd_bgnline(void)
Begin line.
Definition: gsd_prim.c:397
void GS_done_draw(void)
Draw done, swap buffers.
Definition: gs2.c:2500
void gsd_rot(float, char)
ADD.
Definition: gsd_prim.c:605
void gsd_vert_func(float *)
ADD.
Definition: gsd_prim.c:686
void gsd_bgntmesh(void)
ADD.
Definition: gsd_prim.c:297
void gsd_litvert_func2(float *, unsigned long, float *)
ADD.
Definition: gsd_prim.c:673
void gsd_endpolygon(void)
Delimit the vertices of a primitive or a group of like primitives.
Definition: gsd_prim.c:387
void gsd_litvert_func(float *, unsigned long, float *)
Set the current normal vector & specify vertex.
Definition: gsd_prim.c:657
#define TRUE
Definition: gis.h:78
#define UNUSED
A macro for an attribute, if attached to a variable, indicating that the variable is not used.
Definition: gis.h:46
float Ntop[]
Definition: gsd_fringe.c:36
void gsd_3dcursor(float *pt)
Draw 3d cursor.
Definition: gsd_objs.c:719
void gsd_diamond(float *center, unsigned long colr, float siz)
Draws a diamond symbol at the specified center location.
Definition: gsd_objs.c:316
float Box[8][3]
Vertices for box.
Definition: gsd_objs.c:1455
void gsd_draw_box(float *center, unsigned long colr, float siz)
Draws a box symbol at the specified center location.
Definition: gsd_objs.c:502
#define UP_NORM
Definition: gsd_objs.c:68
float CubeNormals[3][3]
Definition: gsd_objs.c:60
void gsd_3darrow(float *center, unsigned long colr, float siz1, float siz2, float *dir, float sz)
Draw 3d north arrow.
Definition: gsd_objs.c:1111
float CubeVertices[8][3]
Definition: gsd_objs.c:62
#define DOWN_NORM
Definition: gsd_objs.c:69
void gsd_line_onsurf(geosurf *gs, float *v1, float *v2)
Line on surface, fix z-values.
Definition: gsd_objs.c:171
void primitive_cylinder(unsigned long colr, int caps)
Primitives only called after transforms.
Definition: gsd_objs.c:1382
int gsd_arrow(float *center, unsigned long colr, float siz, float *dir, float sz, geosurf *onsurf)
Draws an arrow.
Definition: gsd_objs.c:948
void gsd_x(geosurf *gs, float *center, int colr, float siz)
Draws a X symbol at the specified center location.
Definition: gsd_objs.c:263
float Pi
Definition: gsd_objs.c:82
#define ORIGIN
Definition: gsd_objs.c:70
void gsd_drawsphere(float *center, unsigned long colr, float siz)
Draws a sphere at the specified center location.
Definition: gsd_objs.c:565
int gsd_north_arrow(float *pos2, float len, GLuint fontbase, unsigned long arw_clr, unsigned long text_clr)
Draw North Arrow.
Definition: gsd_objs.c:851
float BoxN[6][3]
Definition: gsd_objs.c:1459
float ogverts[8][3]
vertices & normals for octagon in xy plane
Definition: gsd_objs.c:75
void gsd_cube(float *center, unsigned long colr, float siz)
Draws a cube symbol at the specified center location.
Definition: gsd_objs.c:422
int gsd_nline_onsurf(geosurf *gs, float *v1, float *v2, float *pt, int n)
Multiline on surface, fix z-values.
Definition: gsd_objs.c:216
void gsd_diamond_lines(void)
Draw diamond lines.
Definition: gsd_objs.c:577
int gsd_arrow_onsurf(float *base, float *tip, unsigned long colr, int wid, geosurf *gs)
Draw north arrow on surface.
Definition: gsd_objs.c:1022
int gsd_scalebar(float *pos2, float len, GLuint fontbase, unsigned long bar_clr, unsigned long text_clr)
Draw Scalebar takes OpenGL coords and size.
Definition: gsd_objs.c:1193
float OctoN[8][3]
normals for flat-shaded octahedron
Definition: gsd_objs.c:42
float ogvertsplus[8][3]
vertices for octagon in xy plane, z=1
Definition: gsd_objs.c:80
void dir_to_slope_aspect(float *dir, float *slope, float *aspect, int degrees)
Converts a direction vector to slope and aspect angles.
Definition: gsd_objs.c:776
float Octo[6][3]
vertices for octahedron
Definition: gsd_objs.c:34
int gsd_scalebar_v2(float *pos, float len, GLuint fontbase, unsigned long bar_clr, unsigned long text_clr)
Draw Scalebar (as lines)
Definition: gsd_objs.c:1282
void gsd_draw_asterisk(float *center, unsigned long colr, float siz)
Draws an asterisk symbol at the specified center location.
Definition: gsd_objs.c:608
void primitive_cone(unsigned long colr)
Primitives only called after transforms.
Definition: gsd_objs.c:1345
#define ONORM
Definition: gsd_objs.c:37
void gsd_box(float *center, int colr, float *siz)
Draws a box at the specified center location.
Definition: gsd_objs.c:1475
void gsd_draw_gyro(float *center, unsigned long colr, float siz)
Draws a gyro symbol at the specified center location.
Definition: gsd_objs.c:667
void gsd_plus(float *center, int colr, float siz)
Draws a plus sign symbol at the specified center location.
Definition: gsd_objs.c:134
float origin[3]
Definition: gsd_objs.c:66
OGSF header file (structures)
#define X
Definition: ogsf.h:140
float Point3[3]
Definition: ogsf.h:205
#define Z
Definition: ogsf.h:142
#define GSD_FRONT
Definition: ogsf.h:104
#define Y
Definition: ogsf.h:141
#define FUDGE(gs)
Definition: ogsf.h:179
struct list * list
Definition: read_list.c:24
Definition: ogsf.h:266
Definition: manage.h:4