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