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