GRASS 8 Programmer's Manual 8.6.0dev(2026)-4bb960b182
Loading...
Searching...
No Matches
gs.c
Go to the documentation of this file.
1/*!
2 \file lib/ogsf/gs.c
3
4 \brief OGSF library - loading and manipulating surfaces (lower level
5 functions)
6
7 GRASS OpenGL gsurf OGSF Library
8
9 SPDX-FileCopyrightText: 1999-2008 GRASS Development Team
10 SPDX-License-Identifier: GPL-2.0-or-later
11
12 \author Bill Brown USACERL, GMSL/University of Illinois (January 1993)
13 \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
14 */
15
16#include <stdlib.h>
17#include <stdio.h>
18
19#include <grass/ogsf.h>
20#include <grass/glocale.h>
21
22#include "gsget.h"
23#include "rowcol.h"
24
25#define FIRST_SURF_ID 110658
26
27static geosurf *Surf_top;
28static int Invertmask;
29
30/***********************************************************************/
31void gs_err(const char *msg)
32{
33 G_warning("%s", msg);
34
35 return;
36}
37
38/*!
39 \brief Initialize library
40
41 Still need to take care of library initialization,
42 probably want to define a Surf_top of constant value (i.e., 0)
43 */
44void gs_init(void)
45{
46 Surf_top = NULL;
47
48 return;
49}
50
51/*!
52 \brief Get geosurf struct
53
54 \param id surface id
55
56 \return pointer to geosurf struct
57 \return NULL if not found
58 */
60{
61 geosurf *gs;
62
63 G_debug(5, "gs_get_surf():");
64
65 for (gs = Surf_top; gs; gs = gs->next) {
66 if (gs->gsurf_id == id) {
67 G_debug(5, " id=%d", id);
68 return (gs);
69 }
70 }
71
72 return (NULL);
73}
74
75/*!
76 \brief Get previous geosurf struct
77
78 \param id current surface id
79
80 \return pointer to geosurf struct
81 \return NULL if not found
82 */
84{
85 geosurf *ps;
86
87 G_debug(5, "gs_get_prev_surface");
88
89 for (ps = Surf_top; ps; ps = ps->next) {
90 if (ps->gsurf_id == id - 1) {
91 return (ps);
92 }
93 }
94
95 return (NULL);
96}
97
98/*!
99 \brief Get array of geosurf structs
100
101 \param gsurfs pointer to array
102
103 \return number of geosurfs
104 */
106{
107 geosurf *gs;
108 int i;
109
110 for (i = 0, gs = Surf_top; gs; gs = gs->next, i++) {
111 gsurfs[i] = gs;
112 }
113
114 G_debug(5, "gs_num_surfaces(): num=%d", i);
115
116 return (i);
117}
118
119/*!
120 \brief Get number of surfaces
121
122 \return number of surfaces
123 */
125{
126 geosurf *gs;
127 int i;
128
129 for (i = 0, gs = Surf_top; gs; gs = gs->next, i++)
130 ;
131
132 G_debug(5, "gs_num_surfaces(): num=%d", i);
133
134 return (i);
135}
136
137/*!
138 \brief Check if attribute is set
139
140 \param surf pointer to gsurf or NULL to look at all geosurfs
141 \param att attribute id
142
143 \return 1 attribute is set up
144 \return 0 attribute is not set up
145 */
147{
148 geosurf *gs;
149
150 if (surf) {
151 return (NOTSET_ATT != surf->att[att].att_src);
152 }
153
154 /* if surf == NULL, look at all surfs */
155 for (gs = Surf_top; gs; gs = gs->next) {
156 if (NOTSET_ATT != gs->att[att].att_src) {
157 return (1);
158 }
159 }
160
161 return (0);
162}
163
164/*!
165 \brief Get last allocated geosurf struct from list
166
167 \return pointer to geosurf struct
168 */
170{
171 geosurf *ls;
172
173 if (!Surf_top) {
174 return (NULL);
175 }
176
177 for (ls = Surf_top; ls->next; ls = ls->next)
178 ;
179
180 G_debug(5, "gs_get_last_surface(): last surface id=%d", ls->gsurf_id);
181
182 return (ls);
183}
184
185/*!
186 \brief Allocate new geosurf struct
187
188 \return pointer to geosurf struct
189 */
191{
192 geosurf *ns, *ls;
193
194 ns = (geosurf *)G_malloc(sizeof(geosurf)); /* G_fatal_error */
195 if (!ns) {
196 return (NULL);
197 }
198
199 if ((ls = gs_get_last_surface())) {
200 ls->next = ns;
201 ns->gsurf_id = ls->gsurf_id + 1;
202 }
203 else {
204 Surf_top = ns;
206 }
207
208 ns->next = NULL;
209
210 G_debug(5, "gs_get_new_surface(): id=%d", ns->gsurf_id);
211
212 return (ns);
213}
214
215/*!
216 \brief Initialize allocated geosurf struct
217
218 \todo Now xmin & ox are the same, right? - get rid of ox, oy in geosurf
219 struct?
220
221 \param gs pointer to geosurf struct
222 \param ox,oy x/y origin coordinates
223 \param rows number of rows
224 \param cols number of cols
225 \param xres,yres x/y resolution value
226
227 \return -1 on error
228 \return 0 on success
229 */
230int gs_init_surf(geosurf *gs, double ox, double oy, int rows, int cols,
231 double xres, double yres)
232{
233 geosurf *ps;
234 int i;
235
236 if (!gs) {
237 return (-1);
238 }
239
240 G_debug(5, "gs_init_surf() id=%d", gs->gsurf_id);
241
242 /* default attributes */
243 for (i = 0; i < MAX_ATTS; i++) {
244 gs->att[i].att_src = NOTSET_ATT;
245 gs->att[i].att_type = ATTY_INT;
246 gs->att[i].hdata = -1;
247 gs->att[i].user_func = NULL;
248 gs->att[i].constant = 0.;
249 gs->att[i].lookup = NULL;
250 gs->att[i].min_nz = gs->att[i].max_nz = gs->att[i].range_nz = 0;
251 gs->att[i].default_null = 0.;
252 }
253
254 /* default values */
255 gs->ox = ox;
256 gs->oy = oy;
257 gs->rows = rows;
258 gs->cols = cols;
259 gs->xres = xres;
260 gs->yres = yres;
261 gs->x_mod = 2;
262 gs->y_mod = 2;
263 gs->x_modw = rows / 30;
264 gs->y_modw = rows / 30;
265 gs->xmin = ox;
266 gs->xmax = ox + (cols - 1) * xres;
267 gs->xrange = gs->xmax - gs->xmin;
268 gs->ymin = oy;
269 gs->ymax = oy + (rows - 1) * yres;
270 gs->yrange = gs->ymax - gs->ymin;
271 gs->zmin = gs->zmin_nz = gs->zminmasked = 0;
272 gs->zmax = gs->zmax_nz = 0;
273 gs->zrange = gs->zrange_nz = 0;
274 gs->wire_color = 0x00888888;
275 gs->x_trans = gs->y_trans = gs->z_trans = 0.0;
276 gs->nz_topo = gs->nz_color = 0;
277 gs->norm_needupdate = 1;
278 gs->mask_needupdate = 1;
279 gs->curmask = NULL;
280 gs->norms = NULL;
281
282 gs->draw_mode = DM_GOURAUD;
283
284 /* default z_exag value */
285 if (gs->gsurf_id == FIRST_SURF_ID) {
286 gs->z_exag = 1.0;
287 }
288 else {
289 ps = gs_get_prev_surface(gs->gsurf_id);
290 gs->z_exag = ps->z_exag;
291 }
292
293 return (0);
294}
295
296/*!
297 \brief Init geosurf normbuff
298
299 \param gs pointer to geosurf struct
300
301 \return 0 on error
302 \return 1 on success
303 */
305{
306 long size;
307
308 if (!gs) {
309 return (0);
310 }
311
312 if (gs->norms) {
313 G_free(gs->norms);
314 }
315
316 size = (long)gs->rows * gs->cols * sizeof(unsigned long);
317
318 gs->norms = (unsigned long *)G_malloc(size); /* G_fatal_error */
319 if (!gs->norms) {
320 return (-1);
321 }
322
323 gs->norm_needupdate = 1;
324
325 return (1);
326}
327
328/*!
329 \brief Debugging, print 'from/to' model coordinates to stderr
330
331 \todo G_debug ?
332
333 \param ft pointer to coordinates
334 */
335void print_frto(float (*ft)[4])
336{
337 fprintf(stderr, "FROM: %f, %f, %f\n", ft[FROM][X], ft[FROM][Y],
338 ft[FROM][Z]);
339 fprintf(stderr, "TO: %f, %f, %f\n", ft[TO][X], ft[TO][Y], ft[TO][Z]);
340
341 return;
342}
343
344/*!
345 \brief Debugging, print 'to' real coordinates to stderr
346
347 \todo G_debug ?
348
349 \param rt pointer to coordinates
350 */
351void print_realto(float *rt)
352{
353 fprintf(stderr, "REAL TO: %f, %f, %f\n", rt[X], rt[Y], rt[Z]);
354
355 return;
356}
357
358/*!
359 \brief Debugging, 256 integer values from buffer
360
361 \todo G_debug ?
362
363 \param buff pointer to buffer
364 */
365void print_256lookup(int *buff)
366{
367 int i;
368
369 for (i = 0; i < 256; i++) {
370 if (!(i % 8)) {
371 fprintf(stderr, "\n");
372 }
373
374 fprintf(stderr, "%x ", buff[i]);
375 }
376
377 fprintf(stderr, "\n");
378
379 return;
380}
381
382/*!
383 \brief Debugging, print geosurf fields to stderr
384
385 \todo G_debug ?
386
387 \param s pointer to geosurf struct
388 */
390{
391 fprintf(stderr, "ID: %d\n", s->gsurf_id);
392 fprintf(stderr, "rows: %d cols: %d\n", s->rows, s->cols);
393 fprintf(stderr, "draw_mode: %x\n", s->draw_mode);
394 fprintf(stderr, "wire_color: %lx\n", s->wire_color);
395 fprintf(stderr, "ox: %lf oy: %lf\n", s->ox, s->oy);
396 fprintf(stderr, "xres: %lf yres: %lf\n", s->xres, s->yres);
397 fprintf(stderr, "z_exag: %f \n", s->z_exag);
398 fprintf(stderr, "x_trans: %f y_trans: %f z_trans: %f\n", s->x_trans,
399 s->y_trans, s->z_trans);
400 fprintf(stderr, "xmin: %f ymin: %f zmin: %f\n", s->xmin, s->ymin, s->zmin);
401 fprintf(stderr, "xmax: %f ymax: %f zmax: %f\n", s->xmax, s->ymax, s->zmax);
402 fprintf(stderr, "x_mod: %d y_mod: %d x_modw: %d y_modw: %d\n", s->x_mod,
403 s->y_mod, s->x_modw, s->y_modw);
404
405 return;
406}
407
408/*!
409 \brief Debugging, print geoview fields to stderr
410
411 \todo G_debug ?
412
413 \param gv pointer to geoview struct
414 */
416{
417 fprintf(stderr, "coord_sys: %d\n", gv->coord_sys);
418 fprintf(stderr, "view_proj: %d\n", gv->view_proj);
419 fprintf(stderr, "infocus: %d\n", gv->infocus);
420 print_frto(gv->from_to);
421 fprintf(stderr, "twist: %d fov: %d\n", gv->twist, gv->fov);
422 fprintf(stderr, "incl: %d look: %d\n", gv->incl, gv->look);
423 fprintf(stderr, "real_to: %f %f %f\n", gv->real_to[X], gv->real_to[Y],
424 gv->real_to[Z]);
425 fprintf(stderr, "vert_exag: %f scale: %f \n", gv->vert_exag, gv->scale);
426
427 return;
428}
429
430/*!
431 \brief Set default attribute values
432
433 \param gs pointer to geosurf struct
434 \param defs array of default values (dim MAX_ATTRS)
435 \param null_defs array of null default values (dim MAX_ATTRS)
436 */
438{
439 int i;
440
441 G_debug(5, "gs_set_defaults(): id=%d", gs->gsurf_id);
442
443 for (i = 0; i < MAX_ATTS; i++) {
444 gs->att[i].constant = defs[i];
445 gs->att[i].default_null = null_defs[i];
446 gs->att[i].lookup = NULL;
447 gs->att[i].hdata = -1;
448 gs->att[i].att_src = NOTSET_ATT;
449 }
450
451 return;
452}
453
454/*!
455 \brief Remove geosurf struct from list
456
457 \param id surface id
458 */
459void gs_delete_surf(int id)
460{
461 geosurf *fs;
462
463 G_debug(5, "gs_delete_surf");
464
465 fs = gs_get_surf(id);
466
467 if (fs) {
469 }
470
471 return;
472}
473
474/*!
475 \brief Free geosurf struct
476
477 \param fs pointer to geosurf struct
478
479 \return 1 found
480 \return 0 not found
481 \return -1 on error
482 */
484{
485 geosurf *gs;
486 int found = 0;
487
488 G_debug(5, "gs_free_surf");
489
490 if (Surf_top) {
491 if (fs == Surf_top) {
492 if (Surf_top->next) {
493 /* can't free top if last */
494 found = 1;
495 Surf_top = fs->next;
496 }
497 else {
499
500 if (fs->curmask) {
501 G_free(fs->curmask);
502 }
503
504 if (fs->norms) {
505 G_free(fs->norms);
506 }
507
508 G_free(fs);
509 Surf_top = NULL;
510 }
511 }
512 else {
513 for (gs = Surf_top; gs && !found; gs = gs->next) {
514 if (gs->next) {
515 if (gs->next == fs) {
516 found = 1;
517 gs->next = fs->next;
518 }
519 }
520 }
521 }
522
523 if (found) {
525
526 if (fs->curmask) {
527 G_free(fs->curmask);
528 }
529
530 if (fs->norms) {
531 G_free(fs->norms);
532 }
533
534 G_free(fs);
535 fs = NULL;
536 }
537
538 return (found);
539 }
540
541 return (-1);
542}
543
544/*!
545 \brief Free unshared buffers of geosurf struct
546
547 <i>fs</i> has already been taken out of the list
548
549 This function is fairly revealing about how shared datasets work
550
551 \param fs pointer to geosurf struct
552 */
554{
555 geosurf *gs;
556 int i, j, same;
557 int old_datah;
558
559 G_debug(5, "gs_free_unshared_buffs");
560
561 /* for each attribute
562 if !same, free buff
563 */
564 for (i = 0; i < MAX_ATTS; i++) {
565 same = 0;
566
567 if (0 < (old_datah = fs->att[i].hdata)) {
568 /* for ea att of all other surfs */
569 for (gs = Surf_top; gs; gs = gs->next) {
570 for (j = 0; j < MAX_ATTS; j++) {
571 if ((old_datah == gs->att[j].hdata) && (fs != gs)) {
572 same = 1;
573 }
574 }
575 }
576
577 if (!same) {
579 }
580 }
581 }
582
583 return;
584}
585
586/*!
587 \brief Get number of reused values
588
589 \param dh value
590
591 \return number of reused values
592 */
594{
595 geosurf *gs;
596 int ref, j;
597
598 G_debug(5, "gs_num_datah_reused");
599
600 /* for each attribute
601 if same, ++reference
602 */
603 /* for ea att of all surfs */
604 ref = 0;
605
606 for (gs = Surf_top; gs; gs = gs->next) {
607 for (j = 0; j < MAX_ATTS; j++) {
608 if (dh == gs->att[j].hdata) {
609 ref++;
610 }
611 }
612 }
613
614 return (ref);
615}
616
617/*!
618 \brief Get attribute type
619
620 \param gs pointer to geosurf struct
621 \param desc attribute id
622
623 \return -1 on error
624 \return attribute type
625 */
627{
628 G_debug(5, "gs_get_att_type");
629
630 if (!LEGAL_ATT(desc)) {
631 return (-1);
632 }
633
634 if (gs) {
635 if (gs->att[desc].att_src != NOTSET_ATT) {
636 return (gs->att[desc].att_type);
637 }
638 }
639
640 return (-1);
641}
642
643/*!
644 \brief Get attribute source
645
646 \param gs pointer to geosurf struct
647 \param desc attribute id (descriptor)
648
649 \return -1 on error
650 \return attribute source id
651 */
652int gs_get_att_src(geosurf *gs, int desc)
653{
654 if (gs)
655 G_debug(5, "gs_get_att_src(): id=%d, desc=%d", gs->gsurf_id, desc);
656 if (!LEGAL_ATT(desc)) {
657 return (-1);
658 }
659
660 if (gs) {
661 return (gs->att[desc].att_src);
662 }
663
664 return (-1);
665}
666
667/*!
668 \brief Get attribute data buffer
669
670 \param gs pointer to geosurf struct
671 \param desc attribute id (descriptor)
672 \param to_write non-zero value for 'write'
673
674 \return NULL on error
675 \return pointer to typbuff
676 */
678{
679 typbuff *tb;
680 geosurf *gsref;
681
682 if (gs) {
683 G_debug(5, "gs_get_att_typbuff(): id=%d desc=%d to_write=%d",
684 gs->gsurf_id, desc, to_write);
685 if ((tb = gsds_get_typbuff(gs->att[desc].hdata, to_write))) {
686 tb->tfunc = NULL;
687
688 if (desc == ATT_TOPO) {
690
691 if (gsref && gsref != gs) {
692 tb->tfunc = gsdiff_do_SD;
693 }
694 }
695
696 return (tb);
697 }
698 }
699
700 return (NULL);
701}
702
703/*!
704 \brief Allocate attribute buffer
705
706 \param gs pointer to geosurf struct
707 \param desc attribute id (descriptor)
708 \param type buffer type (based on raster map type)
709
710 \return -1 on error
711 \return amount of allocated memory
712 */
713size_t gs_malloc_att_buff(geosurf *gs, int desc, int type)
714{
715 int hdata, dims[2], ndims;
716
717 G_debug(5, "gs_malloc_att_buff");
718
719 if (gs) {
720 if (0 < (hdata = gs->att[desc].hdata)) {
721 dims[0] = gs->rows;
722 dims[1] = gs->cols;
723 ndims = 2;
724 gs_set_att_type(gs, desc, type);
725
726 return (gsds_alloc_typbuff(hdata, dims, ndims, type));
727 }
728 }
729
730 return 0;
731}
732
733/*!
734 \brief Allocate attribute lookup
735
736 \param gs pointer to geosurf struct
737 \param desc attribute id
738
739 \return -1 on error
740 \return pointer to typbuff (casted)
741 */
743{
744 int size;
745
746 G_debug(5, "gs_malloc_lookup");
747
748 if (gs) {
749 if (gs->att[desc].lookup) {
750 G_free(gs->att[desc].lookup);
751 gs->att[desc].lookup = NULL;
752 }
753
754 switch (gs->att[desc].att_type) {
755 case (ATTY_SHORT):
756 size = 32768 * sizeof(int);
757
758 /* positive integers only, because use as array index */
759 gs->att[desc].lookup = (int *)G_malloc(size); /* G_fatal_error */
760 if (!gs->att[desc].lookup) {
761 return (-1);
762 }
763
764 break;
765 case (ATTY_CHAR):
766 size = 256 * sizeof(int);
767
768 /* unsigned char */
769 gs->att[desc].lookup = (int *)G_malloc(size);
770 if (!gs->att[desc].lookup) {
771 return (-1);
772 }
773
774 break;
775 default:
776 G_warning("bad type: gs_malloc_lookup");
777 return (-1);
778 }
779
780 if (gs->att[desc].lookup) {
781 return (0);
782 }
783 }
784
785 return (-1);
786}
787
788/*!
789 \brief Set attribute type
790
791 \param gs pointer to geosurf struct
792 \param desc attribute id
793 \param type attribute type
794
795 \return -1 on error
796 \return 0 on success
797 */
798int gs_set_att_type(geosurf *gs, int desc, int type)
799{
800
801 G_debug(5, "gs_set_att_type(): desc=%d, type=%d", desc, type);
802
803 if (gs && LEGAL_TYPE(type)) {
804 gs->att[desc].att_type = type;
805
806 return (0);
807 }
808
809 return (-1);
810}
811
812/*!
813 \brief Set attribute source
814
815 \param gs pointer to geosurf struct
816 \param desc attribute id (descriptor)
817 \param src source id
818
819 \return -1 on error
820 \return 0 on success
821 */
822int gs_set_att_src(geosurf *gs, int desc, int src)
823{
824 if (gs)
825 G_debug(5, "gs_set_att_src(): id=%d desc=%d src=%d", gs->gsurf_id, desc,
826 src);
827
828 /* check if old source was MAP_ATT, free buff */
829 if (MAP_ATT == gs_get_att_src(gs, desc)) {
830 if (1 == gs_num_datah_reused(gs->att[desc].hdata)) {
831 /* only reference */
832 G_debug(5, "gs_set_att_src(): replacing existing map");
833 gsds_free_datah(gs->att[desc].hdata);
834 }
835
836 if (ATT_TOPO == desc) {
837 if (gs->norms) {
838 G_free(gs->norms);
839 }
840
841 gs->norms = NULL;
842 gs->norm_needupdate = 0;
843 }
844 }
845
846 if (gs && LEGAL_SRC(src)) {
847 gs->att[desc].att_src = src;
848
849 return (0);
850 }
851
852 return (-1);
853}
854
855/*!
856 \brief Set attribute constant value
857
858 \todo set typbuf constant
859
860 \param gs pointer to geosurf struct
861 \param desc attribute id
862 \param constant constant value
863
864 \return 0 on success
865 \return -1 on error
866 */
867int gs_set_att_const(geosurf *gs, int desc, float constant)
868{
869
870 if (gs) {
871 G_debug(5, "gs_set_att_const(): id=%d, desc=%d, const=%f", gs->gsurf_id,
872 desc, constant);
873 gs->att[desc].constant = constant;
874
875 if (ATT_MASK == desc) {
876 gs->mask_needupdate = 1;
877 }
878 else {
880 }
881
882 Gs_update_attrange(gs, desc);
883
884 return (0);
885 }
886
887 return (-1);
888}
889
890/*!
891 \brief Set geosurf mask mode
892
893 \param invert invert mask
894 */
895void gs_set_maskmode(int invert)
896{
897 Invertmask = invert;
898
899 return;
900}
901
902/*!
903 \brief Check if mask is defined
904
905 \param gs pointer to geosurf struct
906
907 \return 1 if defined
908 \return 0 not defined
909 */
911{
912 return (gs->att[ATT_MASK].att_src != NOTSET_ATT);
913}
914
915/*!
916 \brief
917
918 Should only be called when setting up the current mask (gs_bm.c)
919
920 \param tb pointer to typbuff
921 \param col number of cols
922 \param row number of rows
923 \param offset offset value
924
925 \return 1
926 \return 0
927 */
928int gs_masked(typbuff *tb, int col, int row, int offset)
929{
930 int ret;
931
932 ret = 1;
933
934 if (tb->bm) {
935 ret = BM_get(tb->bm, col, row);
936 }
937 else if (tb->cb) {
938 ret = tb->cb[offset];
939 }
940 else if (tb->sb) {
941 ret = tb->sb[offset];
942 }
943 else if (tb->ib) {
944 ret = tb->ib[offset];
945 }
946 else if (tb->fb) {
947 ret = tb->fb[offset];
948 }
949
950 return (Invertmask ? ret : !ret);
951}
952
953/*!
954 \brief
955
956 Call this one when you already know att_src is MAP_ATT
957
958 \param cobuff
959 \param coloratt color attribute
960 \param offset offset value
961
962 \return packed color for category at offset
963 */
965{
966 if (coloratt->lookup) {
967 /* for now, but may add larger color lookup capabilities later,
968 so would have to use GET_MAPATT */
969 return (coloratt->lookup[cobuff->cb[offset]]);
970 }
971
972 return (cobuff->ib[offset]);
973}
974
975/*
976 In the following functions, "extents" refers to translated extents for
977 a single surface, while "range" refers to accumulated extents of all
978 loaded surfaces
979 */
980
981/*!
982 \brief Get z-extent values
983
984 \todo pass flag to use zminmasked instead of zmin
985
986 \param gs pointer to geosurf struct
987 \param[out] min z-min value
988 \param[out] max z-max value
989 \param[out] mid z-middle value
990
991 \return 1
992 */
993int gs_get_zextents(geosurf *gs, float *min, float *max, float *mid)
994{
995 *min = gs->zmin + gs->z_trans;
996 *max = gs->zmax + gs->z_trans;
997 *mid = (*max + *min) / 2.;
998
999 return (1);
1000}
1001
1002/*!
1003 \brief Get x-extent values
1004
1005 \param gs pointer to geosurf struct
1006 \param[out] min x-min value
1007 \param[out] max x-max value
1008
1009 \return 1
1010 */
1011int gs_get_xextents(geosurf *gs, float *min, float *max)
1012{
1013 *min = gs->xmin + gs->x_trans;
1014 *max = gs->xmax + gs->x_trans;
1015
1016 return (1);
1017}
1018
1019/*!
1020 \brief Get y-extent values
1021
1022 \param gs pointer to geosurf struct
1023 \param[out] min y-min value
1024 \param[out] max y-max value
1025
1026 \return 1
1027 */
1028int gs_get_yextents(geosurf *gs, float *min, float *max)
1029{
1030 *min = gs->ymin + gs->y_trans;
1031 *max = gs->ymax + gs->y_trans;
1032
1033 return (1);
1034}
1035
1036/*!
1037 \brief Get z-range
1038
1039 \todo pass flag to use zminmasked instead of zmin
1040 could also have this return a weighted average for vertical "centroid"
1041
1042 \param[out] min z-min value
1043 \param[out] max z-max value
1044
1045 \return -1 on error (no surface)
1046 \return 1 on success
1047 */
1048int gs_get_zrange0(float *min, float *max)
1049{
1050 geosurf *gs;
1051
1052 if (Surf_top) {
1053 *min = Surf_top->zmin;
1054 *max = Surf_top->zmax;
1055 }
1056 else {
1057 return (-1);
1058 }
1059
1060 for (gs = Surf_top->next; gs; gs = gs->next) {
1061 if (gs->zmin < *min) {
1062 *min = gs->zmin;
1063 }
1064
1065 if (gs->zmax > *max) {
1066 *max = gs->zmax;
1067 }
1068 }
1069
1070 return (1);
1071}
1072
1073/*!
1074 \brief Get z-range
1075
1076 \param[out] min z-min value
1077 \param[out] max z-max value
1078
1079 \return -1 on error (no surface)
1080 \return 1 on success
1081 */
1082int gs_get_zrange(float *min, float *max)
1083{
1084 geosurf *gs;
1085 float tmin, tmax, tmid;
1086
1087 if (Surf_top) {
1088 gs_get_zextents(Surf_top, &tmin, &tmax, &tmid);
1089 *min = tmin;
1090 *max = tmax;
1091 }
1092 else {
1093 return (-1);
1094 }
1095
1096 for (gs = Surf_top->next; gs; gs = gs->next) {
1098
1099 if (tmin < *min) {
1100 *min = tmin;
1101 }
1102
1103 if (tmax > *max) {
1104 *max = tmax;
1105 }
1106 }
1107
1108 return (1);
1109}
1110
1111/*!
1112 \brief Get x-range
1113
1114 \param[out] min x-min value
1115 \param[out] max x-max value
1116
1117 \return -1 on error (no surface)
1118 \return 1 on success
1119 */
1120int gs_get_xrange(float *min, float *max)
1121{
1122 geosurf *gs;
1123 float tmin, tmax;
1124
1125 if (Surf_top) {
1126 gs_get_xextents(Surf_top, &tmin, &tmax);
1127 *min = tmin;
1128 *max = tmax;
1129 }
1130 else {
1131 return (-1);
1132 }
1133
1134 for (gs = Surf_top->next; gs; gs = gs->next) {
1136
1137 if (tmin < *min) {
1138 *min = tmin;
1139 }
1140
1141 if (tmax > *max) {
1142 *max = tmax;
1143 }
1144 }
1145
1146 return (1);
1147}
1148
1149/*!
1150 \brief Get y-range
1151
1152 \param[out] min y-min value
1153 \param[out] max y-max value
1154
1155 \return -1 on error (no surface)
1156 \return 1 on success
1157 */
1158int gs_get_yrange(float *min, float *max)
1159{
1160 geosurf *gs;
1161 float tmin, tmax;
1162
1163 if (Surf_top) {
1164 gs_get_yextents(Surf_top, &tmin, &tmax);
1165 *min = tmin;
1166 *max = tmax;
1167 }
1168 else {
1169 return (-1);
1170 }
1171
1172 for (gs = Surf_top->next; gs; gs = gs->next) {
1174
1175 if (tmin < *min) {
1176 *min = tmin;
1177 }
1178
1179 if (tmax > *max) {
1180 *max = tmax;
1181 }
1182 }
1183
1184 return (1);
1185}
1186
1187/*!
1188 \brief Get average z-max value
1189
1190 Useful for setting position of cplane, lighting ball, etc.
1191
1192 \param[out] azmax average z-max value
1193
1194 \return -1 on error
1195 \return 1 on success
1196 */
1198{
1199 float zmax;
1200 int i;
1201 geosurf *gs;
1202
1203 zmax = *azmax = 0.0;
1204
1205 if (Surf_top) {
1206 for (i = 0, gs = Surf_top; gs; i++, gs = gs->next) {
1207 zmax += (gs->zmax + gs->z_trans);
1208 }
1209
1210 *azmax = zmax / i;
1211
1212 return (1);
1213 }
1214
1215 return (-1);
1216}
1217
1218/*!
1219 \brief Get data center point
1220
1221 \param[out] cen center (array X,Y,Z)
1222
1223 \return -1 on error
1224 \return 1 on success
1225 */
1227{
1228 float zmin, zmax, ymin, ymax, xmin, xmax;
1229 geosurf *gs;
1230
1231 if (Surf_top) {
1232 zmin = Surf_top->zmin;
1233 zmax = Surf_top->zmax;
1234 ymin = Surf_top->ymin;
1235 ymax = Surf_top->ymax;
1236 xmin = Surf_top->xmin;
1237 xmax = Surf_top->xmax;
1238
1239 for (gs = Surf_top->next; gs; gs = gs->next) {
1240 if (gs->zmin < zmin) {
1241 zmin = gs->zmin;
1242 }
1243
1244 if (gs->zmax > zmax) {
1245 zmax = gs->zmax;
1246 }
1247
1248 if (gs->ymin < ymin) {
1249 ymin = gs->ymin;
1250 }
1251
1252 if (gs->ymax > ymax) {
1253 ymax = gs->ymax;
1254 }
1255
1256 if (gs->xmin < xmin) {
1257 xmin = gs->xmin;
1258 }
1259
1260 if (gs->xmax > xmax) {
1261 xmax = gs->xmax;
1262 }
1263 }
1264
1265 cen[X] = (xmin + xmax) / 2. - xmin;
1266 cen[Y] = (ymin + ymax) / 2. - ymin;
1267 cen[Z] = (zmin + zmax) / 2.;
1268
1269 return (1);
1270 }
1271
1272 cen[X] = cen[Y] = cen[Z] = 0.0;
1273
1274 return (-1);
1275}
1276
1277/*!
1278 \brief Set for geosurf need-to-update mark
1279
1280 \return -1 no surface available
1281 \return 1 on success
1282 */
1284{
1285 geosurf *gs;
1286
1287 if (Surf_top) {
1288 Surf_top->norm_needupdate = 1;
1289 }
1290 else {
1291 return (-1);
1292 }
1293
1294 for (gs = Surf_top->next; gs; gs = gs->next) {
1295 gs->norm_needupdate = 1;
1296 }
1297
1298 return (1);
1299}
1300
1301/*!
1302 \brief Check if point is masked
1303
1304 \param gs pointer to geosurf struct
1305 \param[in] pt point coordinates (X,Y,Z)
1306
1307 \return 1 masked
1308 \return 0 not masked
1309 */
1311{
1312 int vrow, vcol, drow, dcol;
1313 int retmask = 0, npts = 0;
1314 float p2[2];
1315
1316 if (!gs->curmask) {
1317 return (0);
1318 }
1319
1320 vrow = Y2VROW(gs, pt[Y]);
1321 vcol = X2VCOL(gs, pt[X]);
1322
1323 /* check right & bottom edges */
1324 if (pt[X] == VCOL2X(gs, VCOLS(gs))) {
1325 /* right edge */
1326 vcol -= 1;
1327 }
1328
1329 if (pt[Y] == VROW2Y(gs, VROWS(gs))) {
1330 /* bottom edge */
1331 vrow -= 1;
1332 }
1333
1334 drow = VROW2DROW(gs, vrow);
1335 dcol = VCOL2DCOL(gs, vcol);
1336
1337 if (BM_get(gs->curmask, dcol, drow)) {
1338 retmask |= MASK_TL;
1339 npts++;
1340 }
1341
1342 dcol = VCOL2DCOL(gs, vcol + 1);
1343
1344 if (BM_get(gs->curmask, dcol, drow)) {
1345 retmask |= MASK_TR;
1346 npts++;
1347 }
1348
1349 drow = VROW2DROW(gs, vrow + 1);
1350
1351 if (BM_get(gs->curmask, dcol, drow)) {
1352 retmask |= MASK_BR;
1353 npts++;
1354 }
1355
1356 dcol = VCOL2DCOL(gs, vcol);
1357
1358 if (BM_get(gs->curmask, dcol, drow)) {
1359 retmask |= MASK_BL;
1360 npts++;
1361 }
1362
1363 if (npts != 1) {
1364 /* zero or masked */
1365 return (retmask | npts);
1366 }
1367
1368 p2[X] = VCOL2X(gs, vcol);
1369 p2[Y] = VROW2Y(gs, vrow + 1);
1370
1371 switch (retmask) {
1372 case MASK_TL:
1373 if ((pt[X] - p2[X]) / VXRES(gs) > (pt[Y] - p2[Y]) / VYRES(gs)) {
1374 /* lower triangle */
1375 return (0);
1376 }
1377
1378 return (retmask | npts);
1379 case MASK_TR:
1380
1381 return (retmask | npts);
1382 case MASK_BR:
1383 if ((pt[X] - p2[X]) / VXRES(gs) <= (pt[Y] - p2[Y]) / VYRES(gs)) {
1384 /* upper triangle */
1385 return (0);
1386 }
1387
1388 return (retmask | npts);
1389 case MASK_BL:
1390
1391 return (retmask | npts);
1392 }
1393
1394 /* Assume that if we get here it is an error */
1395 return (0);
1396}
1397
1398/*!
1399 \brief Calculate distance on surface
1400
1401 \param gs pointer to geosurf struct
1402 \param p1 from point
1403 \param p2 to point
1404 \param[out] dist distance
1405 \param use_exag use exag for calculation
1406
1407 \return 0 on error (points not in region)
1408 \return 1 on success
1409 */
1410int gs_distance_onsurf(geosurf *gs, float *p1, float *p2, float *dist,
1411 int use_exag)
1412{
1413 Point3 *tmp;
1414 int np, i;
1415 float exag, length;
1416
1417 if (in_vregion(gs, p1) && in_vregion(gs, p2)) {
1418 if (NULL == (tmp = gsdrape_get_segments(gs, p1, p2, &np))) {
1419 return (0);
1420 }
1421
1422 length = 0.;
1423
1424 if (use_exag) {
1425 exag = GS_global_exag();
1426 tmp[0][Z] *= exag;
1427
1428 for (i = 0; i < (np - 1); i++) {
1429 tmp[i + 1][Z] *= exag;
1430 length += GS_distance(tmp[i], tmp[i + 1]);
1431 }
1432 }
1433 else {
1434 for (i = 0; i < (np - 1); i++) {
1435 length += GS_distance(tmp[i], tmp[i + 1]);
1436 }
1437 }
1438
1439 *dist = length;
1440
1441 return (1);
1442 }
1443
1444 return (0);
1445}
#define NULL
Definition ccmath.h:32
int BM_get(struct BM *, int, int)
Gets 'val' from the bitmap.
Definition bitmap.c:213
void G_free(void *)
Free allocated memory.
Definition gis/alloc.c:145
void G_warning(const char *,...) __attribute__((format(printf
#define G_malloc(n)
Definition defs/gis.h:136
int G_debug(int, const char *,...) __attribute__((format(printf
int gsds_free_datah(int)
Free allocated dataset.
Definition gsds.c:325
int Gs_update_attrange(geosurf *, int)
Update no_zero ranges for attribute (actually no_null now)
Definition gs3.c:1080
size_t gsds_alloc_typbuff(int, int *, int, int)
Allocates correct buffer according to type, keeps track of total mem.
Definition gsds.c:476
int in_vregion(geosurf *, float *)
ADD.
Definition gsdrape.c:694
Point3 * gsdrape_get_segments(geosurf *, float *, float *, int *)
ADD.
Definition gsdrape.c:346
float gsdiff_do_SD(float, int)
ADD.
Definition gsdiff.c:90
typbuff * gsds_get_typbuff(int, IFLAG)
float GS_distance(float *, float *)
Calculate distance.
Definition gs_util.c:137
geosurf * gsdiff_get_SDref(void)
ADD.
Definition gsdiff.c:73
float GS_global_exag(void)
Get global z-exag value.
Definition gs2.c:1996
#define min(x, y)
Definition draw2.c:29
#define max(x, y)
Definition draw2.c:30
int gs_get_xextents(geosurf *gs, float *min, float *max)
Get x-extent values.
Definition gs.c:1011
int gs_masked(typbuff *tb, int col, int row, int offset)
Should only be called when setting up the current mask (gs_bm.c)
Definition gs.c:928
void print_view_fields(geoview *gv)
Debugging, print geoview fields to stderr.
Definition gs.c:415
int gs_get_datacenter(float *cen)
Get data center point.
Definition gs.c:1226
int gs_get_zextents(geosurf *gs, float *min, float *max, float *mid)
Get z-extent values.
Definition gs.c:993
int gs_get_zrange(float *min, float *max)
Get z-range.
Definition gs.c:1082
size_t gs_malloc_att_buff(geosurf *gs, int desc, int type)
Allocate attribute buffer.
Definition gs.c:713
int gs_set_att_src(geosurf *gs, int desc, int src)
Set attribute source.
Definition gs.c:822
int gs_get_yextents(geosurf *gs, float *min, float *max)
Get y-extent values.
Definition gs.c:1028
int gs_mapcolor(typbuff *cobuff, gsurf_att *coloratt, int offset)
Call this one when you already know att_src is MAP_ATT.
Definition gs.c:964
void gs_free_unshared_buffs(geosurf *fs)
Free unshared buffers of geosurf struct.
Definition gs.c:553
void gs_err(const char *msg)
Definition gs.c:31
int gs_get_xrange(float *min, float *max)
Get x-range.
Definition gs.c:1120
int gs_att_is_set(geosurf *surf, unsigned int att)
Check if attribute is set.
Definition gs.c:146
geosurf * gs_get_surf(int id)
Get geosurf struct.
Definition gs.c:59
geosurf * gs_get_last_surface(void)
Get last allocated geosurf struct from list.
Definition gs.c:169
int gs_set_att_const(geosurf *gs, int desc, float constant)
Set attribute constant value.
Definition gs.c:867
int gs_malloc_lookup(geosurf *gs, int desc)
Allocate attribute lookup.
Definition gs.c:742
int gs_get_yrange(float *min, float *max)
Get y-range.
Definition gs.c:1158
void gs_delete_surf(int id)
Remove geosurf struct from list.
Definition gs.c:459
int gs_set_att_type(geosurf *gs, int desc, int type)
Set attribute type.
Definition gs.c:798
void print_surf_fields(geosurf *s)
Debugging, print geosurf fields to stderr.
Definition gs.c:389
int gs_getall_surfaces(geosurf **gsurfs)
Get array of geosurf structs.
Definition gs.c:105
int gs_setall_norm_needupdate(void)
Set for geosurf need-to-update mark.
Definition gs.c:1283
void print_256lookup(int *buff)
Debugging, 256 integer values from buffer.
Definition gs.c:365
int gs_init_surf(geosurf *gs, double ox, double oy, int rows, int cols, double xres, double yres)
Initialize allocated geosurf struct.
Definition gs.c:230
#define FIRST_SURF_ID
Definition gs.c:25
void gs_init(void)
Initialize library.
Definition gs.c:44
void gs_set_maskmode(int invert)
Set geosurf mask mode.
Definition gs.c:895
geosurf * gs_get_new_surface(void)
Allocate new geosurf struct.
Definition gs.c:190
int gs_free_surf(geosurf *fs)
Free geosurf struct.
Definition gs.c:483
int gs_get_att_type(geosurf *gs, int desc)
Get attribute type.
Definition gs.c:626
int gs_distance_onsurf(geosurf *gs, float *p1, float *p2, float *dist, int use_exag)
Calculate distance on surface.
Definition gs.c:1410
geosurf * gs_get_prev_surface(int id)
Get previous geosurf struct.
Definition gs.c:83
int gs_num_surfaces(void)
Get number of surfaces.
Definition gs.c:124
int gs_init_normbuff(geosurf *gs)
Init geosurf normbuff.
Definition gs.c:304
typbuff * gs_get_att_typbuff(geosurf *gs, int desc, int to_write)
Get attribute data buffer.
Definition gs.c:677
int gs_num_datah_reused(int dh)
Get number of reused values.
Definition gs.c:593
void print_frto(float(*ft)[4])
Debugging, print 'from/to' model coordinates to stderr.
Definition gs.c:335
int gs_mask_defined(geosurf *gs)
Check if mask is defined.
Definition gs.c:910
int gs_get_zrange0(float *min, float *max)
Get z-range.
Definition gs.c:1048
int gs_point_is_masked(geosurf *gs, float *pt)
Check if point is masked.
Definition gs.c:1310
int gs_get_data_avg_zmax(float *azmax)
Get average z-max value.
Definition gs.c:1197
int gs_get_att_src(geosurf *gs, int desc)
Get attribute source.
Definition gs.c:652
void gs_set_defaults(geosurf *gs, float *defs, float *null_defs)
Set default attribute values.
Definition gs.c:437
void print_realto(float *rt)
Debugging, print 'to' real coordinates to stderr.
Definition gs.c:351
OGSF header file (structures)
#define NOTSET_ATT
Definition ogsf.h:85
#define ATT_MASK
Definition ogsf.h:78
#define ATTY_SHORT
Definition ogsf.h:171
#define X
Definition ogsf.h:141
#define MAX_ATTS
Definition ogsf.h:46
#define MASK_TR
Definition ogsf.h:192
#define ATT_TOPO
Definition ogsf.h:76
float Point3[3]
Definition ogsf.h:206
#define Z
Definition ogsf.h:143
#define MASK_BL
Definition ogsf.h:194
#define IFLAG
Definition ogsf.h:72
#define LEGAL_ATT(a)
Definition ogsf.h:82
#define Y
Definition ogsf.h:142
#define MAP_ATT
Definition ogsf.h:86
#define MASK_BR
Definition ogsf.h:193
#define MASK_TL
Definition ogsf.h:191
#define ATTY_INT
Definition ogsf.h:170
#define ATTY_CHAR
Definition ogsf.h:172
#define FROM
Definition ogsf.h:145
#define LEGAL_SRC(s)
Definition ogsf.h:89
#define DM_GOURAUD
Definition ogsf.h:57
#define CONST_ATT
Definition ogsf.h:87
#define LEGAL_TYPE(t)
Definition ogsf.h:174
#define TO
Definition ogsf.h:146
struct ps_state ps
#define VYRES(gs)
Definition rowcol.h:10
#define Y2VROW(gs, py)
Definition rowcol.h:27
#define VXRES(gs)
Definition rowcol.h:9
#define VCOL2X(gs, vcol)
Definition rowcol.h:40
#define VCOLS(gs)
Definition rowcol.h:14
#define VROWS(gs)
Definition rowcol.h:13
#define VROW2Y(gs, vrow)
Definition rowcol.h:39
#define VROW2DROW(gs, vrow)
Definition rowcol.h:31
#define X2VCOL(gs, px)
Definition rowcol.h:28
#define VCOL2DCOL(gs, vcol)
Definition rowcol.h:32
Definition ogsf.h:267
float x_trans
Definition ogsf.h:284
float ymax
Definition ogsf.h:285
int rows
Definition ogsf.h:269
float ymin
Definition ogsf.h:285
double yres
Definition ogsf.h:282
float xmax
Definition ogsf.h:285
int cols
Definition ogsf.h:269
double ox
real world origin (i.e., SW corner)
Definition ogsf.h:281
unsigned int draw_mode
DM_GOURAUD | DM_FRINGE | DM_POLY, DM_WIRE, DM_WIRE_POLY.
Definition ogsf.h:275
long wire_color
0xBBGGRR or WC_COLOR_ATT
Definition ogsf.h:278
float xmin
Definition ogsf.h:285
int gsurf_id
Definition ogsf.h:268
int y_mod
Definition ogsf.h:289
int x_modw
Definition ogsf.h:289
int y_modw
Definition ogsf.h:289
double xres
Definition ogsf.h:282
int x_mod
cells per viewcell, per wire viewcell
Definition ogsf.h:289
struct g_surf * next
Definition ogsf.h:296
double oy
Definition ogsf.h:281
float z_exag
Definition ogsf.h:283
float z_trans
Definition ogsf.h:284
float zmin
Definition ogsf.h:285
float zmax
Definition ogsf.h:285
float y_trans
Definition ogsf.h:284