GRASS 8 Programmer's Manual 8.6.0dev(2026)-55de52a352
Loading...
Searching...
No Matches
gs3.c
Go to the documentation of this file.
1/*!
2 \file lib/ogsf/gs3.c
3
4 \brief OGSF library - loading surfaces (lower level functions)
5
6 GRASS OpenGL gsurf OGSF Library
7
8 SPDX-FileCopyrightText: 1999-2008 GRASS Development Team
9 SPDX-License-Identifier: GPL-2.0-or-later
10
11 \author Bill Brown USACERL, GMSL/University of Illinois (January 1993)
12 \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
13 */
14
15#include <stdlib.h>
16#include <string.h>
17
18#include <grass/gis.h>
19#include <grass/raster.h>
20#include <grass/glocale.h>
21#include <grass/bitmap.h>
22
23#include <grass/ogsf.h>
24/* for geoview & geodisplay in 3dview stuff */
25#include "gsget.h"
26/* for update_attrange - might be able to move this func now */
27
28/*!
29 \brief Used in the function Gs_update_attrange()
30 */
31#define INIT_MINMAX(p, nm, size, min, max, found) \
32 found = 0; \
33 p += (size - 1); \
34 while (size--) { \
35 if (!BM_GET_BYOFFSET(nm, size)) { \
36 min = max = *p; \
37 found = 1; \
38 break; \
39 } \
40 p--; \
41 }
42
43/*!
44 \brief Used in the function Gs_update_attrange()
45 */
46#define SET_MINMAX(p, nm, size, min, max) \
47 p += (size - 1); \
48 while (size--) { \
49 if (!BM_GET_BYOFFSET(nm, size)) { \
50 if (*p < min) { \
51 min = *p; \
52 } \
53 else if (*p > max) { \
54 max = *p; \
55 } \
56 } \
57 p--; \
58 }
59
60typedef int FILEDESC;
61
62#define NO_DATA_COL 0xffffff
63
64/*!
65 \brief Calculates distance in METERS between two points in current projection
66 (2D)
67
68 Uses G_distance().
69
70 \param[in] from 'from' point (X, Y)
71 \param[in] to 'to' point (X, Y)
72
73 \return distance
74 */
75double Gs_distance(double *from, double *to)
76{
77 static int first = 1;
78
79 if (first) {
80 first = 0;
82 }
83
84 return G_distance(from[0], from[1], to[0], to[1]);
85}
86
87/*!
88 \brief Load raster map as floating point map
89
90 Calling function must have already allocated space in buff for
91 wind->rows * wind->cols floats.
92
93 This routine simply loads the map into a 2d array by repetitve calls
94 to get_f_raster_row.
95
96 \param wind current window
97 \param map_name raster map name
98 \param[out] buff data buffer
99 \param[out] nullmap null map buffer
100 \param[out] has_null indicates if raster map contains null-data
101
102 \return 1 on success
103 \return 0 on failure
104 */
105int Gs_loadmap_as_float(struct Cell_head *wind, const char *map_name,
106 float *buff, struct BM *nullmap, int *has_null)
107{
109 const char *map_set;
110 int offset, row, col;
111
112 G_debug(3, "Gs_loadmap_as_float(): name=%s", map_name);
113
114 map_set = G_find_raster2(map_name, "");
115 if (!map_set) {
116 G_warning(_("Raster map <%s> not found"), map_name);
117 return 0;
118 }
119 *has_null = 0;
120
121 cellfile = Rast_open_old(map_name, map_set);
122 char *mname = G_fully_qualified_name(map_name, map_set);
123
124 G_message(_("Loading raster map <%s>..."), mname);
125
126 for (row = 0; row < wind->rows; row++) {
127 offset = row * wind->cols;
128 Rast_get_f_row(cellfile, &(buff[offset]), row);
129
130 G_percent(row, wind->rows, 2);
131
132 for (col = 0; col < wind->cols; col++) {
133 if (Rast_is_f_null_value(buff + offset + col)) {
134 *has_null = 1;
135 BM_set(nullmap, col, row, 1);
136 }
137 /* set nm */
138 }
139 }
140 G_percent(1, 1, 1);
141
142 G_debug(4, " has_null=%d", *has_null);
143 G_free(mname);
144
146
147 return (1);
148}
149
150/*!
151 \brief Load raster map as integer map
152
153 Calling function must have already allocated space in buff for
154 wind->rows * wind->cols floats.
155
156 This routine simply loads the map into a 2d array by repetitve calls
157 to get_f_raster_row.
158
159 \todo fn body of Gs_loadmap_as_float()
160
161 \param wind current window
162 \param map_name raster map name
163 \param[out] buff data buffer
164 \param[out] nullmap null map buffer
165 \param[out] has_null indicates if raster map contains null-data
166
167 \return 1 on success
168 \return 0 on failure
169 */
170int Gs_loadmap_as_int(struct Cell_head *wind, const char *map_name, int *buff,
171 struct BM *nullmap, int *has_null)
172{
174 const char *map_set;
175 int offset, row, col;
176
177 G_debug(3, "Gs_loadmap_as_int");
178
179 map_set = G_find_raster2(map_name, "");
180 if (!map_set) {
181 G_warning(_("Raster map <%s> not found"), map_name);
182 return 0;
183 }
184 *has_null = 0;
185
186 cellfile = Rast_open_old(map_name, map_set);
187 char *mname = G_fully_qualified_name(map_name, map_set);
188
189 G_message(_("Loading raster map <%s>..."), mname);
190
191 for (row = 0; row < wind->rows; row++) {
192 offset = row * wind->cols;
193 Rast_get_c_row(cellfile, &(buff[offset]), row);
194
195 G_percent(row, wind->rows, 2);
196
197 for (col = 0; col < wind->cols; col++) {
198 if (Rast_is_f_null_value(buff + offset + col)) {
199 *has_null = 1;
200 BM_set(nullmap, col, row, 1);
201 }
202
203 /* set nm */
204 }
205 }
206 G_percent(1, 1, 1);
207
209 G_free(mname);
210
211 return (1);
212}
213
214/*!
215 \brief Get map data type
216
217 \param filename raster map name
218 \param negflag
219
220 \return -1 if map is integer and Rast_read_range() fails
221 \return data type (ARRY_*)
222 */
223int Gs_numtype(const char *filename, int *negflag)
224{
225 CELL max = 0, min = 0;
226 struct Range range;
227 const char *mapset;
229 static int max_short, max_char;
230 static int first = 1;
231
232 if (first) {
233 max_short = max_char = 1;
234 shortbits = 8 * sizeof(short);
235
236 for (bitplace = 1; bitplace < shortbits; ++bitplace) {
237 /*1 bit for sign */
238 max_short *= 2;
239 }
240
241 max_short -= 1;
242
243 /* NO bits for sign, using unsigned char */
244 charbits = 8 * sizeof(unsigned char);
245
246 for (bitplace = 0; bitplace < charbits; ++bitplace) {
247 max_char *= 2;
248 }
249
250 max_char -= 1;
251
252 first = 0;
253 }
254
255 mapset = G_find_raster2(filename, "");
256 if (!mapset) {
257 G_warning(_("Raster map <%s> not found"), filename);
258 return -1;
259 }
260
261 if (Rast_map_is_fp(filename, mapset)) {
262 G_debug(3, "Gs_numtype(): fp map detected");
263
264 return (ATTY_FLOAT);
265 }
266
267 if (-1 == Rast_read_range(filename, mapset, &range)) {
268 return (-1);
269 }
270
271 Rast_get_range_min_max(&range, &min, &max);
272 *negflag = (min < 0);
273
275 return (ATTY_CHAR);
276 }
277
279 return (ATTY_SHORT);
280 }
281
282 return (ATTY_INT);
283}
284
285/*!
286 \brief Load raster map as integer map
287
288 Calling function must have already allocated space in buff for
289 wind->rows * wind->cols shorts.
290
291 This routine simply loads the map into a 2d array by repetitve calls
292 to get_map_row.
293
294 \param wind current window
295 \param map_name raster map name
296 \param[out] buff data buffer
297 \param[out] nullmap null map buffer
298 \param[out] has_null indicates if raster map contains null-data
299
300 \return 1 on success
301 \return -1 on failure,
302 \return -2 if read ok, but 1 or more values were too large (small)
303 to fit into a short (in which case the max (min) short is used)
304 */
305int Gs_loadmap_as_short(struct Cell_head *wind, const char *map_name,
306 short *buff, struct BM *nullmap, int *has_null)
307{
309 const char *map_set;
310 int *ti, *tmp_buf;
311 int offset, row, col, val, max_short, overflow, shortsize, bitplace;
312 short *ts;
313
314 G_debug(3, "Gs_loadmap_as_short");
315
316 overflow = 0;
317 shortsize = 8 * sizeof(short);
318
319 /* 1 bit for sign */
320 /* same as 2 << (shortsize-1) */
321 for (max_short = bitplace = 1; bitplace < shortsize; ++bitplace) {
322 max_short *= 2;
323 }
324
325 max_short -= 1;
326
327 map_set = G_find_raster2(map_name, "");
328 if (!map_set) {
329 G_warning(_("Raster map <%s> not found"), map_name);
330 return -1;
331 }
332 *has_null = 0;
333
334 cellfile = Rast_open_old(map_name, map_set);
335
336 tmp_buf = (int *)G_malloc(wind->cols * sizeof(int)); /* G_fatal_error */
337 if (!tmp_buf) {
338 return -1;
339 }
340
341 char *mname = G_fully_qualified_name(map_name, map_set);
342 G_message(_("Loading raster map <%s>..."), mname);
343
344 for (row = 0; row < wind->rows; row++) {
345 offset = row * wind->cols;
347
348 G_percent(row, wind->rows, 2);
349
350 ts = &(buff[offset]);
351 ti = tmp_buf;
352
353 for (col = 0; col < wind->cols; col++) {
355 *has_null = 1;
356 BM_set(nullmap, col, row, 1);
357 }
358 else {
359 val = *ti;
360 if (abs(val) > max_short) {
361 overflow = 1;
362 /* assign floor/ceiling value?
363 */
364 *ts = (short)(max_short * val / abs(val));
365 }
366 else {
367 *ts = (short)val;
368 }
369 }
370
371 ti++;
372 ts++;
373 }
374 }
375 G_percent(1, 1, 1);
376
378
380 G_free(mname);
381
382 return (overflow ? -2 : 1);
383}
384
385/*!
386 \brief Load raster map as integer map
387
388 Calling function must have already allocated space in buff for
389 wind->rows * wind->cols unsigned chars.
390
391 This routine simply loads the map into a 2d array by repetitve calls
392 to get_map_row.
393
394 Since signs of chars can be tricky, we only load positive chars
395 between 0-255.
396
397 \todo fn body Gs_loadmap_as_float()
398
399 \param wind current window
400 \param map_name raster map name
401 \param[out] buff data buffer
402 \param[out] nullmap null map buffer
403 \param[out] has_null indicates if raster map contains null-data
404
405 \return 1 on success
406 \return -1 on failure
407 \return -2 if read ok, but 1 or more values
408 were too large (small) to fit into an unsigned char.
409 (in which case the max (min) char is used)
410 */
411int Gs_loadmap_as_char(struct Cell_head *wind, const char *map_name,
412 unsigned char *buff, struct BM *nullmap, int *has_null)
413{
415 const char *map_set;
416 int *ti, *tmp_buf;
417 int offset, row, col, val, max_char, overflow, charsize, bitplace;
418 unsigned char *tc;
419
420 G_debug(3, "Gs_loadmap_as_char");
421
422 overflow = 0;
423 charsize = 8 * sizeof(unsigned char);
424
425 /* 0 bits for sign! */
426 max_char = 1;
427
428 for (bitplace = 0; bitplace < charsize; ++bitplace) {
429 max_char *= 2;
430 }
431
432 max_char -= 1;
433
434 map_set = G_find_raster2(map_name, "");
435 if (!map_set) {
436 G_warning(_("Raster map <%s> not found"), map_name);
437 return -1;
438 }
439 *has_null = 0;
440
441 cellfile = Rast_open_old(map_name, map_set);
442
443 tmp_buf = (int *)G_malloc(wind->cols * sizeof(int)); /* G_fatal_error */
444 if (!tmp_buf) {
445 return -1;
446 }
447
448 char *mname = G_fully_qualified_name(map_name, map_set);
449 G_message(_("Loading raster map <%s>..."), mname);
450
451 for (row = 0; row < wind->rows; row++) {
452 offset = row * wind->cols;
454 tc = (unsigned char *)&(buff[offset]);
455 ti = tmp_buf;
456
457 G_percent(row, wind->rows, 2);
458
459 for (col = 0; col < wind->cols; col++) {
461 *has_null = 1;
462 BM_set(nullmap, col, row, 1);
463 }
464 else {
465 val = *ti;
466 if (val > max_char) {
467 overflow = 1;
468 *tc = (unsigned char)max_char;
469 }
470 else if (val < 0) {
471 overflow = 1;
472 *tc = 0;
473 }
474 else {
475 *tc = (unsigned char)val;
476 }
477 }
478
479 ti++;
480 tc++;
481 }
482 }
483 G_percent(1, 1, 1);
484
486
488 G_free(mname);
489
490 return (overflow ? -2 : 1);
491}
492
493/*!
494 \brief Load raster map as integer map
495
496 Calling function must have already allocated space in buff for
497 struct BM of wind->rows & wind->cols.
498
499 This routine simply loads the map into the bitmap by repetitve calls
500 to get_map_row. Any value other than 0 in the map will set the bitmap.
501 (may want to change later to allow specific value to set)
502
503 Changed to use null.
504
505 \param wind current window
506 \param map_name raster map name
507 \param[out] buff data buffer
508
509 \returns 1 on success
510 \return -1 on failure
511 */
512int Gs_loadmap_as_bitmap(struct Cell_head *wind, const char *map_name,
513 struct BM *buff)
514{
516 const char *map_set;
517 int *tmp_buf;
518 int row, col;
519
520 G_debug(3, "Gs_loadmap_as_bitmap");
521
522 map_set = G_find_raster2(map_name, "");
523 if (!map_set) {
524 G_warning(_("Raster map <%s> not found"), map_name);
525 return -1;
526 }
527
528 cellfile = Rast_open_old(map_name, map_set);
529
530 tmp_buf = (int *)G_malloc(wind->cols * sizeof(int)); /* G_fatal_error */
531 if (!tmp_buf) {
532 return -1;
533 }
534
535 char *mname = G_fully_qualified_name(map_name, map_set);
536 G_message(_("Loading raster map <%s>..."), mname);
537
538 for (row = 0; row < wind->rows; row++) {
540
541 for (col = 0; col < wind->cols; col++) {
543 /* no data */
544 BM_set(buff, col, row, 1);
545 }
546 else {
547 BM_set(buff, col, row, 0);
548 }
549 }
550 }
551
553
555 G_free(mname);
556
557 return (1);
558}
559
560/*!
561 \brief Build color table (256)
562
563 Calling function must have already allocated space in buff for range of
564 data (256 for now) - simply calls get_color for each cat in color range
565
566 \param filename raster map name
567 \param[out] buff data buffer
568
569 \return 1 on success
570 \return 0 on failure
571 */
572int Gs_build_256lookup(const char *filename, int *buff)
573{
574 const char *mapset;
575 struct Colors colrules;
576 CELL min, max, cats[256];
577 int i;
578 unsigned char r[256], g[256], b[256], set[256];
579
580 G_debug(3, "building color table");
581
582 mapset = G_find_raster2(filename, "");
583 if (!mapset) {
584 G_warning(_("Raster map <%s> not found"), filename);
585 return 0;
586 }
587
588 Rast_read_colors(filename, mapset, &colrules);
590
591 if (min < 0 || max > 255) {
592 G_warning(
593 _("Color table range doesn't match data (mincol=%d, maxcol=%d"),
594 min, max);
595
596 min = min < 0 ? 0 : min;
597 max = max > 255 ? 255 : max;
598 }
599
600 G_zero(cats, 256 * sizeof(CELL));
601
602 for (i = min; i <= max; i++) {
603 cats[i] = i;
604 }
605
606 Rast_lookup_c_colors(cats, r, g, b, set, 256, &colrules);
607
608 for (i = 0; i < 256; i++) {
609
610 if (set[i]) {
611 buff[i] =
612 (r[i] & 0xff) | ((g[i] & 0xff) << 8) | ((b[i] & 0xff) << 16);
613 }
614 else {
615 buff[i] = NO_DATA_COL;
616 }
617 }
618
619 return (1);
620}
621
622/*!
623 \brief Pack color table
624
625 Passed an array of 32 bit ints that is converted from cell values
626 to packed colors (0xbbggrr)
627
628 \param filename raster map name
629 \param buff
630 \param rows number of rows
631 \param cols number of cols
632 */
633void Gs_pack_colors(const char *filename, int *buff, int rows, int cols)
634{
635 const char *mapset;
636 struct Colors colrules;
637 unsigned char *r, *g, *b, *set;
638 int *cur, i, j;
639
640 mapset = G_find_raster2(filename, "");
641 if (!mapset) {
642 G_warning(_("Raster map <%s> not found"), filename);
643 return;
644 }
645
646 r = (unsigned char *)G_malloc(cols);
647 g = (unsigned char *)G_malloc(cols);
648 b = (unsigned char *)G_malloc(cols);
649 set = (unsigned char *)G_malloc(cols);
650
651 Rast_read_colors(filename, mapset, &colrules);
652
653 cur = buff;
654 char *mname = G_fully_qualified_name(filename, mapset);
655
656 G_message(_("Translating colors from raster map <%s>..."), mname);
657
658 for (i = 0; i < rows; i++) {
659 Rast_lookup_c_colors(cur, r, g, b, set, cols, &colrules);
660 G_percent(i, rows, 2);
661
662 for (j = 0; j < cols; j++) {
663 if (set[j]) {
664 cur[j] = (r[j] & 0xff) | ((g[j] & 0xff) << 8) |
665 ((b[j] & 0xff) << 16);
666 }
667 else {
668 cur[j] = NO_DATA_COL;
669 }
670 }
671
672 cur = &(cur[cols]);
673 }
674 G_percent(1, 1, 1);
675
677
678 G_free(r);
679 G_free(g);
680 G_free(b);
681 G_free(mname);
682 G_free(set);
683
684 return;
685}
686
687/*!
688 \brief Pack color table (floating-point map)
689
690 Passed a array of floats that will be converted from cell values
691 to packed colors (0xbbggrr) and float to int
692 Floating point data not freed here, use:
693 gsds_free_data_buff(id, ATTY_FLOAT)
694
695 \param filename raster map name
696 \param fbuf
697 \param ibuf
698 \param rows number of rows
699 \param cols number of cols
700 */
701void Gs_pack_colors_float(const char *filename, float *fbuf, int *ibuf,
702 int rows, int cols)
703{
704 const char *mapset;
705 struct Colors colrules;
706 unsigned char *r, *g, *b, *set;
707 int i, j, *icur;
708 FCELL *fcur;
709
710 mapset = G_find_raster2(filename, "");
711 if (!mapset) {
712 G_warning(_("Raster map <%s> not found"), filename);
713 return;
714 }
715
716 r = (unsigned char *)G_malloc(cols);
717 g = (unsigned char *)G_malloc(cols);
718 b = (unsigned char *)G_malloc(cols);
719 set = (unsigned char *)G_malloc(cols);
720
721 Rast_read_colors(filename, mapset, &colrules);
722
723 fcur = fbuf;
724 icur = ibuf;
725 char *mname = G_fully_qualified_name(filename, mapset);
726
727 G_message(_("Translating colors from raster map <%s>..."), mname);
728
729 for (i = 0; i < rows; i++) {
730 Rast_lookup_f_colors(fcur, r, g, b, set, cols, &colrules);
731 G_percent(i, rows, 2);
732
733 for (j = 0; j < cols; j++) {
734 if (set[j]) {
735 icur[j] = (r[j] & 0xff) | ((g[j] & 0xff) << 8) |
736 ((b[j] & 0xff) << 16);
737 }
738 else {
739 icur[j] = NO_DATA_COL;
740 }
741 }
742
743 icur = &(icur[cols]);
744 fcur = &(fcur[cols]);
745 }
746 G_percent(1, 1, 1);
747
749
750 G_free(r);
751 G_free(g);
752 G_free(b);
753 G_free(set);
754 G_free(mname);
755
756 return;
757}
758
759/*!
760 \brief Get categories/labels
761
762 Formats label as in d.what.rast -> (catval) catlabel
763
764 \param filename raster map name
765 \param drow
766 \param dcol
767 \param catstr category string
768
769 \return 1 on success
770 \return 0 on failure
771 */
772int Gs_get_cat_label(const char *filename, int drow, int dcol, char *catstr)
773{
774 struct Categories cats;
775 const char *mapset;
776 CELL *buf;
777 DCELL *dbuf;
778 RASTER_MAP_TYPE map_type;
779 int fd = -1;
780
781 if ((mapset = G_find_raster2(filename, "")) == NULL) {
782 G_warning(_("Raster map <%s> not found"), filename);
783 return 0;
784 }
785
786 if (-1 != Rast_read_cats(filename, mapset, &cats)) {
787 fd = Rast_open_old(filename, mapset);
788 map_type = Rast_get_map_type(fd);
789
790 if (map_type == CELL_TYPE) {
791 buf = Rast_allocate_c_buf();
792
793 Rast_get_c_row(fd, buf, drow);
794 if (Rast_is_c_null_value(&buf[dcol])) {
795 sprintf(catstr, "(NULL) %s", Rast_get_c_cat(&buf[dcol], &cats));
796 }
797 else {
798 sprintf(catstr, "(%d) %s", buf[dcol],
799 Rast_get_c_cat(&buf[dcol], &cats));
800 }
801
802 G_free(buf);
803 }
804
805 else {
806 /* fp map */
808
811 sprintf(catstr, "(NULL) %s",
812 Rast_get_d_cat(&dbuf[dcol], &cats));
813 }
814 else {
815 sprintf(catstr, "(%g) %s", dbuf[dcol],
816 Rast_get_d_cat(&dbuf[dcol], &cats));
817 }
818
819 G_free(dbuf);
820 }
821 }
822 else {
823 strcpy(catstr, "no category label");
824 return 0;
825 }
826
827 /* TODO: may want to keep these around for multiple queries */
828 Rast_free_cats(&cats);
829
830 if (fd >= 0)
831 Rast_close(fd);
832
833 return (1);
834}
835
836/*!
837 \brief Save 3dview
838
839 \param vname view name
840 \param gv pointer to geoview struct
841 \param gd pointer to geodisplay struct (unused)
842 \param w current window
843 \param defsurf default geosurf struct
844
845 \return -1 on error
846 \return ?
847 */
849 struct Cell_head *w, geosurf *defsurf)
850{
851 const char *mapset;
852 struct G_3dview v;
853 float zmax, zmin;
854
855 GS_get_zrange(&zmin, &zmax, 0);
856
858 mapset = G_mapset();
859
860 if (mapset != NULL) {
861 if (defsurf) {
862 if (defsurf->draw_mode & DM_WIRE_POLY) {
863 v.display_type = 3;
864 }
865 else if (defsurf->draw_mode & DM_WIRE ||
866 defsurf->draw_mode & DM_COL_WIRE) {
867 v.display_type = 1;
868 }
869 else if (defsurf->draw_mode & DM_POLY) {
870 v.display_type = 2;
871 }
872
873 v.mesh_freq = defsurf->x_modw; /* mesh resolution */
874 v.poly_freq = defsurf->x_mod; /* poly resolution */
875 v.dozero = !(defsurf->nz_topo);
876 v.colorgrid = (defsurf->draw_mode & DM_COL_WIRE) ? 1 : 0;
877 v.shading = (defsurf->draw_mode & DM_GOURAUD) ? 1 : 0;
878 }
879
880 if (gv->infocus) {
881 GS_v3eq(v.from_to[TO], gv->real_to);
882 v.from_to[TO][Z] -= zmin;
883 GS_v3mult(v.from_to[TO], gv->scale);
884 v.from_to[TO][Z] *= gv->vert_exag;
885 }
886 else {
887 GS_v3eq(v.from_to[TO], gv->from_to[TO]);
888 }
889
891
892 GS_v3eq(v.from_to[FROM], gv->from_to[FROM]);
894
895 v.exag = gv->vert_exag;
896 v.fov = gv->fov / 10.;
897 v.twist = gv->twist;
898 v.fringe = 0; /* not implemented here */
899
900 v.lightson = 1; /* always true, currently */
901
902 if (gv->lights[0].position[W] == 1) {
903 /* local */
904 v.lightpos[X] = gv->lights[0].position[X];
905 v.lightpos[Y] = gv->lights[0].position[Y];
906 v.lightpos[Z] = gv->lights[0].position[Z];
908 v.lightpos[W] = 1.0; /* local */
909 }
910 else {
911 v.lightpos[X] = gv->lights[0].position[X];
912 v.lightpos[Y] = gv->lights[0].position[Y];
913 v.lightpos[Z] = gv->lights[0].position[Z];
914 v.lightpos[W] = 0.0; /* inf */
915 }
916
917 v.lightcol[0] = gv->lights[0].color[0];
918 v.lightcol[1] = gv->lights[0].color[1];
919 v.lightcol[2] = gv->lights[0].color[2];
920
921 v.ambient = (gv->lights[0].ambient[0] + gv->lights[0].ambient[1] +
922 gv->lights[0].ambient[2]) /
923 3.;
924 v.shine = gv->lights[0].shine;
925
926 v.surfonly = 0; /* N/A - now uses constant color */
927 strcpy((v.pgm_id), "Nvision-ALPHA!");
928
929 return (G_put_3dview(vname, &v, w));
930 }
931 else {
932 return (-1);
933 }
934}
935
936/*!
937 \brief Load 3dview
938
939 \param vname view name
940 \param gv pointer to geoview struct
941 \param gd pointer to geodisplay struct (unused)
942 \param w current window
943 \param defsurf default geosurf struct
944
945 \return 1
946 */
948 struct Cell_head *w, const geosurf *defsurf)
949{
950 const char *mapset;
951 struct G_3dview v;
952 int ret = -1;
953
954 mapset = G_find_file2("3d.view", vname, "");
955
956 if (mapset != NULL) {
957 ret = G_get_3dview(vname, mapset, &v);
958 }
959
960 if (ret >= 0) {
961 if (strcmp((v.pgm_id), "Nvision-ALPHA!")) {
962 G_warning(_("View not saved by this program,"
963 "there may be some inconsistencies"));
964 }
965
966 /* set poly and mesh resolutions */
967 v.mesh_freq = (int)(v.mesh_freq * v.vwin.ns_res / w->ns_res);
968 v.poly_freq = (int)(v.poly_freq * v.vwin.ns_res / w->ns_res);
969
970 /* Set To and FROM positions */
971 /* TO */
972 float pt[3];
973
974 pt[0] = (v.from_to[TO][X] - w->west) - w->ew_res / 2.;
975 pt[1] = (v.from_to[TO][Y] - w->south) - w->ns_res / 2.;
976 pt[2] = v.from_to[TO][Z];
978
979 /* FROM */
980 pt[0] = (float)v.from_to[FROM][X];
981 pt[1] = (float)v.from_to[FROM][Y];
982 pt[2] = (float)v.from_to[FROM][Z];
984
985 if (defsurf) {
986 int dmode = 0;
987
989 v.mesh_freq);
990
991 while (v.display_type >= 10) {
992 /* globe stuff not used */
993 v.display_type -= 10;
994 }
995
996 /* set drawing modes */
997 if (v.colorgrid) {
999 }
1000
1001 if (v.shading) {
1002 dmode |= DM_GOURAUD;
1003 }
1004
1005 switch (v.display_type) {
1006 case 1:
1007 dmode |= DM_WIRE;
1008
1009 break;
1010 case 2:
1011 dmode |= DM_POLY;
1012
1013 break;
1014 case 3:
1016
1017 break;
1018 }
1020
1021 /* should also set nozeros here */
1022 }
1023
1024 /* set exaggeration */
1025 if (v.exag)
1027
1028 /* Set FOV */
1029 if (v.fov) {
1030 GS_set_fov(
1031 (int)(v.fov > 0 ? v.fov * 10. + 0.5 : v.fov * 10. - 0.5));
1032 }
1033 else {
1034 /* TODO: do ortho */
1035 }
1036
1037 /* Set twist */
1038 if (v.twist)
1039 GS_set_twist((int)(v.twist > 0 ? v.twist + 0.5 : v.twist - 0.5));
1040
1041 /* TODO: OK to here - need to unravel/reverse lights stuff*** */
1042
1043 if (v.lightson) {
1044 /* Lights are on */
1045
1046 /* Light Position */
1047 gv->lights[0].position[X] = v.lightpos[X];
1048 gv->lights[0].position[Y] = v.lightpos[Y];
1049 gv->lights[0].position[Z] = v.lightpos[Z];
1050
1051 /* Light Color */
1052 gv->lights[0].color[0] = v.lightcol[0];
1053 gv->lights[0].color[1] = v.lightcol[1];
1054 gv->lights[0].color[2] = v.lightcol[2];
1055
1056 /* Light Shininess */
1057 gv->lights[0].shine = v.shine;
1058
1059 /* Light Ambient */
1060 gv->lights[0].ambient[0] = gv->lights[0].ambient[1] =
1061 gv->lights[0].ambient[2] = v.ambient * 3.;
1062
1063 } /* Done with lights */
1064
1066
1067 } /* Done with file */
1068 return (1);
1069}
1070
1071/*!
1072 \brief Update no_zero ranges for attribute (actually no_null now)
1073
1074 \param gs pointer to geosurf struct
1075 \param desc attribute id (descriptor)
1076
1077 \return -1 on error
1078 \return 1 on success
1079 */
1081{
1082 size_t size;
1083 float min = 0.0;
1084 float max = 0.0;
1085 typbuff *tb;
1086 struct BM *nm;
1087 int found;
1088
1089 gs->att[desc].max_nz = gs->att[desc].min_nz = gs->att[desc].range_nz = 0.0;
1090
1091 if (CONST_ATT == gs_get_att_src(gs, desc)) {
1092 gs->att[desc].max_nz = gs->att[desc].min_nz = gs->att[desc].constant;
1093 min = max = gs->att[desc].constant;
1094 gs->att[desc].range_nz = 0.0;
1095 }
1096 else if (CF_COLOR_PACKED & gsds_get_changed(gs->att[desc].hdata)) {
1097 gs->att[desc].max_nz = 0xFFFFFF;
1098 gs->att[desc].min_nz = 0x010101;
1099 gs->att[desc].range_nz = 0xFFFFFF;
1100 }
1101 else {
1102 if (NULL == (tb = gsds_get_typbuff(gs->att[desc].hdata, 0))) {
1103 return (-1);
1104 }
1105
1106 nm = tb->nm;
1107
1108 if (tb->ib) {
1109 int *p;
1110
1111 size = (size_t)gs->rows * gs->cols;
1112 p = tb->ib;
1113 INIT_MINMAX(p, nm, size, min, max, found);
1114
1115 if (!found) {
1116 /* all nulls! */
1117 return (-1);
1118 }
1119
1120 size = (size_t)gs->rows * gs->cols;
1121 p = tb->ib;
1122 SET_MINMAX(p, nm, size, min, max);
1123 }
1124 else if (tb->sb) {
1125 short *p;
1126
1127 size = (size_t)gs->rows * gs->cols;
1128 p = tb->sb;
1129 INIT_MINMAX(p, nm, size, min, max, found);
1130
1131 if (!found) {
1132 /* all nulls! */
1133 return (-1);
1134 }
1135
1136 size = (size_t)gs->rows * gs->cols;
1137 p = tb->sb;
1138 SET_MINMAX(p, nm, size, min, max);
1139 }
1140 else if (tb->cb) {
1141 char *p;
1142
1143 size = (size_t)gs->rows * gs->cols;
1144 p = (char *)tb->cb;
1145 INIT_MINMAX(p, nm, size, min, max, found);
1146
1147 if (!found) {
1148 /* all nulls! */
1149 return (-1);
1150 }
1151
1152 size = (size_t)gs->rows * gs->cols;
1153 p = (char *)tb->cb;
1154 SET_MINMAX(p, nm, size, min, max);
1155 }
1156 else if (tb->fb) {
1157 float *p;
1158
1159 size = (size_t)gs->rows * gs->cols;
1160 p = tb->fb;
1161 INIT_MINMAX(p, nm, size, min, max, found);
1162
1163 if (!found) {
1164 /* all nulls! */
1165 return (-1);
1166 }
1167
1168 size = (size_t)gs->rows * gs->cols;
1169 p = tb->fb;
1170 SET_MINMAX(p, nm, size, min, max);
1171 }
1172
1173 gs->att[desc].max_nz = max;
1174 gs->att[desc].min_nz = min;
1175 gs->att[desc].range_nz = gs->att[desc].max_nz - gs->att[desc].min_nz;
1176 }
1177
1178 if (ATT_TOPO == desc) {
1179 gs->zmin = min;
1180 gs->zmax = max;
1181 gs->zrange = gs->zmax - gs->zmin;
1182 gs->zminmasked = gs->zmin;
1183 gs->zmax_nz = gs->zmax;
1184 gs->zmin_nz = gs->zmin;
1185 gs->zrange_nz = gs->zmax_nz - gs->zmin_nz;
1186 }
1187
1188 G_debug(3, "Gs_update_attrange(): min=%f max=%f", gs->zmin, gs->zmax);
1189
1190 return (1);
1191}
#define NULL
Definition ccmath.h:32
int BM_set(struct BM *, int, int, int)
Sets bitmap value to 'val' at location 'x' 'y'.
Definition bitmap.c:182
void G_percent(long, long, int)
Print percent complete messages.
Definition percent.c:59
void G_zero(void *, int)
Zero out a buffer, buf, of length i.
Definition gis/zero.c:21
void G_free(void *)
Free allocated memory.
Definition gis/alloc.c:145
void G_warning(const char *,...) __attribute__((format(printf
int G_get_3dview(const char *, const char *, struct G_3dview *)
Gets a 3D View.
Definition view.c:237
#define G_malloc(n)
Definition defs/gis.h:136
const char * G_find_file2(const char *, const char *, const char *)
Searches for a file from the mapset search list or in a specified mapset. (look but don't touch)
Definition find_file.c:230
char * G_fully_qualified_name(const char *, const char *)
Get fully qualified element name.
Definition nme_in_mps.c:99
int G_put_3dview(const char *, const struct G_3dview *, const struct Cell_head *)
Saves info to a 3d.view file in the current mapset.
Definition view.c:158
double G_distance(double, double, double, double)
Returns distance in meters.
void G_message(const char *,...) __attribute__((format(printf
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 G_get_3dview_defaults(struct G_3dview *, struct Cell_head *)
Sets default for v based on w.
Definition view.c:54
const char * G_mapset(void)
Get current mapset name.
Definition gis/mapset.c:31
int int G_begin_distance_calculations(void)
Begin distance calculations.
void GS_v3mult(float *, float)
Multiple vectors.
Definition gs_util.c:225
void GS_set_fov(int)
Set field of view.
Definition gs2.c:2837
void GS_alldraw_wire(void)
Draw all wires.
Definition gs2.c:1916
int GS_get_zrange(float *, float *, int)
Get z-extent for all loaded surfaces.
Definition gs2.c:2684
int GS_setall_drawmode(int)
Set all draw-modes.
Definition gs2.c:2058
int gs_get_att_src(geosurf *, int)
Get attribute source.
Definition gs.c:652
void GS_set_focus(float *)
Set focus.
Definition gs2.c:2516
void GS_set_twist(int)
Set viewpoint twist value.
Definition gs2.c:2871
void GS_v3eq(float *, float *)
Copy vector values.
Definition gs_util.c:174
int GS_setall_drawres(int, int, int, int)
Set all draw resolutions.
Definition gs2.c:2195
void GS_set_global_exag(float)
Set global z-exag value.
Definition gs2.c:1974
void GS_moveto_real(float *)
Move position to (real)
Definition gs2.c:2642
int gsds_get_changed(int)
ADD.
Definition gsds.c:609
void gsd_model2real(Point3)
Convert model to real coordinates.
Definition gsd_views.c:389
typbuff * gsds_get_typbuff(int, IFLAG)
void Rast_free_cats(struct Categories *)
Free category structure memory.
CELL * Rast_allocate_c_buf(void)
Allocate memory for a CELL type raster map.
Definition alloc_cell.c:78
DCELL * Rast_allocate_d_buf(void)
Allocates memory for a raster map of type DCELL.
Definition alloc_cell.c:104
int Rast_read_colors(const char *, const char *, struct Colors *)
Read color table of raster map.
int Rast_read_cats(const char *, const char *, struct Categories *)
Read raster category file.
#define Rast_is_f_null_value(fcellVal)
void Rast_lookup_f_colors(const FCELL *, unsigned char *, unsigned char *, unsigned char *, unsigned char *, int, struct Colors *)
Lookup an array of colors (FCELL)
Definition color_look.c:109
void Rast_close(int)
Close a raster map.
int Rast_open_old(const char *, const char *)
Open an existing integer raster map (cell)
void Rast_free_colors(struct Colors *)
Free color structure memory.
Definition color_free.c:28
char * Rast_get_c_cat(CELL *, struct Categories *)
Get a raster category label (CELL)
void Rast_get_c_row(int, CELL *, int)
Get raster row (CELL type)
void Rast_get_f_row(int, FCELL *, int)
Get raster row (FCELL type)
void Rast_get_d_row(int, DCELL *, int)
Get raster row (DCELL type)
void Rast_get_c_color_range(CELL *, CELL *, const struct Colors *)
Get color range values (CELL)
Definition color_range.c:62
void Rast_get_range_min_max(const struct Range *, CELL *, CELL *)
Get range min and max.
int Rast_read_range(const char *, const char *, struct Range *)
Read raster range (CELL)
int Rast_map_is_fp(const char *, const char *)
Check if raster map is floating-point.
#define Rast_is_d_null_value(dcellVal)
#define Rast_is_c_null_value(cellVal)
void Rast_lookup_c_colors(const CELL *, unsigned char *, unsigned char *, unsigned char *, unsigned char *, int, struct Colors *)
Lookup an array of colors.
Definition color_look.c:42
char * Rast_get_d_cat(DCELL *, struct Categories *)
Get a raster category label (DCELL)
RASTER_MAP_TYPE Rast_get_map_type(int)
Determine raster type from descriptor.
#define min(x, y)
Definition draw2.c:29
#define max(x, y)
Definition draw2.c:30
float FCELL
Definition gis.h:633
#define G_UNUSED
A macro for an attribute, if attached to a variable, indicating that the variable is not used.
Definition gis.h:43
double DCELL
Definition gis.h:632
int CELL
Definition gis.h:631
#define _(str)
Definition glocale.h:10
int Gs_load_3dview(const char *vname, geoview *gv, geodisplay *gd, struct Cell_head *w, const geosurf *defsurf)
Load 3dview.
Definition gs3.c:947
int Gs_loadmap_as_short(struct Cell_head *wind, const char *map_name, short *buff, struct BM *nullmap, int *has_null)
Load raster map as integer map.
Definition gs3.c:305
int Gs_loadmap_as_bitmap(struct Cell_head *wind, const char *map_name, struct BM *buff)
Load raster map as integer map.
Definition gs3.c:512
int Gs_numtype(const char *filename, int *negflag)
Get map data type.
Definition gs3.c:223
void Gs_pack_colors(const char *filename, int *buff, int rows, int cols)
Pack color table.
Definition gs3.c:633
void Gs_pack_colors_float(const char *filename, float *fbuf, int *ibuf, int rows, int cols)
Pack color table (floating-point map)
Definition gs3.c:701
#define INIT_MINMAX(p, nm, size, min, max, found)
Used in the function Gs_update_attrange()
Definition gs3.c:31
int Gs_loadmap_as_char(struct Cell_head *wind, const char *map_name, unsigned char *buff, struct BM *nullmap, int *has_null)
Load raster map as integer map.
Definition gs3.c:411
#define NO_DATA_COL
Definition gs3.c:62
int Gs_save_3dview(const char *vname, geoview *gv, geodisplay *gd, struct Cell_head *w, geosurf *defsurf)
Save 3dview.
Definition gs3.c:848
int FILEDESC
Definition gs3.c:60
int Gs_loadmap_as_float(struct Cell_head *wind, const char *map_name, float *buff, struct BM *nullmap, int *has_null)
Load raster map as floating point map.
Definition gs3.c:105
int Gs_get_cat_label(const char *filename, int drow, int dcol, char *catstr)
Get categories/labels.
Definition gs3.c:772
#define SET_MINMAX(p, nm, size, min, max)
Used in the function Gs_update_attrange()
Definition gs3.c:46
double Gs_distance(double *from, double *to)
Calculates distance in METERS between two points in current projection (2D)
Definition gs3.c:75
int Gs_build_256lookup(const char *filename, int *buff)
Build color table (256)
Definition gs3.c:572
int Gs_update_attrange(geosurf *gs, int desc)
Update no_zero ranges for attribute (actually no_null now)
Definition gs3.c:1080
int Gs_loadmap_as_int(struct Cell_head *wind, const char *map_name, int *buff, struct BM *nullmap, int *has_null)
Load raster map as integer map.
Definition gs3.c:170
float g
Definition named_colr.c:7
OGSF header file (structures)
#define ATTY_SHORT
Definition ogsf.h:171
#define X
Definition ogsf.h:141
#define ATT_TOPO
Definition ogsf.h:76
#define DM_WIRE_POLY
Definition ogsf.h:65
#define Z
Definition ogsf.h:143
#define DM_WIRE
Definition ogsf.h:62
#define W
Definition ogsf.h:144
#define ATTY_FLOAT
Definition ogsf.h:169
#define Y
Definition ogsf.h:142
#define ATTY_INT
Definition ogsf.h:170
#define ATTY_CHAR
Definition ogsf.h:172
#define FROM
Definition ogsf.h:145
#define DM_POLY
Definition ogsf.h:64
#define DM_GOURAUD
Definition ogsf.h:57
#define CONST_ATT
Definition ogsf.h:87
#define CF_COLOR_PACKED
Definition ogsf.h:185
#define TO
Definition ogsf.h:146
#define DM_COL_WIRE
Definition ogsf.h:63
#define strcpy
Definition parson.c:66
double b
Definition r_raster.c:37
double r
Definition r_raster.c:37
#define CELL_TYPE
Definition raster.h:11
int RASTER_MAP_TYPE
Definition raster.h:25
Definition bitmap.h:17
2D/3D raster map header (used also for region)
Definition gis.h:443
double ew_res
Resolution - east to west cell size for 2D data.
Definition gis.h:479
double ns_res
Resolution - north to south cell size for 2D data.
Definition gis.h:483
int rows
Number of rows for 2D data.
Definition gis.h:458
int cols
Number of columns for 2D data.
Definition gis.h:462
double south
Extent coordinates (south)
Definition gis.h:491
double west
Extent coordinates (west)
Definition gis.h:495
Definition gis.h:689
struct Cell_head vwin
Definition gis.h:528
int mesh_freq
Definition gis.h:511
float from_to[2][3]
Definition gis.h:507
float fov
Definition gis.h:508
char pgm_id[40]
Definition gis.h:506
int colorgrid
Definition gis.h:516
float lightcol[3]
Definition gis.h:525
int shading
Definition gis.h:517
int dozero
Definition gis.h:515
int lightson
Definition gis.h:514
float shine
Definition gis.h:527
int display_type
Definition gis.h:513
int poly_freq
Definition gis.h:512
float ambient
Definition gis.h:526
float exag
Definition gis.h:510
float twist
Definition gis.h:509
int fringe
Definition gis.h:518
float lightpos[4]
Definition gis.h:524
int surfonly
Definition gis.h:519
Definition ogsf.h:267