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