GRASS 8 Programmer's Manual 8.6.0dev(2026)-1d1e47ad9d
Loading...
Searching...
No Matches
gs2.c
Go to the documentation of this file.
1/*!
2 \file lib/ogsf/gs2.c
3
4 \brief OGSF library - loading and manipulating surfaces (higher level
5 functions)
6
7 GRASS OpenGL gsurf OGSF Library
8
9 Plans for handling color maps:
10 NOW:
11 if able to load as unsigned char, make lookup table containing palette
12 otherwise, load directly as packed color, set lookup = NULL
13 MAYBE LATER:
14 if able to load as POSITIVE short, make lookup table containing palette
15 - may want to calculate savings first (ie, numcells > 32768)
16 (not exactly, it's Friday & time to go home - figure it later)
17 otherwise, load directly as packed color, set lookup = NULL
18 MESSY! - need to fix up!
19
20 (C) 1999-2008 by the GRASS Development Team
21
22 This program is free software under the
23 GNU General Public License (>=v2).
24 Read the file COPYING that comes with GRASS
25 for details.
26
27 \author Bill Brown USACERL (1993)
28 \author Pierre de Mouveaux <p_de_mouveaux hotmail.com> (updated October 1999)
29 \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
30 */
31
32#include <stdlib.h>
33#include <string.h>
34#include <math.h>
35
36#include <grass/config.h>
37
38#if defined(OPENGL_X11) || defined(OPENGL_WINDOWS)
39#include <GL/gl.h>
40#include <GL/glu.h>
41#elif defined(OPENGL_AQUA)
42#include <OpenGL/gl.h>
43#include <OpenGL/glu.h>
44#endif
45
46#include <grass/gis.h>
47#include <grass/raster.h>
48#include <grass/ogsf.h>
49#include <grass/glocale.h>
50
51#include "gsget.h"
52#include "rowcol.h"
53#include "rgbpack.h"
54
55/* Hack to make NVIZ2.2 query functions.("What's Here" and "Look at")
56 * to work.
57 * Uses gs_los_intersect1() instead of gs_los_intersect().
58 * Pierre de Mouveaux - 31 oct. 1999. p_de_mouveaux@hotmail.com.
59 */
60#define NVIZ_HACK 1
61
63
64/* array of surface ids */
65static int Surf_ID[MAX_SURFS];
66static int Next_surf = 0;
67static int SDref_surf = 0;
68
69/* attributes array */
70static float Default_const[MAX_ATTS];
71static float Default_nulls[MAX_ATTS];
72
73/* largest dimension */
74static float Longdim;
75
76/* N, S, W, E */
77static float Region[4];
78static geoview Gv;
79static geodisplay Gd;
80static struct Cell_head wind;
81static int Buffermode;
82static int Numlights = 0;
83static int Resetlight = 1;
84static int Modelshowing = 0;
85
86void void_func(void)
87{
88 return;
89}
90
91/*!
92 \brief Initialize OGSF library
93
94 Get region settings - wind
95
96 Set Region (NSWE array) and compute scale
97 */
98void GS_libinit(void)
99{
100 static int first = 1;
101
102 G_get_set_window(&wind);
103
104 Region[0] = wind.north;
105 Region[1] = wind.south;
106 Region[2] = wind.west;
107 Region[3] = wind.east;
108
109 /* scale largest dimension to GS_UNIT_SIZE */
110 if ((wind.east - wind.west) > (wind.north - wind.south)) {
111 Longdim = (wind.east - wind.west);
112 }
113 else {
114 Longdim = (wind.north - wind.south);
115 }
116
117 Gv.scale = GS_UNIT_SIZE / Longdim;
118
119 G_debug(1, "GS_libinit(): n=%f s=%f w=%f e=%f scale=%f first=%d", Region[0],
120 Region[1], Region[2], Region[3], Gv.scale, first);
121
123
124 if (first) {
125 gs_init();
126 }
127
128 first = 0;
129
130 return;
131}
132
133/*!
134 \brief Get largest dimension
135
136 \param[out] dim dimension
137
138 \return 1
139 */
140int GS_get_longdim(float *dim)
141{
142 *dim = Longdim;
143
144 G_debug(3, "GS_get_longdim(): dim=%g", *dim);
145
146 return (1);
147}
148
149/*!
150 \brief Get 2D region extent
151
152 \param[out] n,s,w,e extent values
153
154 \return 1
155 */
156int GS_get_region(float *n, float *s, float *w, float *e)
157{
158 *n = Region[0];
159 *s = Region[1];
160 *w = Region[2];
161 *e = Region[3];
162
163 return (1);
164}
165
166/*!
167 \brief Set default attributes for map objects
168
169 \param defs attributes array (dim MAX_ATTS)
170 \param null_defs null attributes array (dim MAX_ATTS)
171 */
173{
174 int i;
175
176 G_debug(3, "GS_set_att_defaults");
177
178 for (i = 0; i < MAX_ATTS; i++) {
179 Default_const[i] = defs[i];
180 Default_nulls[i] = null_defs[i];
181 }
182
183 return;
184}
185
186/*!
187 Check if surface exists
188
189 \param id surface id
190
191 \return 0 not found
192 \return 1 found
193 */
194int GS_surf_exists(int id)
195{
196 int i, found = 0;
197
198 G_debug(3, "GS_surf_exists(): id=%d", id);
199
200 if (NULL == gs_get_surf(id)) {
201 return (0);
202 }
203
204 for (i = 0; i < Next_surf && !found; i++) {
205 if (Surf_ID[i] == id) {
206 found = 1;
207 }
208 }
209
210 return (found);
211}
212
213/*!
214 \brief Add new surface
215
216 Note that origin has 1/2 cell added to represent center of cells
217 because library assumes that east - west = (cols - 1) * ew_res,
218 since left and right columns are on the edges.
219
220 \return surface id
221 \return -1 on error (MAX_SURFS exceeded)
222 */
224{
225 geosurf *ns;
226
227 G_debug(3, "GS_new_surface():");
228
229 if (Next_surf < MAX_SURFS) {
230 ns = gs_get_new_surface();
231 gs_init_surf(ns, wind.west + wind.ew_res / 2.,
232 wind.south + wind.ns_res / 2., wind.rows, wind.cols,
233 wind.ew_res, wind.ns_res);
234 gs_set_defaults(ns, Default_const, Default_nulls);
235
236 /* make default shine current */
238
239 Surf_ID[Next_surf] = ns->gsurf_id;
240 ++Next_surf;
241
242 G_debug(3, " id=%d", ns->gsurf_id);
243
244 return (ns->gsurf_id);
245 }
246
247 return (-1);
248}
249
251{
252 Resetlight = i;
253 if (i)
254 Numlights = 0;
255}
256
258{
259 return Resetlight;
260}
261
262/*!
263 \brief Add new model light
264
265 \return light model id
266 \return -1 on error (MAX_LIGHTS exceeded)
267 */
269{
270 int i;
271
272 if (GS_get_light_reset()) {
273
275
276 for (i = 0; i < MAX_LIGHTS; i++) {
277 Gv.lights[i].position[X] = Gv.lights[i].position[Y] = 0.0;
278 Gv.lights[i].position[Z] = 1.0;
279 Gv.lights[i].position[W] = 0.0; /* infinite */
280 Gv.lights[i].color[0] = Gv.lights[i].color[1] =
281 Gv.lights[i].color[2] = 1.0;
282 Gv.lights[i].ambient[0] = Gv.lights[i].ambient[1] =
283 Gv.lights[i].ambient[2] = 0.2;
284 Gv.lights[i].shine = 32.0;
285 }
286
288 }
289
290 if (Numlights < MAX_LIGHTS) {
291 gsd_deflight(Numlights + 1, &(Gv.lights[Numlights]));
292 gsd_switchlight(Numlights + 1, 1);
293
294 return ++Numlights;
295 }
296
297 return -1;
298}
299
300/*!
301 \brief Set light position
302
303 \bug I think lights array doesn't match sgi_light array
304
305 \param num light id (starts with 1)
306 \param xpos,ypos,zpos coordinates (model)
307 \param local local coordinate (for viewport)
308 */
309void GS_setlight_position(int num, float xpos, float ypos, float zpos,
310 int local)
311{
312 if (num) {
313 num -= 1;
314 if (num < Numlights) {
315 Gv.lights[num].position[X] = xpos;
316 Gv.lights[num].position[Y] = ypos;
317 Gv.lights[num].position[Z] = zpos;
318 Gv.lights[num].position[W] = (float)local;
319
320 gsd_deflight(num + 1, &(Gv.lights[num]));
321 }
322 }
323
324 return;
325}
326
327/*!
328 \brief Get light position
329
330 \param num light id (starts at 1)
331 \param[out] xpos,ypos,zpos coordinates
332 \param[out] local ?
333 */
334void GS_getlight_position(int num, float *xpos, float *ypos, float *zpos,
335 int *local)
336{
337 if (num) {
338 num -= 1;
339 if (num < Numlights) {
340 *xpos = Gv.lights[num].position[X];
341 *ypos = Gv.lights[num].position[Y];
342 *zpos = Gv.lights[num].position[Z];
343 *local = (int)Gv.lights[num].position[W];
344 }
345 }
346
347 return;
348}
349
350/*!
351 \brief Set light color
352
353 \param num light id (starts at 1)
354 \param red,green,blue color values (from 0.0 to 1.0)
355 */
356void GS_setlight_color(int num, float red, float green, float blue)
357{
358 if (num) {
359 num -= 1;
360 if (num < Numlights) {
361 Gv.lights[num].color[0] = red;
362 Gv.lights[num].color[1] = green;
363 Gv.lights[num].color[2] = blue;
364
365 gsd_deflight(num + 1, &(Gv.lights[num]));
366 }
367 }
368
369 return;
370}
371
372/*!
373 \brief Get light color
374
375 \param num light id (starts at 1)
376 \param[out] red,green,blue color values
377 */
378void GS_getlight_color(int num, float *red, float *green, float *blue)
379{
380 if (num) {
381 num -= 1;
382 if (num < Numlights) {
383 *red = Gv.lights[num].color[0];
384 *green = Gv.lights[num].color[1];
385 *blue = Gv.lights[num].color[2];
386 }
387 }
388
389 return;
390}
391
392/*!
393 \brief Set light ambient
394
395 Red, green, blue from 0.0 to 1.0
396
397 \param num light id (starts at 1)
398 \param red,green,blue color values
399 */
400void GS_setlight_ambient(int num, float red, float green, float blue)
401{
402 if (num) {
403 num -= 1;
404 if (num < Numlights) {
405 Gv.lights[num].ambient[0] = red;
406 Gv.lights[num].ambient[1] = green;
407 Gv.lights[num].ambient[2] = blue;
408
409 gsd_deflight(num + 1, &(Gv.lights[num]));
410 }
411 }
412
413 return;
414}
415
416/*!
417 \brief Get light ambient
418
419 \param num light id (starts at 1)
420 \param[out] red,green,blue color values
421 */
422void GS_getlight_ambient(int num, float *red, float *green, float *blue)
423{
424 if (num) {
425 num -= 1;
426 if (num < Numlights) {
427 *red = Gv.lights[num].ambient[0];
428 *green = Gv.lights[num].ambient[1];
429 *blue = Gv.lights[num].ambient[2];
430 }
431 }
432
433 return;
434}
435
436/*!
437 \brief Switch off all lights
438 */
440{
441 int i;
442
443 for (i = 0; i < Numlights; i++) {
444 gsd_switchlight(i + 1, 0);
445 }
446
447 return;
448}
449
450/*!
451 \brief Switch on all lights
452 */
453void GS_lights_on(void)
454{
455 int i;
456
457 for (i = 0; i < Numlights; i++) {
458 gsd_switchlight(i + 1, 1);
459 }
460
461 return;
462}
463
464/*!
465 \brief Switch on/off light
466
467 \param num light id (starts at 1)
468 \param on non-zero for 'on' otherwise 'off'
469 */
470void GS_switchlight(int num, int on)
471{
472 if (num) {
473 num -= 1;
474
475 if (num < Numlights) {
476 gsd_switchlight(num + 1, on);
477 }
478 }
479
480 return;
481}
482
483/*!
484 \brief Check if transparency is set
485
486 \return 0 transparency not set
487 \return 1 transparency is set
488 */
490{
491 return (gs_att_is_set(NULL, ATT_TRANSP) || (FC_GREY == gsd_getfc()));
492}
493
494/*!
495 \brief Retrieves coordinates for lighting model position, at center of view
496
497 \param[out] pos coordinates
498 */
499void GS_get_modelposition1(float pos[])
500{
501 /* TODO: Still needs work to handle other cases */
502 /* this is a quick hack to get lighting adjustments debugged */
503 /*
504 GS_v3dir(Gv.from_to[FROM], Gv.from_to[TO], center);
505 GS_v3mult(center, 1000);
506 GS_v3add(center, Gv.from_to[FROM]);
507 */
508
510 gs_get_data_avg_zmax(&(pos[Z]));
511
512 G_debug(1, "GS_get_modelposition1(): model position: %f %f %f", pos[X],
513 pos[Y], pos[Z]);
514
515 return;
516}
517
518/*!
519 \brief Retrieves coordinates for lighting model position, at center of view
520
521 Position at nearclip * 2: tried nearclip + siz, but since need to
522 know position to calculate size, have two dependent variables
523 (nearclip * 2) from eye.
524
525 \param[out] size size
526 \param[out] pos coordinates (X, Y, Z)
527 */
528void GS_get_modelposition(float *size, float *pos)
529{
530 float dist, near_h, dir[3];
531
532 dist = 2. * Gd.nearclip;
533
534 near_h = 2.0 * tan(4.0 * atan(1.) * Gv.fov / 3600.) * dist;
535 *size = near_h / 8.0;
536
537 /* prevent clipping - would only happen if fov > ~127 degrees, at
538 fov = 2.0 * atan(2.0) */
539
540 if (*size > Gd.nearclip) {
541 *size = Gd.nearclip;
542 }
543
544 GS_v3dir(Gv.from_to[FROM], Gv.from_to[TO], dir);
545
546 pos[X] = Gv.from_to[FROM][X] + dir[X] * dist;
547 pos[Y] = Gv.from_to[FROM][Y] + dir[Y] * dist;
548 pos[Z] = Gv.from_to[FROM][Z] + dir[Z] * dist;
549
550 return;
551}
552
553/*!
554 \brief Set decoration, north arrow ??
555
556 \todo scale used to calculate len of arrow still needs work
557 needs go function that returns center / eye distance
558 gsd_get_los function is not working correctly ??
559
560 \param pt point value in true world coordinates (?)
561 \param id surface id
562 \param[out] pos2 output coordinates
563 */
564void GS_set_Narrow(int *pt, int id, float *pos2)
565{
566 geosurf *gs;
567 float x, y, z;
569 GLint viewport[4];
570
571 if (GS_get_selected_point_on_surface(pt[X], pt[Y], &id, &x, &y, &z)) {
572 gs = gs_get_surf(id);
573 if (gs) {
574 z = gs->zmax;
575 pos2[X] = (float)x - gs->ox + gs->x_trans;
576 pos2[Y] = (float)y - gs->oy + gs->y_trans;
577 pos2[Z] = (float)z + gs->z_trans;
578
579 return;
580 }
581 }
582 else {
583 gs = gs_get_surf(id);
584
585 /* Need to get model matrix, etc
586 * to run gluUnProject
587 */
589 gsd_do_scale(1);
593
594 if (gs) {
596 GLdouble factor;
597 GLdouble out[3];
598
599 z = (float)gs->zmax + gs->z_trans;
600
603 &out_near[Y], &out_near[Z]);
606 &out_far[Y], &out_far[Z]);
607
608 glPopMatrix();
609
610 factor = (out_near[Z] - z) / (out_near[Z] - out_far[Z]);
611
612 out[X] = out_near[X] - ((out_near[X] - out_far[X]) * factor);
613 out[Y] = out_near[Y] - ((out_near[Y] - out_far[Y]) * factor);
614 out[Z] = z;
615
616 pos2[X] = (float)out[X];
617 pos2[Y] = (float)out[Y];
618 pos2[Z] = (float)out[Z];
619
620 return;
621 }
622 }
623 return;
624}
625
626/*!
627 \brief Draw place marker
628
629 Used to display query point for raster queries.
630
631 \param id surface id
632 \param pt point, X, Y value in true world coordinates
633 */
634void GS_draw_X(int id, float *pt)
635{
636 geosurf *gs;
637 Point3 pos;
638 float siz;
639 gvstyle style;
640
641 if ((gs = gs_get_surf(id))) {
643 style.size = siz / 200.;
644 pos[X] = pt[X] - gs->ox;
645 pos[Y] = pt[Y] - gs->oy;
647
649
650 gsd_do_scale(1);
651 gsd_translate(gs->x_trans, gs->y_trans, gs->z_trans);
652 gsd_linewidth(1);
653
655 pos[Z] = gs->att[ATT_TOPO].constant;
656 gs = NULL; /* tells gpd_obj to use given Z val */
657 }
658 style.color = Gd.bgcol;
659 style.symbol = ST_GYRO;
660 gpd_obj(gs, &style, pos);
661 gsd_flush();
662
664 }
665
666 return;
667}
668
669/*!
670 \brief Draw line on surface
671
672 \param id surface id
673 \param x1,y1,x2,y2 line nodes
674 */
675void GS_draw_line_onsurf(int id, float x1, float y1, float x2, float y2)
676{
677 float p1[2], p2[2];
678 geosurf *gs;
679
680 if ((gs = gs_get_surf(id))) {
681 p1[X] = x1 - gs->ox;
682 p1[Y] = y1 - gs->oy;
683 p2[X] = x2 - gs->ox;
684 p2[Y] = y2 - gs->oy;
685
687
688 gsd_do_scale(1);
689 gsd_translate(gs->x_trans, gs->y_trans, gs->z_trans);
690 gsd_linewidth(1);
691
693 gsd_line_onsurf(gs, p1, p2);
694
696 gsd_flush();
697 }
698
699 return;
700}
701
702/*!
703 \brief Draw multiline on surface
704
705 Like above but limits points in line to n or points found in segment,
706 whichever is smaller.
707
708 \param id surface id
709 \param x1,y1,x2,y2 line nodes
710 \param lasp
711 \param n
712
713 \return number of points used
714 */
715int GS_draw_nline_onsurf(int id, float x1, float y1, float x2, float y2,
716 float *lasp, int n)
717{
718 float p1[2], p2[2];
719 geosurf *gs;
720 int ret = 0;
721
722 if ((gs = gs_get_surf(id))) {
723 p1[X] = x1 - gs->ox;
724 p1[Y] = y1 - gs->oy;
725 p2[X] = x2 - gs->ox;
726 p2[Y] = y2 - gs->oy;
727
729
730 gsd_do_scale(1);
731 gsd_translate(gs->x_trans, gs->y_trans, gs->z_trans);
732 gsd_linewidth(1);
734 ret = gsd_nline_onsurf(gs, p1, p2, lasp, n);
736
738 gsd_flush();
739 }
740
741 return (ret);
742}
743
744/*!
745 \brief Draw flow-line on surace
746
747 This is slow - should be moved to gs_ but GS_ good for testing
748 and useful for app programmer
749
750 \param id surface id
751 \param x,y coordinates of flow-line
752 */
753void GS_draw_flowline_at_xy(int id, float x, float y)
754{
755 geosurf *gs;
756 float nv[3], pdir[2], mult;
757 float p1[2], p2[2], next[2];
758 int i = 0;
759
760 if ((gs = gs_get_surf(id))) {
761 p1[X] = x;
762 p1[Y] = y;
763 /* multiply by 1.5 resolutions to ensure a crossing ? */
764 mult = .1 * (VXRES(gs) > VYRES(gs) ? VXRES(gs) : VYRES(gs));
765
767
768 while (1 == GS_get_norm_at_xy(id, p1[X], p1[Y], nv)) {
769 if (nv[Z] == 1.0) {
770 if (pdir[X] == 0.0 && pdir[Y] == 0.0) {
771 break;
772 }
773
774 p2[X] = p1[X] + (pdir[X] * mult);
775 p2[Y] = p1[Y] + (pdir[Y] * mult);
776 }
777 else {
778 /* use previous direction */
779 GS_v2norm(nv);
780 p2[X] = p1[X] + (nv[X] * mult);
781 p2[Y] = p1[Y] + (nv[Y] * mult);
782 pdir[X] = nv[X];
783 pdir[Y] = nv[Y];
784 }
785
786 if (i > 2000) {
787 break;
788 }
789
790 if (GS_coordpair_repeats(p1, p2, 0)) {
791 break;
792 }
793
794 /* Think about this: */
795 /* degenerate line means edge or level edge ? */
796 /* next is filled with last point drawn */
797 if (2 >
798 GS_draw_nline_onsurf(id, p1[X], p1[Y], p2[X], p2[Y], next, 3)) {
799 break;
800 }
801
802 p1[X] = next[X];
803 p1[Y] = next[Y];
804 }
805
806 G_debug(3, "GS_draw_flowline_at_xy(): dir: %f %f", nv[X], nv[Y]);
807 }
808
809 return;
810}
811
812/*!
813 \brief Draw fringe around data (surface) at selected corners
814
815 \param id surface id
816 \param clr color
817 \param elev elevation value
818 \param where nw/ne/sw/se edges - 0 (turn off) 1 (turn on)
819 */
820void GS_draw_fringe(int id, unsigned long clr, float elev, int *where)
821{
822 geosurf *gs;
823
824 G_debug(3, "GS_draw_fringe(): id: %d clr: %ld elev %f edges: %d %d %d %d",
825 id, clr, elev, where[0], where[1], where[2], where[3]);
826 if ((gs = gs_get_surf(id)))
827 gsd_display_fringe(gs, clr, elev, where);
828}
829
830/*!
831 \brief Draw legend
832
833 \todo add legend from list option
834 make font loading more flexible
835
836 \param name legend name
837 \param fontbase font-base
838 \param size ?
839 \param flags legend flags
840 \param range values range
841 \param pt ?
842 */
843int GS_draw_legend(const char *name, GLuint fontbase, int size, int *flags,
844 float *range, int *pt)
845{
846 int list_no;
847
848 list_no = gsd_put_legend(name, fontbase, size, flags, range, pt);
849
850 return (list_no);
851}
852
853/*!
854 \brief Draw pre-defined list
855
856 Uses glFlush() to ensure all drawing is complete
857 before returning
858
859 \param list_id list id
860 */
862{
864 glFlush();
865 return;
866}
867
868/*!
869 \brief Draw all glLists
870
871 Uses glFlush() to ensure all drawing is complete
872 before returning
873 */
875{
876 gsd_calllists(0); /* not sure if 0 is right - MN */
877 glFlush();
878 return;
879}
880
881/*!
882 \brief Delete pre-defined list
883
884 \param list_id list id
885 */
887{
889
890 return;
891}
892
893/*!
894 \brief Draw lighting model
895 */
897{
898 static float center[3];
899 float tcenter[3];
900
901 if (!Modelshowing) {
903 }
904
906
907 gsd_zwritemask(0x0);
908 gsd_backface(1);
909
913 gsd_do_scale(1);
914
915 if (Gv.vert_exag) {
916 tcenter[Z] *= Gv.vert_exag;
917 gsd_scale(1.0, 1.0, 1. / Gv.vert_exag);
918 }
919
920 gsd_drawsphere(tcenter, 0xDDDDDD, (float)(Longdim / 10.));
922 Modelshowing = 1;
923
924 gsd_backface(0);
925 gsd_zwritemask(0xffffffff);
926
927 return;
928}
929
930/*!
931 \brief Draw lighting model
932
933 Just turn off any cutting planes and draw it just outside near
934 clipping plane, since lighting is infinite now
935 */
937{
938 static float center[3], size;
939 float tcenter[3], tsize;
940 int i, wason[MAX_CPLANES];
941
943
944 for (i = 0; i < MAX_CPLANES; i++) {
945 if (wason[i]) {
947 }
948 }
949
950 if (!Modelshowing) {
952 }
953
955 tsize = size;
956
957 gsd_zwritemask(0x0);
958 gsd_backface(1);
959
963 gsd_drawsphere(tcenter, 0xDDDDDD, tsize);
965 Modelshowing = 1;
966
967 gsd_backface(0);
968 gsd_zwritemask(0xffffffff);
969
970 for (i = 0; i < MAX_CPLANES; i++) {
971 if (wason[i]) {
972 gsd_cplane_on(i);
973 }
974 }
975
976 gsd_flush();
977
978 return;
979}
980
981/*!
982 \brief Update current mask
983
984 May be called to update total mask for a surface at convenient times
985 instead of waiting until ready to redraw surface
986
987 \param id surface id
988
989 \return ?
990 */
992{
993 geosurf *gs;
994
995 gs = gs_get_surf(id);
996 return (gs_update_curmask(gs));
997}
998
999/*!
1000 \brief Check if point is masked ?
1001
1002 \param id surface id
1003 \param pt point
1004
1005 \return 1 masked
1006 \return 0 not masked
1007 \return -1 on error, invalid surface id
1008 */
1009int GS_is_masked(int id, float *pt)
1010{
1011 geosurf *gs;
1012 Point3 tmp;
1013
1014 if ((gs = gs_get_surf(id))) {
1015 tmp[X] = pt[X] - gs->ox;
1016 tmp[Y] = pt[Y] - gs->oy;
1017
1018 return (gs_point_is_masked(gs, tmp));
1019 }
1020
1021 return (-1);
1022}
1023
1024/*!
1025 \brief Unset Scaled Difference surface
1026 */
1028{
1030 SDref_surf = 0;
1031
1032 return;
1033}
1034
1035/*!
1036 \brief Set surface as Scaled Difference surface
1037
1038 \param id surface id
1039
1040 \return 1 on success
1041 \return 0 on error, invalid surface id
1042 */
1043int GS_set_SDsurf(int id)
1044{
1045 geosurf *gs;
1046
1047 if ((gs = gs_get_surf(id))) {
1049 SDref_surf = id;
1050
1051 return (1);
1052 }
1053
1054 return (0);
1055}
1056
1057/*!
1058 \brief Set ?
1059
1060 \param scale scale value
1061
1062 \return 1
1063 */
1064int GS_set_SDscale(float scale)
1065{
1066 gsdiff_set_SDscale(scale);
1067
1068 return (1);
1069}
1070
1071/*!
1072 \brief Get ?
1073
1074 \param[out] id ?
1075
1076 \return 1 on success
1077 \return 0 on error
1078 */
1079int GS_get_SDsurf(int *id)
1080{
1081 geosurf *gs;
1082
1083 if ((gs = gsdiff_get_SDref())) {
1084 *id = SDref_surf;
1085
1086 return (1);
1087 }
1088
1089 return (0);
1090}
1091
1092/*!
1093 \brief Get ?
1094
1095 \param[out] scale value
1096
1097 \return 1
1098 */
1099int GS_get_SDscale(float *scale)
1100{
1101 *scale = gsdiff_get_SDscale();
1102
1103 return (1);
1104}
1105
1106/*!
1107 \brief Update normals
1108
1109 \param id surface id
1110
1111 \return ?
1112 */
1114{
1115 geosurf *gs;
1116
1117 gs = gs_get_surf(id);
1118
1119 return (gs_calc_normals(gs));
1120}
1121
1122/*!
1123 \brief Get attributes
1124
1125 \param id surface id
1126 \param att
1127 \param[out] set
1128 \param[out] constant
1129 \param[out] mapname
1130
1131 \return 1 on success
1132 \return -1 on error (invalid surface id)
1133 */
1134int GS_get_att(int id, int att, int *set, float *constant, char *mapname)
1135{
1136 int src;
1137 geosurf *gs;
1138
1139 gs = gs_get_surf(id);
1140 if (gs) {
1141 if (-1 != (src = gs_get_att_src(gs, att))) {
1142 *set = src;
1143
1144 if (src == CONST_ATT) {
1145 *constant = gs->att[att].constant;
1146 }
1147 else if (src == MAP_ATT) {
1148 strcpy(mapname, gsds_get_name(gs->att[att].hdata));
1149 }
1150
1151 return (1);
1152 }
1153
1154 return (-1);
1155 }
1156
1157 return (-1);
1158}
1159
1160/*!
1161 \brief Get surface category on given position
1162
1163 Prints "no data" or a description (i.e., "coniferous forest") to
1164 <i>catstr</i>. Usually call after GS_get_selected_point_on_surface().
1165 Define <i>att</i> as MAP_ATT
1166
1167 \todo Allocate catstr using G_store()
1168
1169 \param id surface id
1170 \param att attribute id (MAP_ATT)
1171 \param catstr cat string (must be allocated, dim?)
1172 \param x,y real coordinates
1173
1174 \return -1 if no category info or point outside of window
1175 \return 1 on success
1176 */
1177int GS_get_cat_at_xy(int id, int att, char *catstr, float x, float y)
1178{
1179 int offset, drow, dcol, vrow, vcol;
1180 float ftmp, pt[3];
1181 typbuff *buff;
1182 geosurf *gs;
1183
1184 *catstr = '\0';
1185 gs = gs_get_surf(id);
1186
1187 if (NULL == gs) {
1188 return -1;
1189 }
1190
1191 pt[X] = x;
1192 pt[Y] = y;
1193
1195 if (gs_point_is_masked(gs, pt)) {
1196 return -1;
1197 }
1198
1199 if (!in_vregion(gs, pt)) {
1200 return -1;
1201 }
1202
1203 if (MAP_ATT != gs_get_att_src(gs, att)) {
1204 sprintf(catstr, _("no category info"));
1205 return -1;
1206 }
1207
1208 buff = gs_get_att_typbuff(gs, att, 0);
1209
1210 vrow = Y2VROW(gs, pt[Y]);
1211 vcol = X2VCOL(gs, pt[X]);
1212 drow = VROW2DROW(gs, vrow);
1213 dcol = VCOL2DCOL(gs, vcol);
1214
1215 offset = DRC2OFF(gs, drow, dcol);
1216
1217 if (GET_MAPATT(buff, offset, ftmp)) {
1218 return (Gs_get_cat_label(gsds_get_name(gs->att[att].hdata), drow, dcol,
1219 catstr));
1220 }
1221
1222 sprintf(catstr, _("no data"));
1223
1224 return 1;
1225}
1226
1227/*!
1228 \brief Get surface normal at x,y (real coordinates)
1229
1230 Usually call after GS_get_selected_point_on_surface()
1231
1232 \param id surface id
1233 \param x,y real coordinates
1234 \param[out] nv surface normal
1235
1236 \return -1 if point outside of window or masked
1237 \return 1 on success
1238 */
1239int GS_get_norm_at_xy(int id, float x, float y, float *nv)
1240{
1241 int offset, drow, dcol, vrow, vcol;
1242 float pt[3];
1243 geosurf *gs;
1244
1245 gs = gs_get_surf(id);
1246
1247 if (NULL == gs) {
1248 return (-1);
1249 }
1250
1251 if (gs->norm_needupdate) {
1253 }
1254
1255 pt[X] = x;
1256 pt[Y] = y;
1257
1259 if (gs_point_is_masked(gs, pt)) {
1260 return (-1);
1261 }
1262
1263 if (!in_vregion(gs, pt)) {
1264 return (-1);
1265 }
1266
1267 vrow = Y2VROW(gs, pt[Y]);
1268 vcol = X2VCOL(gs, pt[X]);
1269 drow = VROW2DROW(gs, vrow);
1270 dcol = VCOL2DCOL(gs, vcol);
1271
1272 offset = DRC2OFF(gs, drow, dcol);
1273
1274 if (gs->norms) {
1275 FNORM(gs->norms[offset], nv);
1276 }
1277 else {
1278 /* otherwise must be a constant */
1279 nv[0] = 0.0;
1280 nv[1] = 0.0;
1281 nv[2] = 1.0;
1282 }
1283
1284 return (1);
1285}
1286
1287/*!
1288 \brief Get RGB color at given point
1289
1290 Colors are translated to rgb and returned as Rxxx Gxxx Bxxx Usually
1291 call after GS_get_selected_point_on_surface().
1292
1293 Prints NULL or the value (i.e., "921.5") to valstr
1294
1295 \param id surface id
1296 \param att attribute id
1297 \param[out] valstr value string (allocated, dim?)
1298 \param x,y real coordinates
1299
1300 \return -1 if point outside of window or masked
1301 \return 1 on success
1302 */
1303int GS_get_val_at_xy(int id, int att, char *valstr, float x, float y)
1304{
1305 int offset, drow, dcol, vrow, vcol;
1306 float ftmp, pt[3];
1307 typbuff *buff;
1308 geosurf *gs;
1309
1310 *valstr = '\0';
1311 gs = gs_get_surf(id);
1312
1313 if (NULL == gs) {
1314 return -1;
1315 }
1316
1317 pt[X] = x;
1318 pt[Y] = y;
1319
1321
1322 if (gs_point_is_masked(gs, pt)) {
1323 return -1;
1324 }
1325
1326 if (!in_vregion(gs, pt)) {
1327 return (-1);
1328 }
1329
1330 if (CONST_ATT == gs_get_att_src(gs, att)) {
1331 if (att == ATT_COLOR) {
1332 int r, g, b, i;
1333
1334 i = gs->att[att].constant;
1335 sprintf(valstr, "R%d G%d B%d", INT_TO_RED(i, r), INT_TO_GRN(i, g),
1336 INT_TO_BLU(i, b));
1337 }
1338 else {
1339 sprintf(valstr, "%f", gs->att[att].constant);
1340 }
1341
1342 return 1;
1343 }
1344 else if (MAP_ATT != gs_get_att_src(gs, att)) {
1345 return -1;
1346 }
1347
1348 buff = gs_get_att_typbuff(gs, att, 0);
1349
1350 vrow = Y2VROW(gs, pt[Y]);
1351 vcol = X2VCOL(gs, pt[X]);
1352 drow = VROW2DROW(gs, vrow);
1353 dcol = VCOL2DCOL(gs, vcol);
1354
1355 offset = DRC2OFF(gs, drow, dcol);
1356
1357 if (GET_MAPATT(buff, offset, ftmp)) {
1358 if (att == ATT_COLOR) {
1359 int r, g, b, i;
1360
1362 &(gs->att[ATT_COLOR]), offset);
1363 sprintf(valstr, "R%d G%d B%d", INT_TO_RED(i, r), INT_TO_GRN(i, g),
1364 INT_TO_BLU(i, b));
1365 }
1366 else {
1367 sprintf(valstr, "%f", ftmp);
1368 }
1369
1370 return (1);
1371 }
1372
1373 sprintf(valstr, "NULL");
1374
1375 return (1);
1376}
1377
1378/*!
1379 \brief Unset attribute
1380
1381 \param id surface id
1382 \param att attribute id
1383
1384 \return ?
1385 */
1386int GS_unset_att(int id, int att)
1387{
1388 geosurf *gs;
1389
1390 gs = gs_get_surf(id);
1391 gs->mask_needupdate = 1;
1392
1393 return (gs_set_att_src(gs, att, NOTSET_ATT));
1394}
1395
1396/*!
1397 \brief Set attribute constant
1398
1399 \param id surface id
1400 \param att attribute id
1401 \param constant value
1402
1403 \return ?
1404 */
1405int GS_set_att_const(int id, int att, float constant)
1406{
1407 geosurf *gs;
1408 int ret;
1409
1410 gs = gs_get_surf(id);
1411 ret = (gs_set_att_const(gs, att, constant));
1412
1413 Gs_update_attrange(gs, att);
1414
1415 return (ret);
1416}
1417
1418/*!
1419 \brief Set mask mode
1420
1421 Mask attribute special: constant is set to indicate invert or no
1422
1423 \param id surface id
1424 \param mode id
1425
1426 \return mode id
1427 \return -1 on error (invalid surface id)
1428 */
1429int GS_set_maskmode(int id, int mode)
1430{
1431 geosurf *gs;
1432
1433 gs = gs_get_surf(id);
1434
1435 if (gs) {
1436 gs->att[ATT_MASK].constant = mode;
1437 gs->mask_needupdate = 1;
1438
1439 return (mode);
1440 }
1441
1442 return (-1);
1443}
1444
1445/*!
1446 \brief Get mask mode
1447
1448 \param id surface id
1449 \param[out] mode id
1450
1451 \return 1 on success
1452 \return -1 on error (invalid surface id)
1453 */
1454int GS_get_maskmode(int id, int *mode)
1455{
1456 geosurf *gs;
1457
1458 gs = gs_get_surf(id);
1459
1460 if (gs) {
1461 *mode = gs->att[ATT_MASK].constant;
1462
1463 return (1);
1464 }
1465
1466 return (-1);
1467}
1468
1469/*!
1470 \brief Set client data
1471
1472 \param id surface id
1473 \param clientd pointer to client data struct
1474
1475 \return 1 on success
1476 \return -1 on error (invalid surface id)
1477 */
1478int GS_Set_ClientData(int id, void *clientd)
1479{
1480 geosurf *gs;
1481
1482 gs = gs_get_surf(id);
1483 if (gs) {
1484 gs->clientdata = clientd;
1485
1486 return (1);
1487 }
1488
1489 return (-1);
1490}
1491
1492/*!
1493 \brief Get client data
1494
1495 \param id surface id
1496
1497 \return pointer to client data
1498 \return NULL on error
1499 */
1501{
1502 geosurf *gs;
1503
1504 gs = gs_get_surf(id);
1505 if (gs) {
1506 return (gs->clientdata);
1507 }
1508
1509 return (NULL);
1510}
1511
1512/*!
1513 \brief Get number of surfaces
1514
1515 \return number of surfaces
1516 */
1518{
1519 return (gs_num_surfaces());
1520}
1521
1522/*!
1523 \brief Get surface list
1524
1525 Must be freed when not needed!
1526
1527 \param[out] numsurfs number of available surfaces
1528
1529 \return pointer to surface array
1530 \return NULL on error
1531 */
1533{
1534 int i, *ret;
1535
1536 *numsurfs = Next_surf;
1537
1538 if (Next_surf) {
1539 ret = (int *)G_malloc(Next_surf * sizeof(int));
1540
1541 for (i = 0; i < Next_surf; i++) {
1542 ret[i] = Surf_ID[i];
1543 }
1544
1545 return (ret);
1546 }
1547
1548 return (NULL);
1549}
1550
1551/*!
1552 \brief Delete surface
1553
1554 \param id surface id
1555
1556 \return 1 on success
1557 \return -1 on error
1558 */
1560{
1561 int i, j, found;
1562
1563 found = FALSE;
1564
1565 G_debug(1, "GS_delete_surface(): id=%d", id);
1566
1567 if (GS_surf_exists(id)) {
1568 gs_delete_surf(id);
1569 for (i = 0; i < Next_surf && !found; i++) {
1570 if (Surf_ID[i] == id) {
1571 found = TRUE;
1572
1573 for (j = i; j < Next_surf; j++) {
1574 Surf_ID[j] = Surf_ID[j + 1];
1575 }
1576 }
1577 }
1578
1580
1581 if (found) {
1582 --Next_surf;
1583 return 1;
1584 }
1585 }
1586
1587 return -1;
1588}
1589
1590/*!
1591 \brief Load raster map as attribute
1592
1593 \param id surface id
1594 \param filename filename
1595 \param att attribute descriptor
1596
1597 \return -1 on error (invalid surface id)
1598 \return ?
1599 */
1600int GS_load_att_map(int id, const char *filename, int att)
1601{
1602 geosurf *gs;
1603 unsigned int changed;
1604 unsigned int atty;
1605 const char *mapset;
1606 struct Cell_head rast_head;
1607 int reuse, begin, hdata, ret, neg, has_null;
1608 typbuff *tbuff;
1609
1610 G_debug(3, "GS_load_att_map(): map=%s", filename);
1611
1612 reuse = ret = neg = has_null = 0;
1613 gs = gs_get_surf(id);
1614
1615 if (NULL == gs) {
1616 return -1;
1617 }
1618
1619 gs->mask_needupdate = (ATT_MASK == att || ATT_TOPO == att ||
1620 (gs->nz_topo && ATT_TOPO == att) ||
1621 (gs->nz_color && ATT_COLOR == att));
1622
1623 gs_set_att_src(gs, att, MAP_ATT);
1624
1625 /* Check against maps already loaded in memory */
1626 /* if to be color attribute:
1627 - if packed color for another surface, OK to reuse
1628 - if unchanged, ok to reuse IF it's of type char (will have lookup)
1629 */
1630 begin = hdata = 1;
1631
1632 /* Get MAPSET to ensure names are fully qualified */
1633 mapset = G_find_raster2(filename, "");
1634 if (mapset == NULL) {
1635 /* Check for valid filename */
1636 G_warning("Raster map <%s> not found", filename);
1637 return -1;
1638 }
1639
1640 /* Check to see if map is in Region */
1641 Rast_get_cellhd(filename, mapset, &rast_head);
1642 if (rast_head.north <= wind.south || rast_head.south >= wind.north ||
1643 rast_head.east <= wind.west || rast_head.west >= wind.east) {
1644 char *mname = G_fully_qualified_name(filename, mapset);
1645 G_warning(
1646 _("Raster map <%s> is outside of current region. Load failed."),
1647 mname);
1648 G_free(mname);
1649 }
1650
1651 while (!reuse && (0 < hdata)) {
1652 changed = CF_COLOR_PACKED;
1654
1655 if (0 < (hdata = gsds_findh(filename, &changed, &atty, begin))) {
1656
1657 G_debug(3, "GS_load_att_map(): %s already has data handle %d.CF=%x",
1658 filename, hdata, changed);
1659
1660 /* handle found */
1661 if (ATT_COLOR == att) {
1662 if ((changed == CF_COLOR_PACKED) ||
1663 (!changed && atty == ATTY_CHAR)) {
1664 reuse = 1;
1665 }
1666 }
1667 else if (atty == ATTY_MASK && att != ATT_MASK) {
1668 reuse = 0;
1669 /* should also free mask data & share new - but need backward
1670 reference? */
1671 }
1672 else if (!changed) {
1673 reuse = 1;
1674 }
1675 }
1676
1677 begin = 0;
1678 }
1679
1680 if (reuse) {
1681 gs->att[att].hdata = hdata;
1682 gs_set_att_type(gs, att, atty); /* ?? */
1683
1684 /* free lookup & set to NULL! */
1685 if (atty == ATTY_INT) {
1686 if (gs->att[att].lookup) {
1687 free(gs->att[att].lookup);
1688 gs->att[att].lookup = NULL;
1689 }
1690 }
1691 /* TODO: FIX THIS stuff with lookup sharing! */
1692
1693 G_debug(3, "GS_load_att_map(): %s is being reused. hdata=%d", filename,
1694 hdata);
1695 }
1696 else {
1697 G_debug(
1698 3, "GS_load_att_map(): %s not loaded in correct form - loading now",
1699 filename);
1700
1701 /* not loaded - need to get new dataset handle */
1702 gs->att[att].hdata = gsds_newh(filename);
1703
1704 tbuff = gs_get_att_typbuff(gs, att, 1);
1705
1706 /* TODO: Provide mechanism for loading certain attributes at
1707 specified sizes, allow scaling or capping, or scale non-zero */
1708 if (ATT_MASK == att) {
1709 atty = ATTY_MASK;
1710 }
1711 else {
1712 atty = Gs_numtype(filename, &neg);
1713 }
1714
1715#ifdef MAYBE_LATER
1716 if (att == ATT_COLOR && atty == ATTY_SHORT) {
1717 atty = (neg ? ATTY_INT : ATTY_SHORT);
1718 }
1719#endif
1720
1721 if (att == ATT_COLOR && atty == ATTY_SHORT) {
1722 atty = ATTY_INT;
1723 }
1724
1725 if (0 == gs_malloc_att_buff(gs, att, ATTY_NULL)) {
1727 _("GS_load_att_map(): Out of memory. Unable to load map"));
1728 }
1729
1730 switch (atty) {
1731 case ATTY_MASK:
1732 if (0 == gs_malloc_att_buff(gs, att, ATTY_MASK)) {
1734 _("GS_load_att_map(): Out of memory. Unable to load map"));
1735 }
1736
1737 ret = Gs_loadmap_as_bitmap(&wind, filename, tbuff->bm);
1738
1739 break;
1740 case ATTY_CHAR:
1741 if (0 == gs_malloc_att_buff(gs, att, ATTY_CHAR)) {
1743 _("GS_load_att_map(): Out of memory. Unable to load map"));
1744 }
1745
1746 ret = Gs_loadmap_as_char(&wind, filename, tbuff->cb, tbuff->nm,
1747 &has_null);
1748
1749 break;
1750 case ATTY_SHORT:
1751 if (0 == gs_malloc_att_buff(gs, att, ATTY_SHORT)) {
1753 _("GS_load_att_map(): Out of memory. Unable to load map"));
1754 }
1755
1756 ret = Gs_loadmap_as_short(&wind, filename, tbuff->sb, tbuff->nm,
1757 &has_null);
1758 break;
1759 case ATTY_FLOAT:
1760 if (0 == gs_malloc_att_buff(gs, att, ATTY_FLOAT)) {
1762 _("GS_load_att_map(): Out of memory. Unable to load map"));
1763 }
1764
1765 ret = Gs_loadmap_as_float(&wind, filename, tbuff->fb, tbuff->nm,
1766 &has_null);
1767
1768 break;
1769 case ATTY_INT:
1770 default:
1771 if (0 == gs_malloc_att_buff(gs, att, ATTY_INT)) {
1773 _("GS_load_att_map(): Out of memory. Unable to load map"));
1774 }
1775
1776 ret = Gs_loadmap_as_int(&wind, filename, tbuff->ib, tbuff->nm,
1777 &has_null);
1778 break;
1779
1780 } /* Done with switch */
1781
1782 if (ret == -1) {
1783 gsds_free_data_buff(gs->att[att].hdata, ATTY_NULL);
1784 return -1;
1785 }
1786
1787 G_debug(4, " has_null=%d", has_null);
1788
1789 if (!has_null) {
1790 gsds_free_data_buff(gs->att[att].hdata, ATTY_NULL);
1791 }
1792 else {
1794 }
1795
1796 } /* end if not reuse */
1797
1798 if (ATT_COLOR == att) {
1799#ifdef MAYBE_LATER
1800 if (ATTY_INT == atty) {
1801 Gs_pack_colors(filename, tbuff->ib, gs->rows, gs->cols);
1802 gsds_set_changed(gs->att[att].hdata, CF_COLOR_PACKED);
1803 gs->att[att].lookup = NULL;
1804 }
1805 else {
1806 gs_malloc_lookup(gs, att);
1807 Gs_build_lookup(filename, gs->att[att].lookup);
1808 }
1809#else
1810
1811 if (ATTY_CHAR == atty) {
1812 if (!gs->att[att].lookup) {
1813 /* might already exist if reusing */
1814 gs_malloc_lookup(gs, att);
1815 Gs_build_256lookup(filename, gs->att[att].lookup);
1816 }
1817 }
1818 else if (ATTY_FLOAT == atty) {
1819 if (!reuse) {
1820 if (0 == gs_malloc_att_buff(gs, att, ATTY_INT)) {
1821 G_fatal_error(_("GS_load_att_map(): Out of memory. Unable "
1822 "to load map"));
1823 }
1824
1825 Gs_pack_colors_float(filename, tbuff->fb, tbuff->ib, gs->rows,
1826 gs->cols);
1827 gsds_set_changed(gs->att[att].hdata, CF_COLOR_PACKED);
1828 gsds_free_data_buff(gs->att[att].hdata, ATTY_FLOAT);
1829 gs->att[att].lookup = NULL;
1830 }
1831 }
1832 else {
1833 if (!reuse) {
1834 Gs_pack_colors(filename, tbuff->ib, gs->rows, gs->cols);
1835 gsds_set_changed(gs->att[att].hdata, CF_COLOR_PACKED);
1836 gs->att[att].lookup = NULL;
1837 }
1838 }
1839#endif
1840 }
1841
1842 if (ATT_TOPO == att) {
1844 /* S_DIFF: should also check here to see if this surface is a
1845 reference surface for scaled differences, if so update references
1846 to it */
1847 }
1848
1849 if (ret < 0) {
1850 G_warning(_("Loading failed"));
1851 }
1852
1853 if (-1 == Gs_update_attrange(gs, att)) {
1854 G_warning(_("Error finding range"));
1855 }
1856
1857 return ret;
1858}
1859
1860/*!
1861 \brief Draw surface
1862
1863 \param id surface id
1864 */
1865void GS_draw_surf(int id)
1866{
1867 geosurf *gs;
1868
1869 G_debug(3, "GS_draw_surf(): id=%d", id);
1870
1871 gs = gs_get_surf(id);
1872 if (gs) {
1873 gsd_shademodel(gs->draw_mode & DM_GOURAUD);
1874
1875 if (gs->draw_mode & DM_POLY) {
1876 gsd_surf(gs);
1877 }
1878
1879 if (gs->draw_mode & DM_WIRE) {
1881 }
1882
1883 /* TODO: write wire/poly draw routines */
1884 if (gs->draw_mode & DM_WIRE_POLY) {
1885 gsd_surf(gs);
1887 }
1888 }
1889
1890 return;
1891}
1892
1893/*!
1894 \brief Draw surface wire
1895
1896 Overrides draw_mode for fast display
1897
1898 \param id surface id
1899 */
1900void GS_draw_wire(int id)
1901{
1902 geosurf *gs;
1903
1904 G_debug(3, "GS_draw_wire(): id=%d", id);
1905
1906 gs = gs_get_surf(id);
1907
1908 if (gs) {
1910 }
1911
1912 return;
1913}
1914
1915/*!
1916 \brief Draw all wires
1917
1918 Overrides draw_mode for fast display
1919 */
1921{
1922 geosurf *gs;
1923 int i;
1924
1925 for (i = 0; i < Next_surf; i++) {
1926 if ((gs = gs_get_surf(Surf_ID[i]))) {
1928 }
1929 }
1930
1931 return;
1932}
1933
1934/*!
1935 \brief Draw all surfaces
1936 */
1938{
1939 int i;
1940
1941 for (i = 0; i < Next_surf; i++) {
1942 GS_draw_surf(Surf_ID[i]);
1943 }
1944
1945 return;
1946}
1947
1948/*!
1949 \brief Set Z exag for surface
1950
1951 \param id surface id
1952 \param exag z-exag value
1953 */
1954void GS_set_exag(int id, float exag)
1955{
1956 geosurf *gs;
1957
1958 G_debug(3, "GS_set_exag");
1959
1960 gs = gs_get_surf(id);
1961
1962 if (gs) {
1963 if (gs->z_exag != exag) {
1964 gs->norm_needupdate = 1;
1965 }
1966
1967 gs->z_exag = exag;
1968 }
1969
1970 return;
1971}
1972
1973/*!
1974 \brief Set global z-exag value
1975
1976 \param exag exag value to be set up
1977 */
1978void GS_set_global_exag(float exag)
1979{
1980
1981 G_debug(3, "GS_set_global_exag");
1982
1983 Gv.vert_exag = exag;
1984 /* GL_NORMALIZE */
1985 /* Only need to update norms gs_norms.c
1986 * if exag is used in norm equation which
1987 * it is not! If GL_NORMALIZE is disabled
1988 * will need to include.
1989 gs_setall_norm_needupdate();
1990 */
1991
1992 return;
1993}
1994
1995/*!
1996 \brief Get global z-exag value
1997
1998 \return value
1999 */
2001{
2002 G_debug(3, "GS_global_exag(): %g", Gv.vert_exag);
2003
2004 return (Gv.vert_exag);
2005}
2006
2007/*!
2008 \brief Set wire color
2009
2010 \todo error-handling
2011
2012 \param id surface id
2013 \param colr color value
2014 */
2015void GS_set_wire_color(int id, int colr)
2016{
2017 geosurf *gs;
2018
2019 G_debug(3, "GS_set_wire_color");
2020
2021 gs = gs_get_surf(id);
2022
2023 if (gs) {
2024 gs->wire_color = colr;
2025 }
2026
2027 return;
2028}
2029
2030/*!
2031 \brief Get wire color
2032
2033 \param id surface id
2034 \param[out] colr color value
2035
2036 \return 1 on success
2037 \return -1 on error
2038 */
2039int GS_get_wire_color(int id, int *colr)
2040{
2041 geosurf *gs;
2042
2043 gs = gs_get_surf(id);
2044
2045 if (gs) {
2046 *colr = gs->wire_color;
2047
2048 return (1);
2049 }
2050
2051 return (-1);
2052}
2053
2054/*!
2055 \brief Set all draw-modes
2056
2057 \param mode mode id
2058
2059 \return 0 on success
2060 \return -1 on error
2061 */
2063{
2064 int i;
2065
2066 for (i = 0; i < Next_surf; i++) {
2067 if (0 != GS_set_drawmode(Surf_ID[i], mode)) {
2068 return (-1);
2069 }
2070 }
2071
2072 return (0);
2073}
2074
2075/*!
2076 \brief Set draw mode
2077
2078 \param id surface id
2079 \param mode mode type(s)
2080
2081 \return 0 on success
2082 \return -1 on error (invalid surface id)
2083 */
2084int GS_set_drawmode(int id, int mode)
2085{
2086 geosurf *gs;
2087
2088 G_debug(3, "GS_set_drawmode(): id=%d mode=%d", id, mode);
2089
2090 gs = gs_get_surf(id);
2091
2092 if (gs) {
2093 gs->draw_mode = mode;
2094
2095 return (0);
2096 }
2097
2098 return (-1);
2099}
2100
2101/*!
2102 \brief Get draw mode
2103
2104 \param id surface id
2105 \param[out] mode mode id
2106
2107 \return 1 on success
2108 \return -1 on error (invalid surface id)
2109 */
2110int GS_get_drawmode(int id, int *mode)
2111{
2112 geosurf *gs;
2113
2114 gs = gs_get_surf(id);
2115
2116 if (gs) {
2117 *mode = gs->draw_mode;
2118
2119 return (1);
2120 }
2121
2122 return (-1);
2123}
2124
2125/*!
2126 \brief Set no-zero ?
2127
2128 \param id surface id
2129 \param att attribute id
2130 \param mode mode id
2131 */
2132void GS_set_nozero(int id, int att, int mode)
2133{
2134 geosurf *gs;
2135
2136 G_debug(3, "GS_set_nozero");
2137
2138 gs = gs_get_surf(id);
2139
2140 if (gs) {
2141 if (att == ATT_TOPO) {
2142 gs->nz_topo = mode;
2143 gs->mask_needupdate = 1;
2144 }
2145
2146 if (att == ATT_COLOR) {
2147 gs->nz_color = mode;
2148 gs->mask_needupdate = 1;
2149 }
2150 }
2151
2152 return;
2153}
2154
2155/*!
2156 \brief Get no-zero ?
2157
2158 \param id surface id
2159 \param att attribute id
2160 \param[out] mode mode id
2161
2162 \return -1 on error (invalid surface id)
2163 \return 1 on success
2164 */
2165int GS_get_nozero(int id, int att, int *mode)
2166{
2167 geosurf *gs;
2168
2169 G_debug(3, "GS_set_nozero");
2170
2171 gs = gs_get_surf(id);
2172
2173 if (gs) {
2174 if (att == ATT_TOPO) {
2175 *mode = gs->nz_topo;
2176 }
2177 else if (att == ATT_COLOR) {
2178 *mode = gs->nz_color;
2179 }
2180 else {
2181 return (-1);
2182 }
2183
2184 return (1);
2185 }
2186
2187 return (-1);
2188}
2189
2190/*!
2191 \brief Set all draw resolutions
2192
2193 \param xres,yres x/y resolution value
2194 \param xwire,ywire x/y wire value
2195
2196 \return 0 on success
2197 \return -1 on error
2198 */
2199int GS_setall_drawres(int xres, int yres, int xwire, int ywire)
2200{
2201 int i;
2202
2203 for (i = 0; i < Next_surf; i++) {
2204 if (0 != GS_set_drawres(Surf_ID[i], xres, yres, xwire, ywire)) {
2205 return (-1);
2206 }
2207 }
2208
2209 return (0);
2210}
2211
2212/*!
2213 \brief Set draw resolution for surface
2214
2215 \param id surface id
2216 \param xres,yres x/y resolution value
2217 \param xwire,ywire x/y wire value
2218
2219 \return -1 on error
2220 \return 0 on success
2221 */
2222int GS_set_drawres(int id, int xres, int yres, int xwire, int ywire)
2223{
2224 geosurf *gs;
2225
2226 G_debug(3, "GS_set_drawres() id=%d xyres=%d/%d xywire=%d/%d", id, xres,
2227 yres, xwire, ywire);
2228
2229 if (xres < 1 || yres < 1 || xwire < 1 || ywire < 1) {
2230 return (-1);
2231 }
2232
2233 gs = gs_get_surf(id);
2234
2235 if (gs) {
2236 if (gs->x_mod != xres || gs->y_mod != yres) {
2237 gs->norm_needupdate = 1;
2238 }
2239
2240 gs->x_mod = xres;
2241 gs->y_mod = yres;
2242 gs->x_modw = xwire;
2243 gs->y_modw = ywire;
2244 }
2245
2246 return (0);
2247}
2248
2249/*!
2250 \brief Get draw resolution of surface
2251
2252 \param id surface id
2253 \param[out] xres,yres x/y resolution value
2254 \param[out] xwire,ywire x/y wire value
2255 */
2256void GS_get_drawres(int id, int *xres, int *yres, int *xwire, int *ywire)
2257{
2258 geosurf *gs;
2259
2260 G_debug(3, "GS_get_drawres");
2261
2262 gs = gs_get_surf(id);
2263
2264 if (gs) {
2265 *xres = gs->x_mod;
2266 *yres = gs->y_mod;
2267 *xwire = gs->x_modw;
2268 *ywire = gs->y_modw;
2269 }
2270
2271 return;
2272}
2273
2274/*!
2275 \brief Get dimension of surface
2276
2277 \param id surface id
2278 \param[out] rows,cols number of rows/cols
2279 */
2280void GS_get_dims(int id, int *rows, int *cols)
2281{
2282 geosurf *gs;
2283
2284 gs = gs_get_surf(id);
2285
2286 if (gs) {
2287 *rows = gs->rows;
2288 *cols = gs->cols;
2289 }
2290
2291 return;
2292}
2293
2294/*!
2295 \brief Get exag-value guess
2296
2297 Use no_zero range because if zero IS data, then range won't be that
2298 much off (it's just a GUESS, after all), but if zero is NO data, could
2299 drastically affect guess
2300
2301 \param id surface id
2302 \param[out] exag exag value
2303
2304 \return 1 on success
2305 \return -1 on error
2306 */
2307int GS_get_exag_guess(int id, float *exag)
2308{
2309 geosurf *gs;
2310 float guess;
2311
2312 gs = gs_get_surf(id);
2313 guess = 1.0;
2314
2315 /* if gs is type const return guess = 1.0 */
2317 *exag = guess;
2318 return (1);
2319 }
2320
2321 if (gs) {
2322 if (gs->zrange_nz == 0.0) {
2323 *exag = 0.0;
2324
2325 return (1);
2326 }
2327
2328 G_debug(3, "GS_get_exag_guess(): %f %f", gs->zrange_nz, Longdim);
2329
2330 while (gs->zrange_nz * guess / Longdim >= .25) {
2331 guess *= .1;
2332
2333 G_debug(3, "GS_get_exag_guess(): %f", guess);
2334 }
2335
2336 while (gs->zrange_nz * guess / Longdim < .025) {
2337 guess *= 10.;
2338
2339 G_debug(3, "GS_get_exag_guess(): %f", guess);
2340 }
2341
2342 *exag = guess;
2343
2344 return (1);
2345 }
2346
2347 return (-1);
2348}
2349
2350/*!
2351 \brief Get Z extents for all loaded surfaces
2352
2353 Treating zeros as "no data"
2354
2355 \param[out] min min value
2356 \param[out] max max value
2357 */
2358void GS_get_zrange_nz(float *min, float *max)
2359{
2360 int i, first = 1;
2361 geosurf *gs;
2362
2363 for (i = 0; i < Next_surf; i++) {
2364 if ((gs = gs_get_surf(Surf_ID[i]))) {
2365 if (first) {
2366 first = 0;
2367 *min = gs->zmin_nz;
2368 *max = gs->zmax_nz;
2369 }
2370
2371 if (gs->zmin_nz < *min) {
2372 *min = gs->zmin_nz;
2373 }
2374
2375 if (gs->zmax_nz > *max) {
2376 *max = gs->zmax_nz;
2377 }
2378 }
2379 }
2380
2381 G_debug(3, "GS_get_zrange_nz(): min=%g max=%g", *min, *max);
2382
2383 return;
2384}
2385
2386/*!
2387 \brief Set translation (surface position)
2388
2389 \param id surface id
2390 \param xtrans,ytrans,ztrans translation values
2391 */
2392void GS_set_trans(int id, float xtrans, float ytrans, float ztrans)
2393{
2394 geosurf *gs;
2395
2396 gs = gs_get_surf(id);
2397
2398 if (gs) {
2399 gs->x_trans = xtrans;
2400 gs->y_trans = ytrans;
2401 gs->z_trans = ztrans;
2402 }
2403
2404 G_debug(3, "GS_set_trans(): id=%d, x=%f, y=%f, z=%f", id, xtrans, ytrans,
2405 ztrans);
2406
2407 return;
2408}
2409
2410/*!
2411 \brief Get translation values (surface position)
2412
2413 \param id surface id
2414 \param[out] xtrans,ytrans,ztrans trans values
2415 */
2416void GS_get_trans(int id, float *xtrans, float *ytrans, float *ztrans)
2417{
2418 geosurf *gs;
2419
2420 gs = gs_get_surf(id);
2421
2422 if (gs) {
2423 *xtrans = gs->x_trans;
2424 *ytrans = gs->y_trans;
2425 *ztrans = gs->z_trans;
2426 }
2427
2428 G_debug(3, "GS_get_trans: id=%d, x=%f, y=%f, z=%f", id, *xtrans, *ytrans,
2429 *ztrans);
2430
2431 return;
2432}
2433
2434/*!
2435 \brief Get default draw color
2436
2437 \return color value
2438 */
2439unsigned int GS_default_draw_color(void)
2440{
2441
2442 G_debug(3, "GS_default_draw_color");
2443
2444 return ((unsigned int)Gd.bgcol);
2445}
2446
2447/*!
2448 \brief Get background color
2449
2450 \return color value
2451 */
2452unsigned int GS_background_color(void)
2453{
2454 return ((unsigned int)Gd.bgcol);
2455}
2456
2457/*!
2458 \brief Sets which buffer to draw to
2459
2460 \param where GSD_BOTH, GSD_FRONT, GSD_BACK
2461 */
2462void GS_set_draw(int where)
2463{
2464 Buffermode = where;
2465
2466 switch (where) {
2467 case GSD_BOTH:
2469
2470 break;
2471 case GSD_FRONT:
2473
2474 break;
2475 case GSD_BACK:
2476 default:
2478
2479 break;
2480 }
2481
2482 return;
2483}
2484
2485/*
2486 \brief Ready to draw
2487 */
2489{
2490
2491 G_debug(3, "GS_ready_draw");
2492
2493 gsd_set_view(&Gv, &Gd);
2494
2495 return;
2496}
2497
2498/*!
2499 \brief Draw done, swap buffers
2500 */
2502{
2503
2504 G_debug(3, "GS_done_draw");
2505
2506 if (GSD_BACK == Buffermode) {
2508 }
2509
2510 gsd_flush();
2511
2512 return;
2513}
2514
2515/*!
2516 \brief Set focus
2517
2518 \param realto real coordinates to
2519 */
2521{
2522
2523 G_debug(3, "GS_set_focus(): %f,%f,%f", realto[0], realto[1], realto[2]);
2524
2525 Gv.infocus = 1;
2526 GS_v3eq(Gv.real_to, realto);
2527
2528 gsd_set_view(&Gv, &Gd);
2529
2530 return;
2531}
2532
2533/*!
2534 \brief Set real focus
2535
2536 \param realto real coordinates to
2537 */
2539{
2540
2541 G_get_set_window(&wind);
2542 realto[X] = realto[X] - wind.west - (wind.ew_res / 2.);
2543 realto[Y] = realto[Y] - wind.south - (wind.ns_res / 2.);
2544
2545 Gv.infocus = 1;
2546 GS_v3eq(Gv.real_to, realto);
2547
2548 gsd_set_view(&Gv, &Gd);
2549
2550 return;
2551}
2552
2553/*!
2554 \brief Get focus
2555
2556 OK to call with NULL argument if just want to check state
2557
2558 \param realto real coordinates to
2559
2560 \return ?
2561 */
2563{
2564
2565 G_debug(3, "GS_get_focus");
2566
2567 if (Gv.infocus) {
2568 if (realto) {
2569 GS_v3eq(realto, Gv.real_to);
2570 }
2571 }
2572
2573 return (Gv.infocus);
2574}
2575
2576/*!
2577 \brief Set focus to map center
2578
2579 \param id surface id
2580 */
2582{
2583 float center[3];
2584 geosurf *gs;
2585
2586 G_debug(3, "GS_set_focus_center_map");
2587
2588 gs = gs_get_surf(id);
2589
2590 if (gs) {
2591 center[X] = (gs->xmax - gs->xmin) / 2.;
2592 center[Y] = (gs->ymax - gs->ymin) / 2.;
2593 center[Z] = (gs->zmax_nz + gs->zmin_nz) / 2.;
2594
2595 /* not yet working
2596 buff = gs_get_att_typbuff(gs, ATT_TOPO, 0);
2597 offset = gs->rows*gs->cols/2 + gs->cols/2;
2598 if (buff)
2599 {
2600 if (GET_MAPATT(buff, offset, tmp))
2601 {
2602 center[Z] = tmp;
2603 }
2604 }
2605 */
2606
2608 }
2609}
2610
2611/*!
2612 \brief Move viewpoint
2613
2614 \param pt 'from' model coordinates
2615 */
2616void GS_moveto(float *pt)
2617{
2618 float ft[3];
2619
2620 G_debug(3, "GS_moveto(): %f,%f,%f", pt[0], pt[1], pt[2]);
2621
2622 if (Gv.infocus) {
2623 GS_v3eq(Gv.from_to[FROM], pt);
2624 /*
2625 GS_v3eq(Gv.from_to[TO], Gv.real_to);
2626 */
2627 GS_v3normalize(Gv.from_to[FROM], Gv.from_to[TO]);
2628 /* update inclination, look_dir if we're keeping these */
2629 }
2630 else {
2631 GS_v3eq(ft, Gv.from_to[TO]);
2632 GS_v3sub(ft, Gv.from_to[FROM]);
2633 GS_v3eq(Gv.from_to[FROM], pt);
2634 GS_v3eq(Gv.from_to[TO], pt);
2635 GS_v3add(Gv.from_to[TO], ft);
2636 }
2637
2638 return;
2639}
2640
2641/*!
2642 \brief Move position to (real)
2643
2644 \param pt point real coordinates
2645 */
2646void GS_moveto_real(float *pt)
2647{
2649 GS_moveto(pt);
2650
2651 return;
2652}
2653
2654/*!
2655 \brief Get z-extent for a single surface
2656
2657 \param id surface id
2658 \param[out] min min z-value
2659 \param[out] max max z-value
2660 \param[out] mid middle z-value
2661
2662 \return -1 on error (invalid surface id)
2663 \return ?
2664 */
2665int GS_get_zextents(int id, float *min, float *max, float *mid)
2666{
2667 geosurf *gs;
2668
2669 if (NULL == (gs = gs_get_surf(id))) {
2670 return (-1);
2671 }
2672
2673 G_debug(3, "GS_get_zextents(): id=%d", id);
2674
2675 return (gs_get_zextents(gs, min, max, mid));
2676}
2677
2678/*!
2679 \brief Get z-extent for all loaded surfaces
2680
2681 \param[out] min min z-value
2682 \param[out] max max z-value
2683 \param doexag use z-exaggeration
2684
2685 \return 1 on success
2686 \return -1 on error
2687 */
2688int GS_get_zrange(float *min, float *max, int doexag)
2689{
2690 int ret_surf, ret_vol;
2691 float surf_min, surf_max;
2692 float vol_min, vol_max;
2693
2696
2697 if (ret_surf > 0 && ret_vol > 0) {
2698 *min = (surf_min < vol_min) ? surf_min : vol_min;
2699 *max = (surf_max < vol_max) ? surf_max : vol_max;
2700 }
2701 else if (ret_surf > 0) {
2702 *min = surf_min;
2703 *max = surf_max;
2704 }
2705 else if (ret_vol > 0) {
2706 *min = vol_min;
2707 *max = vol_max;
2708 }
2709
2710 if (doexag) {
2711 *min *= Gv.vert_exag;
2712 *max *= Gv.vert_exag;
2713 }
2714
2715 G_debug(3, "GS_get_zrange(): min=%g max=%g", *min, *max);
2716 return ((ret_surf > 0 || ret_vol > 0) ? (1) : (-1));
2717}
2718
2719/*!
2720 \brief Get viewpoint 'from' position
2721
2722 \param[out] fr from model coordinates
2723 */
2724void GS_get_from(float *fr)
2725{
2726 GS_v3eq(fr, Gv.from_to[FROM]);
2727
2728 G_debug(3, "GS_get_from(): %f,%f,%f", fr[0], fr[1], fr[2]);
2729
2730 return;
2731}
2732
2733/*!
2734 \brief Get viewpoint 'from' real coordinates
2735
2736 \param[out] fr 'from' real coordinates
2737 */
2738void GS_get_from_real(float *fr)
2739{
2740 GS_v3eq(fr, Gv.from_to[FROM]);
2741 gsd_model2real(fr);
2742
2743 return;
2744}
2745
2746/*!
2747 \brief Get 'to' real coordinates
2748
2749 \param[out] to 'to' real coordinates
2750 */
2751void GS_get_to_real(float *to)
2752{
2753 float realto[3];
2754
2755 G_get_set_window(&wind);
2757 to[X] = realto[X] + wind.west + (wind.ew_res / 2.);
2758 to[Y] = realto[Y] + wind.south + (wind.ns_res / 2.);
2759 to[Z] = realto[Z];
2760
2761 return;
2762}
2763
2764/*!
2765 \brief Get zoom setup
2766
2767 \param[out] a,b,c,d current viewport settings
2768 \param[out] maxx,maxy max viewport size
2769 */
2770void GS_zoom_setup(int *a, int *b, int *c, int *d, int *maxx, int *maxy)
2771{
2772 GLint tmp[4];
2773 GLint num[2];
2774
2775 gsd_getViewport(tmp, num);
2776 *a = tmp[0];
2777 *b = tmp[1];
2778 *c = tmp[2];
2779 *d = tmp[3];
2780 *maxx = num[0];
2781 *maxy = num[1];
2782
2783 return;
2784}
2785
2786/*!
2787 \brief Get 'to' model coordinates
2788
2789 \todo need set_to? - just use viewdir?
2790
2791 \param[out] to 'to' model coordinates
2792 */
2793void GS_get_to(float *to)
2794{
2795 G_debug(3, "GS_get_to");
2796
2797 GS_v3eq(to, Gv.from_to[TO]);
2798
2799 return;
2800}
2801
2802/*!
2803 \brief Get viewdir
2804
2805 \param[out] dir viewdir value
2806 */
2807void GS_get_viewdir(float *dir)
2808{
2809 GS_v3dir(Gv.from_to[FROM], Gv.from_to[TO], dir);
2810
2811 return;
2812}
2813
2814/*!
2815 \brief Set viewdir
2816
2817 Automatically turns off focus
2818
2819 \param dir viewdir value
2820 */
2821void GS_set_viewdir(float *dir)
2822{
2823 float tmp[3];
2824
2825 GS_v3eq(tmp, dir);
2826 GS_v3norm(tmp);
2827 GS_v3eq(Gv.from_to[TO], Gv.from_to[FROM]);
2828 GS_v3add(Gv.from_to[TO], tmp);
2829
2831 gsd_set_view(&Gv, &Gd);
2832
2833 return;
2834}
2835
2836/*!
2837 \brief Set field of view
2838
2839 \param fov fov value
2840 */
2841void GS_set_fov(int fov)
2842{
2843 Gv.fov = fov;
2844
2845 return;
2846}
2847
2848/*!
2849 \brief Get field of view
2850
2851 \return field of view, in 10ths of degrees
2852 */
2853int GS_get_fov(void)
2854{
2855 return (Gv.fov);
2856}
2857
2858/*!
2859 \brief Get twist value
2860
2861 10ths of degrees off twelve o'clock
2862 */
2864{
2865 return (Gv.twist);
2866}
2867
2868/*!
2869 \brief Set viewpoint twist value
2870
2871 10ths of degrees off twelve o'clock
2872
2873 \param t tenths of degrees clockwise from 12:00.
2874 */
2876{
2877 Gv.twist = t;
2878
2879 return;
2880}
2881
2882/*!
2883 \brief Set rotation params
2884 */
2885void GS_set_rotation(double angle, double x, double y, double z)
2886{
2887 Gv.rotate.rot_angle = angle;
2888 Gv.rotate.rot_axes[0] = x;
2889 Gv.rotate.rot_axes[1] = y;
2890 Gv.rotate.rot_axes[2] = z;
2891 Gv.rotate.do_rot = 1;
2892
2893 return;
2894}
2895
2896/*!
2897 \brief Stop scene rotation
2898 */
2900{
2901 Gv.rotate.do_rot = 0;
2902}
2903
2904/*!
2905 \brief Reset scene rotation
2906 */
2908{
2909 int i;
2910
2911 for (i = 0; i < 16; i++) {
2912 if (i == 0 || i == 5 || i == 10 || i == 15)
2913 Gv.rotate.rotMatrix[i] = 1.0;
2914 else
2915 Gv.rotate.rotMatrix[i] = 0.0;
2916 }
2917 Gv.rotate.rot_angle = 0.0;
2918 Gv.rotate.rot_axes[0] = 0.0;
2919 Gv.rotate.rot_axes[1] = 0.0;
2920 Gv.rotate.rot_axes[2] = 0.0;
2921 Gv.rotate.do_rot = 0;
2922}
2923
2924/*!
2925 * \brief Get rotation matrix
2926 */
2928{
2929 int i;
2930
2931 for (i = 0; i < 16; i++) {
2932 matrix[i] = Gv.rotate.rotMatrix[i];
2933 }
2934}
2935
2936/*!
2937 * \brief Set rotation matrix
2938 */
2940{
2941 int i;
2942
2943 for (i = 0; i < 16; i++) {
2944 Gv.rotate.rotMatrix[i] = matrix[i];
2945 }
2946}
2947
2948/*!
2949 \brief Unset focus
2950 */
2952{
2953 G_debug(3, "GS_set_nofocus");
2954
2955 Gv.infocus = 0;
2956
2957 return;
2958}
2959
2960/*!
2961 \brief Set focus
2962
2963 Make sure that the center of view is set
2964 */
2966{
2967 G_debug(3, "GS_set_infocus");
2968
2969 Gv.infocus = 1;
2970
2971 return;
2972}
2973
2974/*!
2975 \brief Set viewport
2976
2977 \param left,right,bottom,top viewport extent values
2978 */
2979void GS_set_viewport(int left, int right, int bottom, int top)
2980{
2981 G_debug(3,
2982 "GS_set_viewport(): left=%d, right=%d, "
2983 "bottom=%d, top=%d",
2984 left, right, bottom, top);
2985
2986 gsd_viewport(left, right, bottom, top);
2987
2988 return;
2989}
2990
2991/*!
2992 \brief Send screen coords sx and sy, lib traces through surfaces; sets
2993 new center to point of nearest intersection.
2994
2995 If no intersection, uses line of sight with length of current view
2996 ray (eye to center) to set new center.
2997
2998 Reset center of view to screen coordinates sx, sy.
2999
3000 \param sx,sy screen coordinates
3001
3002 \return 1 on success
3003 \return 0 on error (invalid surface id)
3004 */
3005int GS_look_here(int sx, int sy)
3006{
3007 float x, y, z, len, los[2][3];
3008 Point3 realto, dir;
3009 int id;
3010 geosurf *gs;
3011
3012 if (GS_get_selected_point_on_surface(sx, sy, &id, &x, &y, &z)) {
3013 gs = gs_get_surf(id);
3014 if (gs) {
3015 realto[X] = x - gs->ox + gs->x_trans;
3016 realto[Y] = y - gs->oy + gs->y_trans;
3017 realto[Z] = z + gs->z_trans;
3019
3020 return (1);
3021 }
3022 }
3023 else {
3024 if (gsd_get_los(los, (short)sx, (short)sy)) {
3025 len = GS_distance(Gv.from_to[FROM], Gv.real_to);
3026 GS_v3dir(los[FROM], los[TO], dir);
3027 GS_v3mult(dir, len);
3028 realto[X] = Gv.from_to[FROM][X] + dir[X];
3029 realto[Y] = Gv.from_to[FROM][Y] + dir[Y];
3030 realto[Z] = Gv.from_to[FROM][Z] + dir[Z];
3032
3033 return (1);
3034 }
3035 }
3036
3037 return (0);
3038}
3039
3040/*!
3041 \brief Get selected point of surface
3042
3043 Given screen coordinates sx and sy, find closest intersection of
3044 view ray with surfaces and return coordinates of intersection in x, y,
3045 z, and identifier of surface in id.
3046
3047 \param sx,sy screen coordinates
3048 \param[out] id surface id
3049 \param[out] x,y,z point on surface (model coordinates?)
3050
3051 \returns 0 if no intersections found
3052 \return number of intersections
3053 */
3054int GS_get_selected_point_on_surface(int sx, int sy, int *id, float *x,
3055 float *y, float *z)
3056{
3057 float los[2][3], find_dist[MAX_SURFS], closest;
3058 Point3 point, tmp, finds[MAX_SURFS];
3059 int surfs[MAX_SURFS], i, iclose, numhits = 0;
3060 geosurf *gs;
3061
3062 /* returns surface-world coords */
3063 gsd_get_los(los, (short)sx, (short)sy);
3064
3065 if (!gs_setlos_enterdata(los)) {
3066 G_debug(3, "gs_setlos_enterdata(los): returns false");
3067 return (0);
3068 }
3069
3070 for (i = 0; i < Next_surf; i++) {
3071 G_debug(3, "id=%d", i);
3072
3073 gs = gs_get_surf(Surf_ID[i]);
3074
3075 /* los_intersect expects surf-world coords (xy transl, no scaling) */
3076
3077#if NVIZ_HACK
3078 if (gs_los_intersect1(Surf_ID[i], los, point)) {
3079#else
3080 if (gs_los_intersect(Surf_ID[i], los, point)) {
3081#endif
3082 if (!gs_point_is_masked(gs, point)) {
3083 GS_v3eq(tmp, point);
3084 tmp[X] += gs->x_trans;
3085 tmp[Y] += gs->y_trans;
3086 tmp[Z] += gs->z_trans;
3088 gsd_surf2real(gs, point);
3089 GS_v3eq(finds[numhits], point);
3090 surfs[numhits] = Surf_ID[i];
3091 numhits++;
3092 }
3093 }
3094 }
3095
3096 for (i = iclose = 0; i < numhits; i++) {
3098
3099 if (find_dist[i] < closest) {
3100 iclose = i;
3101 }
3102 }
3103
3104 if (numhits) {
3105 *x = finds[iclose][X];
3106 *y = finds[iclose][Y];
3107 *z = finds[iclose][Z];
3108 *id = surfs[iclose];
3109 }
3110
3111 G_debug(3, "NumHits %d, next %d", numhits, Next_surf);
3112
3113 return (numhits);
3114}
3115
3116/*!
3117 \brief Set cplace rotation
3118
3119 \param num cplace id
3120 \param dx,dy,dz rotation values
3121 */
3122void GS_set_cplane_rot(int num, float dx, float dy, float dz)
3123{
3124 gsd_cplane_setrot(num, dx, dy, dz);
3125
3126 return;
3127}
3128
3129/*!
3130 \brief Set cplace trans
3131
3132 \param num cplace id
3133 \param dx,dy,dz rotation values
3134 */
3135void GS_set_cplane_trans(int num, float dx, float dy, float dz)
3136{
3137 gsd_cplane_settrans(num, dx, dy, dz);
3138
3139 return;
3140}
3141
3142/*!
3143 \brief Draw cplace
3144
3145 \param num cplace id
3146 */
3147void GS_draw_cplane(int num)
3148{
3150 int nsurfs;
3151
3153 if (2 == nsurfs) {
3154 /* testing */
3156 gsd_draw_cplane_fence(gsurfs[0], gsurfs[1], num);
3157 }
3158 else {
3159 gsd_draw_cplane(num);
3160 }
3161
3162 return;
3163}
3164
3165/*!
3166 \brief Draw cplace fence ?
3167
3168 \param hs1,hs2
3169 \param num cplane id
3170
3171 \return 0 on error
3172 \return 1 on success
3173 */
3174int GS_draw_cplane_fence(int hs1, int hs2, int num)
3175{
3176 geosurf *gs1, *gs2;
3177
3178 if (NULL == (gs1 = gs_get_surf(hs1))) {
3179 return (0);
3180 }
3181
3182 if (NULL == (gs2 = gs_get_surf(hs2))) {
3183 return (0);
3184 }
3185
3187
3188 return (1);
3189}
3190
3191/*!
3192 \brief Draw all cplace fences ?
3193 */
3195{
3196 int onstate[MAX_CPLANES], i;
3197
3199
3200 for (i = 0; i < MAX_CPLANES; i++) {
3201 if (onstate[i]) {
3202 GS_draw_cplane_fence(Surf_ID[0], Surf_ID[1], i);
3203 }
3204 }
3205
3206 return;
3207}
3208
3209/*!
3210 \brief Set cplace
3211
3212 \param num cplane id
3213 */
3214void GS_set_cplane(int num)
3215{
3216 gsd_cplane_on(num);
3217
3218 return;
3219}
3220
3221/*!
3222 \brief Unset clip place (turn off)
3223
3224 \param num cplane id
3225 */
3226void GS_unset_cplane(int num)
3227{
3228 gsd_cplane_off(num);
3229
3230 return;
3231}
3232
3233/*!
3234 \brief Get axis scale
3235
3236 \param sx,sy,sz x/y/z scale values
3237 \param doexag use vertical exaggeration
3238 */
3239void GS_get_scale(float *sx, float *sy, float *sz, int doexag)
3240{
3241 float zexag;
3242
3243 zexag = doexag ? Gv.vert_exag : 1.;
3244 *sx = *sy = Gv.scale;
3245 *sz = Gv.scale * zexag;
3246
3247 return;
3248}
3249
3250/*!
3251 \brief Set fence color
3252
3253 \param mode mode id
3254 */
3255void GS_set_fencecolor(int mode)
3256{
3257 gsd_setfc(mode);
3258
3259 return;
3260}
3261
3262/*!
3263 \brief Get fence color
3264
3265 \return color value
3266 */
3268{
3269 return gsd_getfc();
3270}
3271
3272/*!
3273 \brief Measure distance "as the ball rolls" between two points on
3274 surface
3275
3276 \param hs surface id
3277 \param x1,y1,x2,y2 two points on surface
3278 \param[out] dist measured distance
3279 \param use_exag use exag. surface
3280
3281 \return 0 on error or if one or more points is not in region
3282 \return distance following terrain
3283 */
3284int GS_get_distance_alongsurf(int hs, float x1, float y1, float x2, float y2,
3285 float *dist, int use_exag)
3286{
3287 geosurf *gs;
3288 Point3 p1, p2;
3289
3290 gs = gs_get_surf(hs);
3291 if (gs == NULL) {
3292 return 0;
3293 }
3294
3295 p1[X] = x1;
3296 p1[Y] = y1;
3297 p2[X] = x2;
3298 p2[Y] = y2;
3300 gsd_real2surf(gs, p2);
3301
3302 G_debug(3, "GS_get_distance_alongsurf(): hs=%d p1=%f,%f p2=%f,%f", hs, x1,
3303 y1, x2, y2);
3304 return gs_distance_onsurf(gs, p1, p2, dist, use_exag);
3305}
3306
3307/*!
3308 \brief Save 3d view
3309
3310 \param vname view file name
3311 \param surfid surface id
3312
3313 \return ?
3314 */
3315int GS_save_3dview(const char *vname, int surfid)
3316{
3317 return (Gs_save_3dview(vname, &Gv, &Gd, &wind, gs_get_surf(surfid)));
3318}
3319
3320/*!
3321 \brief Load 3d view
3322
3323 \param vname view file name
3324 \param surfid surface id
3325
3326 \return ?
3327 */
3328int GS_load_3dview(const char *vname, int surfid)
3329{
3330
3331 return (Gs_load_3dview(vname, &Gv, &Gd, &wind, gs_get_surf(surfid)));
3332
3333 /* what to do about lights - I guess, delete all &
3334 create any that exist in 3dview file */
3335}
3336
3337/************************************************************************
3338 * Following routines use Graphics Library
3339 ************************************************************************/
3340
3341/*!
3342 \brief Init viewpoint
3343
3344 \todo allow setting center?
3345 */
3347{
3348 static int first = 1;
3349
3350 G_debug(3, "GS_init_view");
3351
3352 if (first) {
3353 first = 0;
3355
3356 /* OGLXXX doublebuffer: use GLX_DOUBLEBUFFER in attriblist */
3357 /* glxChooseVisual(*dpy, screen, *attriblist); */
3358 /* OGLXXX
3359 * ZMIN not needed -- always 0.
3360 * ZMAX not needed -- always 1.
3361 * getgdesc other posiblilties:
3362 * glxGetConfig();
3363 * glxGetCurrentContext();
3364 * glxGetCurrentDrawable();
3365 * GLint gdtmp;
3366 * getgdesc other posiblilties:
3367 * glxGetConfig();
3368 * glxGetCurrentContext();
3369 * glxGetCurrentDrawable();
3370 * GLint gdtmp;
3371 * glDepthRange params must be scaled to [0, 1]
3372 */
3373 glDepthRange(0.0, 1.0);
3376 /* } */
3377
3378 /* replace these with something meaningful */
3379 Gv.fov = 450;
3380 Gv.twist = 0;
3381
3383
3384 Gv.from_to[FROM][X] = Gv.from_to[FROM][Y] = Gv.from_to[FROM][Z] =
3385 GS_UNIT_SIZE / 2.;
3386
3387 Gv.from_to[TO][X] = GS_UNIT_SIZE / 2.;
3388 Gv.from_to[TO][Y] = GS_UNIT_SIZE / 2.;
3389 Gv.from_to[TO][Z] = 0.;
3390 Gv.from_to[TO][W] = Gv.from_to[FROM][W] = 1.;
3391
3392 Gv.real_to[W] = 1.;
3393 Gv.vert_exag = 1.;
3394
3395 GS_v3eq(Gv.real_to, Gv.from_to[TO]);
3396 GS_v3normalize(Gv.from_to[FROM], Gv.from_to[TO]);
3397
3398 /*
3399 Gd.nearclip = 50;
3400 Gd.farclip = 10000.;
3401 */
3402 Gd.nearclip = 10.;
3403 Gd.farclip = 10000.;
3404 Gd.aspect = (float)GS_get_aspect();
3405
3406 GS_set_focus(Gv.real_to);
3407 }
3408
3409 return;
3410}
3411
3412/*!
3413 \brief Clear view
3414
3415 \param col color value
3416 */
3417void GS_clear(int col)
3418{
3419 G_debug(3, "GS_clear");
3420
3421 col = col | 0xFF000000;
3422
3423 /* OGLXXX
3424 * change glClearDepth parameter to be in [0, 1]
3425 * ZMAX not needed -- always 1.
3426 * getgdesc other posiblilties:
3427 * glxGetConfig();
3428 * glxGetCurrentContext();
3429 * glxGetCurrentDrawable();
3430 * GLint gdtmp;
3431 */
3432 glClearDepth(1.0);
3434 ((float)((col) & 0xff)) / 255., (float)((col) >> 8 & 0xff) / 255.,
3435 (float)((col) >> 16 & 0xff) / 255., (float)((col) >> 24 & 0xff) / 255.);
3437
3438 Gd.bgcol = col;
3439 Modelshowing = 0;
3440 gsd_flush();
3441
3442 return;
3443}
3444
3445/*!
3446 \brief Get aspect value
3447
3448 \return aspect value
3449 */
3450double GS_get_aspect(void)
3451{
3452 int left, right, bottom, top;
3453 GLint tmp[4];
3454
3455 /* OGLXXX
3456 * get GL_VIEWPORT:
3457 * You can probably do better than this.
3458 */
3460 left = tmp[0];
3461 right = tmp[0] + tmp[2] - 1;
3462 bottom = tmp[1];
3463 top = tmp[1] + tmp[3] - 1;
3464
3465 G_debug(3, "GS_get_aspect(): left=%d, right=%d, top=%d, bottom=%d", left,
3466 right, top, bottom);
3467
3468 return ((double)(right - left) / (top - bottom));
3469}
3470
3471/*!
3472 \brief Check for transparency
3473
3474 Disabled.
3475
3476 \return 1
3477 */
3479{
3480 /* OGLXXX
3481 * getgdesc other posiblilties:
3482 * glxGetConfig();
3483 * glxGetCurrentContext();
3484 * glxGetCurrentDrawable();
3485 * GLint gdtmp;
3486 * blending is ALWAYS supported.
3487 * This function returns whether it is enabled.
3488 * return((glGetIntegerv(GL_BLEND, &gdtmp), gdtmp));
3489 */
3490
3491 return (1);
3492}
#define NULL
Definition ccmath.h:32
void G_free(void *)
Free allocated memory.
Definition gis/alloc.c:147
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_warning(const char *,...) __attribute__((format(printf
void G_get_set_window(struct Cell_head *)
Get the current working window (region)
#define G_malloc(n)
Definition defs/gis.h:139
char * G_fully_qualified_name(const char *, const char *)
Get fully qualified element name.
Definition nme_in_mps.c:101
int G_debug(int, const char *,...) __attribute__((format(printf
const char * G_find_raster2(const char *, const char *)
Find a raster map (look but don't touch)
Definition find_rast.c:76
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
int gs_malloc_lookup(geosurf *, int)
Allocate attribute lookup.
Definition gs.c:746
int gs_point_is_masked(geosurf *, float *)
Check if point is masked.
Definition gs.c:1314
GLuint gsd_put_legend(const char *, GLuint, int, int *, float *, int *)
Put legend.
Definition gsd_legend.c:201
void gpd_obj(geosurf *, gvstyle *, Point3)
Draw point representing object.
Definition gpd.c:70
void gsd_setfc(int)
ADD.
Definition gsd_surf.c:1205
int gs_get_zextents(geosurf *, float *, float *, float *)
Get z-extent values.
Definition gs.c:997
int gsd_getfc(void)
ADD.
Definition gsd_surf.c:1217
void gsd_pushmatrix(void)
Push the current matrix stack.
Definition gsd_prim.c:511
void gsd_real2surf(geosurf *, Point3)
Convert real to surface coordinates.
Definition gsd_views.c:481
void gsd_backface(int)
ADD.
Definition gsd_prim.c:254
int gsds_newh(const char *)
Get handle to gsds.
Definition gsds.c:219
void gsd_line_onsurf(geosurf *, float *, float *)
Line on surface, fix z-values.
Definition gsd_objs.c:171
void gsd_scale(float, float, float)
Multiply the current matrix by a general scaling matrix.
Definition gsd_prim.c:525
void gsd_draw_cplane(int)
Draw cplane.
Definition gsd_cplane.c:296
int gs_getall_surfaces(geosurf **)
Get array of geosurf structs.
Definition gs.c:109
void gsd_do_scale(int)
Set current scale.
Definition gsd_views.c:355
void gsdiff_set_SDref(geosurf *)
ADD.
Definition gsdiff.c:64
int GS_v2norm(float *)
Change v1 so that it is a unit vector (2D)
Definition gs_util.c:271
void GS_v3sub(float *, float *)
Subtract vectors.
Definition gs_util.c:212
void gv_update_drapesurfs(void)
Update drape surfaces.
Definition gv.c:157
void gsd_draw_cplane_fence(geosurf *, geosurf *, int)
ADD.
Definition gsd_cplane.c:247
void Gs_pack_colors(const char *, int *, int, int)
Pack color table.
Definition gs3.c:637
void gsd_cplane_off(int)
Turn off clip plane.
Definition gsd_cplane.c:126
void gsd_shademodel(int)
Set shaded model.
Definition gsd_prim.c:419
int Gs_save_3dview(const char *, geoview *, geodisplay *, struct Cell_head *, geosurf *)
Save 3dview.
Definition gs3.c:852
int gs_get_zrange(float *, float *)
Get z-range.
Definition gs.c:1086
void Gs_pack_colors_float(const char *, float *, int *, int, int)
Pack color table (floating-point map)
Definition gs3.c:705
int gs_los_intersect(int, float **, float *)
Crude method of intersecting line of sight with closest part of surface.
Definition gs_query.c:192
void gsd_calllists(int)
ADD.
Definition gsd_prim.c:1185
int gs_get_att_src(geosurf *, int)
Get attribute source.
Definition gs.c:656
int gsds_findh(const char *, IFLAG *, IFLAG *, int)
int Gs_update_attrange(geosurf *, int)
Update no_zero ranges for attribute (actually no_null now)
Definition gs3.c:1084
void GS_v3add(float *, float *)
Sum vectors.
Definition gs_util.c:195
void gsd_surf2real(geosurf *, Point3)
Convert surface to real coordinates.
Definition gsd_views.c:465
int gs_calc_normals(geosurf *)
Calculate normals.
Definition gs_norms.c:124
int GS_v3normalize(float *, float *)
Change v2 so that v1v2 is a unit vector.
Definition gs_util.c:321
int Gs_loadmap_as_short(struct Cell_head *, const char *, short *, struct BM *, int *)
Load raster map as integer map.
Definition gs3.c:309
geosurf * gs_get_surf(int)
Get geosurf struct.
Definition gs.c:63
void gs_delete_surf(int)
Remove geosurf struct from list.
Definition gs.c:463
void gsd_deletelist(GLuint, int)
Delete list.
Definition gsd_prim.c:1153
int gsds_set_changed(int, IFLAG)
void gsd_init_lightmodel(void)
Initialize model light.
Definition gsd_prim.c:719
void gsd_drawsphere(float *, unsigned long, float)
Draws a sphere at the specified center location.
Definition gsd_objs.c:565
int gs_get_datacenter(float *)
Get data center point.
Definition gs.c:1230
void gsd_switchlight(int, int)
Switch light on/off.
Definition gsd_prim.c:877
int Gs_loadmap_as_char(struct Cell_head *, const char *, unsigned char *, struct BM *, int *)
Load raster map as integer map.
Definition gs3.c:415
int gsds_free_data_buff(int, int)
Free allocated buffer.
Definition gsds.c:369
void gsdiff_set_SDscale(float)
Set scale.
Definition gsdiff.c:42
void gsd_calllist(int)
ADD.
Definition gsd_prim.c:1173
void gsd_swapbuffers(void)
Swap buffers.
Definition gsd_prim.c:482
void GS_v3eq(float *, float *)
Copy vector values.
Definition gs_util.c:178
int Gs_load_3dview(const char *, geoview *, geodisplay *, struct Cell_head *, const geosurf *)
Load 3dview.
Definition gs3.c:951
size_t gs_malloc_att_buff(geosurf *, int, int)
Allocate attribute buffer.
Definition gs.c:717
int in_vregion(geosurf *, float *)
ADD.
Definition gsdrape.c:698
int Gs_loadmap_as_bitmap(struct Cell_head *, const char *, struct BM *)
Load raster map as integer map.
Definition gs3.c:516
void gs_set_defaults(geosurf *, float *, float *)
Set default attribute values.
Definition gs.c:441
int gs_mapcolor(typbuff *, gsurf_att *, int)
Call this one when you already know att_src is MAP_ATT.
Definition gs.c:968
void gsd_cplane_setrot(int, float, float, float)
ADD.
Definition gsd_cplane.c:211
int Gs_get_cat_label(const char *, int, int, char *)
Get categories/labels.
Definition gs3.c:776
void gsd_get_cplanes_state(int *)
Get cplane state.
Definition gsd_cplane.c:142
int gsd_nline_onsurf(geosurf *, float *, float *, float *, int)
Multiline on surface, fix z-values.
Definition gsd_objs.c:216
int gs_update_curmask(geosurf *)
Update current maps.
Definition gs_bm.c:228
float gsdiff_get_SDscale(void)
Get scale.
Definition gsdiff.c:54
void gsd_color_func(unsigned int)
Set current color.
Definition gsd_prim.c:698
int gs_set_att_src(geosurf *, int, int)
Set attribute source.
Definition gs.c:826
void gs_init(void)
Initialize library.
Definition gs.c:48
void gsd_backbuffer(void)
Draw to the back buffer.
Definition gsd_prim.c:470
geosurf * gs_get_new_surface(void)
Allocate new geosurf struct.
Definition gs.c:194
void gsd_translate(float, float, float)
Multiply the current matrix by a translation matrix.
Definition gsd_prim.c:539
int gs_set_att_type(geosurf *, int, int)
Set attribute type.
Definition gs.c:802
int gsd_wire_surf(geosurf *)
Draw surface wire.
Definition gsd_wire.c:46
void gsd_popmatrix(void)
Pop the current matrix stack.
Definition gsd_prim.c:501
void gsd_real2model(Point3)
Convert real to model coordinates.
Definition gsd_views.c:373
int Gs_build_256lookup(const char *, int *)
Build color table (256)
Definition gs3.c:576
void gsd_flush(void)
Mostly for flushing drawing commands across a network.
Definition gsd_prim.c:84
void gsd_set_view(geoview *, geodisplay *)
Set view.
Definition gsd_views.c:146
int Gs_loadmap_as_float(struct Cell_head *, const char *, float *, struct BM *, int *)
Load raster map as floating point map.
Definition gs3.c:109
void gsd_viewport(int, int, int, int)
Set the viewport.
Definition gsd_prim.c:1077
void gsd_zwritemask(unsigned long)
Write out z-mask.
Definition gsd_prim.c:241
void gsd_linewidth(short)
Set width of rasterized lines.
Definition gsd_prim.c:267
int gs_num_surfaces(void)
Get number of surfaces.
Definition gs.c:128
int gs_distance_onsurf(geosurf *, float *, float *, float *, int)
Calculate distance on surface.
Definition gs.c:1414
int gs_init_surf(geosurf *, double, double, int, int, double, double)
Initialize allocated geosurf struct.
Definition gs.c:234
void gsd_colormode(int)
Set color mode.
Definition gsd_prim.c:98
typbuff * gs_get_att_typbuff(geosurf *, int, int)
Get attribute data buffer.
Definition gs.c:681
int GS_coordpair_repeats(float *, float *, int)
ADD.
Definition gs_util.c:440
void gsd_display_fringe(geosurf *, unsigned long, float, int[4])
Display fridge.
Definition gsd_fringe.c:51
int GS_v3dir(float *, float *, float *)
Get a normalized direction from v1 to v2, store in v3.
Definition gs_util.c:351
int _viewcell_tri_interp(geosurf *, Point3)
ADD.
Definition gsdrape.c:464
int gs_get_data_avg_zmax(float *)
Get average z-max value.
Definition gs.c:1201
int gsd_get_los(float(*)[3], short, short)
ADD.
Definition gsd_views.c:40
int Gs_numtype(const char *, int *)
Get map data type.
Definition gs3.c:227
void gsd_model2real(Point3)
Convert model to real coordinates.
Definition gsd_views.c:393
int gs_set_att_const(geosurf *, int, float)
Set attribute constant value.
Definition gs.c:871
int gvl_get_zrange(float *, float *)
Get volume z-range value.
Definition gvl.c:478
int gs_setlos_enterdata(Point3 *)
Definition gs_query.c:529
int gs_att_is_set(geosurf *, IFLAG)
void gsd_cplane_settrans(int, float, float, float)
ADD.
Definition gsd_cplane.c:229
int gs_los_intersect1(int, float(*)[3], float *)
Crude method of intersecting line of sight with closest part of surface.
Definition gs_query.c:52
void gsd_deflight(int, struct lightdefs *)
Define light.
Definition gsd_prim.c:836
int gs_init_normbuff(geosurf *)
Init geosurf normbuff.
Definition gs.c:308
float GS_distance(float *, float *)
Calculate distance.
Definition gs_util.c:141
void gsd_bothbuffers(void)
Draw to the front and back buffers.
Definition gsd_prim.c:446
char * gsds_get_name(int)
Get name.
Definition gsds.c:303
void gsd_frontbuffer(void)
Draw to the front buffer.
Definition gsd_prim.c:458
int gsd_surf(geosurf *)
ADD.
Definition gsd_surf.c:80
geosurf * gsdiff_get_SDref(void)
ADD.
Definition gsdiff.c:77
int Gs_loadmap_as_int(struct Cell_head *, const char *, int *, struct BM *, int *)
Load raster map as integer map.
Definition gs3.c:174
void gsd_cplane_on(int)
ADD.
Definition gsd_cplane.c:104
void Rast_get_cellhd(const char *, const char *, struct Cell_head *)
Read the raster header.
Definition get_cellhd.c:41
#define min(x, y)
Definition draw2.c:29
#define max(x, y)
Definition draw2.c:30
#define TRUE
Definition gis.h:78
#define FALSE
Definition gis.h:82
#define _(str)
Definition glocale.h:10
void GS_unset_cplane(int num)
Unset clip place (turn off)
Definition gs2.c:3226
void GS_zoom_setup(int *a, int *b, int *c, int *d, int *maxx, int *maxy)
Get zoom setup.
Definition gs2.c:2770
int GS_get_twist(void)
Get twist value.
Definition gs2.c:2863
void GS_set_cplane_rot(int num, float dx, float dy, float dz)
Set cplace rotation.
Definition gs2.c:3122
int GS_get_zextents(int id, float *min, float *max, float *mid)
Get z-extent for a single surface.
Definition gs2.c:2665
int GS_setall_drawres(int xres, int yres, int xwire, int ywire)
Set all draw resolutions.
Definition gs2.c:2199
int GS_set_SDscale(float scale)
Set ?
Definition gs2.c:1064
void GS_set_global_exag(float exag)
Set global z-exag value.
Definition gs2.c:1978
int GS_new_surface(void)
Add new surface.
Definition gs2.c:223
void GS_get_modelposition(float *size, float *pos)
Retrieves coordinates for lighting model position, at center of view.
Definition gs2.c:528
void GS_draw_list(GLuint list_id)
Draw pre-defined list.
Definition gs2.c:861
void GS_alldraw_cplane_fences(void)
Draw all cplace fences ?
Definition gs2.c:3194
void GS_get_zrange_nz(float *min, float *max)
Get Z extents for all loaded surfaces.
Definition gs2.c:2358
void GS_draw_X(int id, float *pt)
Draw place marker.
Definition gs2.c:634
void GS_set_cplane_trans(int num, float dx, float dy, float dz)
Set cplace trans.
Definition gs2.c:3135
void GS_draw_surf(int id)
Draw surface.
Definition gs2.c:1865
void GS_draw_all_list(void)
Draw all glLists.
Definition gs2.c:874
void GS_set_focus(float *realto)
Set focus.
Definition gs2.c:2520
void GS_getlight_color(int num, float *red, float *green, float *blue)
Get light color.
Definition gs2.c:378
int GS_update_normals(int id)
Update normals.
Definition gs2.c:1113
void GS_set_infocus(void)
Set focus.
Definition gs2.c:2965
int GS_get_light_reset(void)
Definition gs2.c:257
int GS_load_att_map(int id, const char *filename, int att)
Load raster map as attribute.
Definition gs2.c:1600
unsigned int GS_default_draw_color(void)
Get default draw color.
Definition gs2.c:2439
void GS_set_focus_real(float *realto)
Set real focus.
Definition gs2.c:2538
void GS_set_rotation_matrix(double *matrix)
Set rotation matrix.
Definition gs2.c:2939
void GS_get_from(float *fr)
Get viewpoint 'from' position.
Definition gs2.c:2724
void GS_get_dims(int id, int *rows, int *cols)
Get dimension of surface.
Definition gs2.c:2280
void GS_switchlight(int num, int on)
Switch on/off light.
Definition gs2.c:470
void GS_draw_cplane(int num)
Draw cplace.
Definition gs2.c:3147
void GS_get_viewdir(float *dir)
Get viewdir.
Definition gs2.c:2807
void GS_alldraw_wire(void)
Draw all wires.
Definition gs2.c:1920
void GS_clear(int col)
Clear view.
Definition gs2.c:3417
void GS_getlight_ambient(int num, float *red, float *green, float *blue)
Get light ambient.
Definition gs2.c:422
void GS_init_rotation(void)
Reset scene rotation.
Definition gs2.c:2907
void GS_set_focus_center_map(int id)
Set focus to map center.
Definition gs2.c:2581
int GS_set_drawres(int id, int xres, int yres, int xwire, int ywire)
Set draw resolution for surface.
Definition gs2.c:2222
int GS_look_here(int sx, int sy)
Send screen coords sx and sy, lib traces through surfaces; sets new center to point of nearest inters...
Definition gs2.c:3005
void GS_set_cplane(int num)
Set cplace.
Definition gs2.c:3214
int GS_get_att(int id, int att, int *set, float *constant, char *mapname)
Get attributes.
Definition gs2.c:1134
int GS_delete_surface(int id)
Delete surface.
Definition gs2.c:1559
int GS_update_curmask(int id)
Update current mask.
Definition gs2.c:991
int * GS_get_surf_list(int *numsurfs)
Get surface list.
Definition gs2.c:1532
int GS_get_SDscale(float *scale)
Get ?
Definition gs2.c:1099
double GS_get_aspect(void)
Get aspect value.
Definition gs2.c:3450
int GS_get_selected_point_on_surface(int sx, int sy, int *id, float *x, float *y, float *z)
Get selected point of surface.
Definition gs2.c:3054
int GS_get_SDsurf(int *id)
Get ?
Definition gs2.c:1079
int GS_new_light(void)
Add new model light.
Definition gs2.c:268
int GS_draw_nline_onsurf(int id, float x1, float y1, float x2, float y2, float *lasp, int n)
Draw multiline on surface.
Definition gs2.c:715
void GS_get_trans(int id, float *xtrans, float *ytrans, float *ztrans)
Get translation values (surface position)
Definition gs2.c:2416
int GS_get_distance_alongsurf(int hs, float x1, float y1, float x2, float y2, float *dist, int use_exag)
Measure distance "as the ball rolls" between two points on surface.
Definition gs2.c:3284
int GS_get_zrange(float *min, float *max, int doexag)
Get z-extent for all loaded surfaces.
Definition gs2.c:2688
int GS_save_3dview(const char *vname, int surfid)
Save 3d view.
Definition gs2.c:3315
int GS_get_val_at_xy(int id, int att, char *valstr, float x, float y)
Get RGB color at given point.
Definition gs2.c:1303
void GS_draw_line_onsurf(int id, float x1, float y1, float x2, float y2)
Draw line on surface.
Definition gs2.c:675
void GS_set_viewdir(float *dir)
Set viewdir.
Definition gs2.c:2821
void GS_draw_flowline_at_xy(int id, float x, float y)
Draw flow-line on surace.
Definition gs2.c:753
void GS_moveto(float *pt)
Move viewpoint.
Definition gs2.c:2616
void GS_get_scale(float *sx, float *sy, float *sz, int doexag)
Get axis scale.
Definition gs2.c:3239
int GS_get_fov(void)
Get field of view.
Definition gs2.c:2853
int GS_transp_is_set(void)
Check if transparency is set.
Definition gs2.c:489
void GS_libinit(void)
Initialize OGSF library.
Definition gs2.c:98
void GS_setlight_color(int num, float red, float green, float blue)
Set light color.
Definition gs2.c:356
int GS_get_fencecolor(void)
Get fence color.
Definition gs2.c:3267
void void_func(void)
Definition gs2.c:86
int GS_get_nozero(int id, int att, int *mode)
Get no-zero ?
Definition gs2.c:2165
void GS_set_trans(int id, float xtrans, float ytrans, float ztrans)
Set translation (surface position)
Definition gs2.c:2392
int GS_get_region(float *n, float *s, float *w, float *e)
Get 2D region extent.
Definition gs2.c:156
void GS_get_drawres(int id, int *xres, int *yres, int *xwire, int *ywire)
Get draw resolution of surface.
Definition gs2.c:2256
void GS_delete_list(GLuint list_id)
Delete pre-defined list.
Definition gs2.c:886
void GS_get_rotation_matrix(double *matrix)
Get rotation matrix.
Definition gs2.c:2927
void GS_unset_SDsurf(void)
Unset Scaled Difference surface.
Definition gs2.c:1027
void GS_set_nozero(int id, int att, int mode)
Set no-zero ?
Definition gs2.c:2132
void GS_set_Narrow(int *pt, int id, float *pos2)
Set decoration, north arrow ??
Definition gs2.c:564
int GS_get_focus(float *realto)
Get focus.
Definition gs2.c:2562
int GS_num_surfs(void)
Get number of surfaces.
Definition gs2.c:1517
void GS_draw_fringe(int id, unsigned long clr, float elev, int *where)
Draw fringe around data (surface) at selected corners.
Definition gs2.c:820
void GS_unset_rotation(void)
Stop scene rotation.
Definition gs2.c:2899
int GS_get_wire_color(int id, int *colr)
Get wire color.
Definition gs2.c:2039
int GS_is_masked(int id, float *pt)
Check if point is masked ?
Definition gs2.c:1009
void GS_draw_lighting_model(void)
Draw lighting model.
Definition gs2.c:936
void GS_set_fencecolor(int mode)
Set fence color.
Definition gs2.c:3255
int GS_get_exag_guess(int id, float *exag)
Get exag-value guess.
Definition gs2.c:2307
void GS_set_rotation(double angle, double x, double y, double z)
Set rotation params.
Definition gs2.c:2885
void GS_set_light_reset(int i)
Definition gs2.c:250
int GS_get_maskmode(int id, int *mode)
Get mask mode.
Definition gs2.c:1454
int GS_get_drawmode(int id, int *mode)
Get draw mode.
Definition gs2.c:2110
void GS_get_to(float *to)
Get 'to' model coordinates.
Definition gs2.c:2793
void GS_set_wire_color(int id, int colr)
Set wire color.
Definition gs2.c:2015
void GS_lights_on(void)
Switch on all lights.
Definition gs2.c:453
void GS_set_exag(int id, float exag)
Set Z exag for surface.
Definition gs2.c:1954
void GS_ready_draw(void)
Definition gs2.c:2488
int GS_surf_exists(int id)
Definition gs2.c:194
int gsd_getViewport(GLint *, GLint *)
int GS_draw_cplane_fence(int hs1, int hs2, int num)
Draw cplace fence ?
Definition gs2.c:3174
void GS_setlight_position(int num, float xpos, float ypos, float zpos, int local)
Set light position.
Definition gs2.c:309
unsigned int GS_background_color(void)
Get background color.
Definition gs2.c:2452
int GS_set_drawmode(int id, int mode)
Set draw mode.
Definition gs2.c:2084
void GS_alldraw_surf(void)
Draw all surfaces.
Definition gs2.c:1937
int GS_setall_drawmode(int mode)
Set all draw-modes.
Definition gs2.c:2062
void GS_init_view(void)
Init viewpoint.
Definition gs2.c:3346
int GS_set_SDsurf(int id)
Set surface as Scaled Difference surface.
Definition gs2.c:1043
void GS_setlight_ambient(int num, float red, float green, float blue)
Set light ambient.
Definition gs2.c:400
void GS_set_draw(int where)
Sets which buffer to draw to.
Definition gs2.c:2462
int GS_get_cat_at_xy(int id, int att, char *catstr, float x, float y)
Get surface category on given position.
Definition gs2.c:1177
int GS_draw_legend(const char *name, GLuint fontbase, int size, int *flags, float *range, int *pt)
Draw legend.
Definition gs2.c:843
void GS_moveto_real(float *pt)
Move position to (real)
Definition gs2.c:2646
void GS_get_from_real(float *fr)
Get viewpoint 'from' real coordinates.
Definition gs2.c:2738
int GS_set_att_const(int id, int att, float constant)
Set attribute constant.
Definition gs2.c:1405
int GS_Set_ClientData(int id, void *clientd)
Set client data.
Definition gs2.c:1478
int GS_load_3dview(const char *vname, int surfid)
Load 3d view.
Definition gs2.c:3328
void GS_set_att_defaults(float *defs, float *null_defs)
Set default attributes for map objects.
Definition gs2.c:172
void GS_draw_lighting_model1(void)
Draw lighting model.
Definition gs2.c:896
void GS_set_nofocus(void)
Unset focus.
Definition gs2.c:2951
int GS_get_longdim(float *dim)
Get largest dimension.
Definition gs2.c:140
int GS_unset_att(int id, int att)
Unset attribute.
Definition gs2.c:1386
void GS_set_viewport(int left, int right, int bottom, int top)
Set viewport.
Definition gs2.c:2979
void GS_getlight_position(int num, float *xpos, float *ypos, float *zpos, int *local)
Get light position.
Definition gs2.c:334
void GS_done_draw(void)
Draw done, swap buffers.
Definition gs2.c:2501
void GS_set_fov(int fov)
Set field of view.
Definition gs2.c:2841
void GS_get_modelposition1(float pos[])
Retrieves coordinates for lighting model position, at center of view.
Definition gs2.c:499
int GS_get_norm_at_xy(int id, float x, float y, float *nv)
Get surface normal at x,y (real coordinates)
Definition gs2.c:1239
int GS_set_maskmode(int id, int mode)
Set mask mode.
Definition gs2.c:1429
void * GS_Get_ClientData(int id)
Get client data.
Definition gs2.c:1500
int GS_has_transparency(void)
Check for transparency.
Definition gs2.c:3478
void GS_draw_wire(int id)
Draw surface wire.
Definition gs2.c:1900
void GS_lights_off(void)
Switch off all lights.
Definition gs2.c:439
void GS_get_to_real(float *to)
Get 'to' real coordinates.
Definition gs2.c:2751
void GS_set_twist(int t)
Set viewpoint twist value.
Definition gs2.c:2875
float GS_global_exag(void)
Get global z-exag value.
Definition gs2.c:2000
#define INT_TO_GRN(i, g)
Definition gsd_prim.c:54
#define INT_TO_RED(i, r)
Definition gsd_prim.c:53
#define INT_TO_BLU(i, b)
Definition gsd_prim.c:55
#define FNORM(i, nv)
Definition gsget.h:51
#define GET_MAPATT(buff, offset, att)
Definition gsget.h:29
float g
Definition named_colr.c:7
const char * name
Definition named_colr.c:6
OGSF header file (structures)
#define MAX_CPLANES
Definition ogsf.h:47
#define NOTSET_ATT
Definition ogsf.h:84
#define ATT_MASK
Definition ogsf.h:77
#define ATTY_SHORT
Definition ogsf.h:170
#define CM_DIFFUSE
Definition ogsf.h:151
void(* Cxl_func)(void)
Definition gsx.c:21
#define X
Definition ogsf.h:140
#define MAX_ATTS
Definition ogsf.h:45
#define CM_AD
Definition ogsf.h:153
#define ATT_TOPO
Definition ogsf.h:75
#define ST_GYRO
Definition ogsf.h:100
#define ATTY_NULL
Definition ogsf.h:166
#define DM_WIRE_POLY
Definition ogsf.h:64
#define ATT_COLOR
Definition ogsf.h:76
float Point3[3]
Definition ogsf.h:205
#define Z
Definition ogsf.h:142
#define GSD_FRONT
Definition ogsf.h:104
#define DM_WIRE
Definition ogsf.h:61
#define GSD_BOTH
Definition ogsf.h:106
#define W
Definition ogsf.h:143
#define ATTY_FLOAT
Definition ogsf.h:168
#define FC_GREY
Definition ogsf.h:113
#define MAX_LIGHTS
Definition ogsf.h:46
#define ATT_SHINE
Definition ogsf.h:79
#define Y
Definition ogsf.h:141
#define MAP_ATT
Definition ogsf.h:85
#define ATTY_MASK
Definition ogsf.h:167
#define MAX_SURFS
Definition ogsf.h:40
#define GSD_BACK
Definition ogsf.h:105
#define ATTY_INT
Definition ogsf.h:169
#define ATTY_CHAR
Definition ogsf.h:171
#define FROM
Definition ogsf.h:144
#define DM_POLY
Definition ogsf.h:63
#define DM_GOURAUD
Definition ogsf.h:56
#define CONST_ATT
Definition ogsf.h:86
#define ATT_TRANSP
Definition ogsf.h:78
#define GS_UNIT_SIZE
Definition ogsf.h:31
#define CF_COLOR_PACKED
Definition ogsf.h:184
#define TO
Definition ogsf.h:145
#define strcpy
Definition parson.c:66
double b
Definition r_raster.c:39
double t
Definition r_raster.c:39
double r
Definition r_raster.c:39
#define VYRES(gs)
Definition rowcol.h:10
#define Y2VROW(gs, py)
Definition rowcol.h:27
#define VXRES(gs)
Definition rowcol.h:9
#define DRC2OFF(gs, drow, dcol)
Definition rowcol.h:17
#define VROW2DROW(gs, vrow)
Definition rowcol.h:31
#define X2VCOL(gs, px)
Definition rowcol.h:28
#define VCOL2DCOL(gs, vcol)
Definition rowcol.h:32
void free(void *)
2D/3D raster map header (used also for region)
Definition gis.h:446
double bottom
Extent coordinates (bottom) - 3D data.
Definition gis.h:502
double top
Extent coordinates (top) - 3D data.
Definition gis.h:500
int rows
Number of rows for 2D data.
Definition gis.h:461
int cols
Number of columns for 2D data.
Definition gis.h:465
Definition ogsf.h:266
int gsurf_id
Definition ogsf.h:267
Struct for vector feature displaying attributes.
Definition ogsf.h:307
int color
Line color.
Definition ogsf.h:309
int symbol
Point symbol/line type.
Definition ogsf.h:312
float size
Symbol size.
Definition ogsf.h:318
#define x