GRASS GIS 8 Programmer's Manual 8.3.2(2024)-exported
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 from 'from' point (X, Y)
75 \param 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{
112 FILEDESC cellfile;
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
127 G_message(_("Loading raster map <%s>..."),
128 G_fully_qualified_name(map_name, map_set));
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
148 Rast_close(cellfile);
149
150 return (1);
151}
152
153/*!
154 \brief Load raster map as integer map
155
156 Calling function must have already allocated space in buff for
157 wind->rows * wind->cols floats.
158
159 This routine simply loads the map into a 2d array by repetitve calls
160 to get_f_raster_row.
161
162 \todo fn body of Gs_loadmap_as_float()
163
164 \param wind current window
165 \param map_name raster map name
166 \param[out] buff data buffer
167 \param[out] nullmap null map buffer
168 \param[out] has_null indicates if raster map contains null-data
169
170 \return 1 on success
171 \return 0 on failure
172 */
173int Gs_loadmap_as_int(struct Cell_head *wind, const char *map_name, int *buff,
174 struct BM *nullmap, int *has_null)
175{
176 FILEDESC cellfile;
177 const char *map_set;
178 int offset, row, col;
179
180 G_debug(3, "Gs_loadmap_as_int");
181
182 map_set = G_find_raster2(map_name, "");
183 if (!map_set) {
184 G_warning(_("Raster map <%s> not found"), map_name);
185 return 0;
186 }
187 *has_null = 0;
188
189 cellfile = Rast_open_old(map_name, map_set);
190
191 G_message(_("Loading raster map <%s>..."),
192 G_fully_qualified_name(map_name, map_set));
193
194 for (row = 0; row < wind->rows; row++) {
195 offset = row * wind->cols;
196 Rast_get_c_row(cellfile, &(buff[offset]), row);
197
198 G_percent(row, wind->rows, 2);
199
200 for (col = 0; col < wind->cols; col++) {
201 if (Rast_is_f_null_value(buff + offset + col)) {
202 *has_null = 1;
203 BM_set(nullmap, col, row, 1);
204 }
205
206 /* set nm */
207 }
208 }
209 G_percent(1, 1, 1);
210
211 Rast_close(cellfile);
212
213 return (1);
214}
215
216/*!
217 \brief Get map data type
218
219 \param filename raster map name
220 \param negflag
221
222 \return -1 if map is integer and Rast_read_range() fails
223 \return data type (ARRY_*)
224 */
225int Gs_numtype(const char *filename, int *negflag)
226{
227 CELL max = 0, min = 0;
228 struct Range range;
229 const char *mapset;
230 int shortbits, charbits, bitplace;
231 static int max_short, max_char;
232 static int first = 1;
233
234 if (first) {
235 max_short = max_char = 1;
236 shortbits = 8 * sizeof(short);
237
238 for (bitplace = 1; bitplace < shortbits; ++bitplace) {
239 /*1 bit for sign */
240 max_short *= 2;
241 }
242
243 max_short -= 1;
244
245 /* NO bits for sign, using unsigned char */
246 charbits = 8 * sizeof(unsigned char);
247
248 for (bitplace = 0; bitplace < charbits; ++bitplace) {
249 max_char *= 2;
250 }
251
252 max_char -= 1;
253
254 first = 0;
255 }
256
257 mapset = G_find_raster2(filename, "");
258 if (!mapset) {
259 G_warning(_("Raster map <%s> not found"), filename);
260 return -1;
261 }
262
263 if (Rast_map_is_fp(filename, mapset)) {
264 G_debug(3, "Gs_numtype(): fp map detected");
265
266 return (ATTY_FLOAT);
267 }
268
269 if (-1 == Rast_read_range(filename, mapset, &range)) {
270 return (-1);
271 }
272
273 Rast_get_range_min_max(&range, &min, &max);
274 *negflag = (min < 0);
275
277 return (ATTY_CHAR);
278 }
279
280 if (max < max_short && min > -max_short) {
281 return (ATTY_SHORT);
282 }
283
284 return (ATTY_INT);
285}
286
287/*!
288 \brief Load raster map as integer map
289
290 Calling function must have already allocated space in buff for
291 wind->rows * wind->cols shorts.
292
293 This routine simply loads the map into a 2d array by repetitve calls
294 to get_map_row.
295
296 \param wind current window
297 \param map_name raster map name
298 \param[out] buff data buffer
299 \param[out] nullmap null map buffer
300 \param[out] has_null indicates if raster map contains null-data
301
302 \return 1 on success
303 \return -1 on failure,
304 \return -2 if read ok, but 1 or more values were too large (small)
305 to fit into a short (in which case the max (min) short is used)
306 */
307int Gs_loadmap_as_short(struct Cell_head *wind, const char *map_name,
308 short *buff, struct BM *nullmap, int *has_null)
309{
310 FILEDESC cellfile;
311 const char *map_set;
312 int *ti, *tmp_buf;
313 int offset, row, col, val, max_short, overflow, shortsize, bitplace;
314 short *ts;
315
316 G_debug(3, "Gs_loadmap_as_short");
317
318 overflow = 0;
319 shortsize = 8 * sizeof(short);
320
321 /* 1 bit for sign */
322 /* same as 2 << (shortsize-1) */
323 for (max_short = bitplace = 1; bitplace < shortsize; ++bitplace) {
324 max_short *= 2;
325 }
326
327 max_short -= 1;
328
329 map_set = G_find_raster2(map_name, "");
330 if (!map_set) {
331 G_warning(_("Raster map <%s> not found"), map_name);
332 return -1;
333 }
334 *has_null = 0;
335
336 cellfile = Rast_open_old(map_name, map_set);
337
338 tmp_buf = (int *)G_malloc(wind->cols * sizeof(int)); /* G_fatal_error */
339 if (!tmp_buf) {
340 return -1;
341 }
342
343 G_message(_("Loading raster map <%s>..."),
344 G_fully_qualified_name(map_name, map_set));
345
346 for (row = 0; row < wind->rows; row++) {
347 offset = row * wind->cols;
348 Rast_get_c_row(cellfile, tmp_buf, row);
349
350 G_percent(row, wind->rows, 2);
351
352 ts = &(buff[offset]);
353 ti = tmp_buf;
354
355 for (col = 0; col < wind->cols; col++) {
356 if (Rast_is_c_null_value(&tmp_buf[col])) {
357 *has_null = 1;
358 BM_set(nullmap, col, row, 1);
359 }
360 else {
361 val = *ti;
362 if (abs(val) > max_short) {
363 overflow = 1;
364 /* assign floor/ceiling value?
365 */
366 *ts = (short)(max_short * val / abs(val));
367 }
368 else {
369 *ts = (short)val;
370 }
371 }
372
373 ti++;
374 ts++;
375 }
376 }
377 G_percent(1, 1, 1);
378
379 Rast_close(cellfile);
380
381 G_free(tmp_buf);
382
383 return (overflow ? -2 : 1);
384}
385
386/*!
387 \brief Load raster map as integer map
388
389 Calling function must have already allocated space in buff for
390 wind->rows * wind->cols unsigned chars.
391
392 This routine simply loads the map into a 2d array by repetitve calls
393 to get_map_row.
394
395 Since signs of chars can be tricky, we only load positive chars
396 between 0-255.
397
398 \todo fn body Gs_loadmap_as_float()
399
400 \param wind current window
401 \param map_name raster map name
402 \param[out] buff data buffer
403 \param[out] nullmap null map buffer
404 \param[out] has_null indicates if raster map contains null-data
405
406 \return 1 on success
407 \return -1 on failure
408 \return -2 if read ok, but 1 or more values
409 were too large (small) to fit into an unsigned char.
410 (in which case the max (min) char is used)
411 */
412int Gs_loadmap_as_char(struct Cell_head *wind, const char *map_name,
413 unsigned char *buff, struct BM *nullmap, int *has_null)
414{
415 FILEDESC cellfile;
416 const char *map_set;
417 int *ti, *tmp_buf;
418 int offset, row, col, val, max_char, overflow, charsize, bitplace;
419 unsigned char *tc;
420
421 G_debug(3, "Gs_loadmap_as_char");
422
423 overflow = 0;
424 charsize = 8 * sizeof(unsigned char);
425
426 /* 0 bits for sign! */
427 max_char = 1;
428
429 for (bitplace = 0; bitplace < charsize; ++bitplace) {
430 max_char *= 2;
431 }
432
433 max_char -= 1;
434
435 map_set = G_find_raster2(map_name, "");
436 if (!map_set) {
437 G_warning(_("Raster map <%s> not found"), map_name);
438 return -1;
439 }
440 *has_null = 0;
441
442 cellfile = Rast_open_old(map_name, map_set);
443
444 tmp_buf = (int *)G_malloc(wind->cols * sizeof(int)); /* G_fatal_error */
445 if (!tmp_buf) {
446 return -1;
447 }
448
449 G_message(_("Loading raster map <%s>..."),
450 G_fully_qualified_name(map_name, map_set));
451
452 for (row = 0; row < wind->rows; row++) {
453 offset = row * wind->cols;
454 Rast_get_c_row(cellfile, tmp_buf, row);
455 tc = (unsigned char *)&(buff[offset]);
456 ti = tmp_buf;
457
458 G_percent(row, wind->rows, 2);
459
460 for (col = 0; col < wind->cols; col++) {
461 if (Rast_is_c_null_value(&tmp_buf[col])) {
462 *has_null = 1;
463 BM_set(nullmap, col, row, 1);
464 }
465 else {
466 val = *ti;
467 if (val > max_char) {
468 overflow = 1;
469 *tc = (unsigned char)max_char;
470 }
471 else if (val < 0) {
472 overflow = 1;
473 *tc = 0;
474 }
475 else {
476 *tc = (unsigned char)val;
477 }
478 }
479
480 ti++;
481 tc++;
482 }
483 }
484 G_percent(1, 1, 1);
485
486 Rast_close(cellfile);
487
488 G_free(tmp_buf);
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{
515 FILEDESC cellfile;
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 G_message(_("Loading raster map <%s>..."),
536 G_fully_qualified_name(map_name, map_set));
537
538 for (row = 0; row < wind->rows; row++) {
539 Rast_get_c_row(cellfile, tmp_buf, row);
540
541 for (col = 0; col < wind->cols; col++) {
542 if (Rast_is_c_null_value(&tmp_buf[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
552 Rast_close(cellfile);
553
554 G_free(tmp_buf);
555
556 return (1);
557}
558
559/*!
560 \brief Build color table (256)
561
562 Calling function must have already allocated space in buff for range of
563 data (256 for now) - simply calls get_color for each cat in color range
564
565 \param filename raster map name
566 \param[out] buff data buffer
567
568 \return 1 on success
569 \return 0 on failure
570 */
571int Gs_build_256lookup(const char *filename, int *buff)
572{
573 const char *mapset;
574 struct Colors colrules;
575 CELL min, max, cats[256];
576 int i;
577 unsigned char r[256], g[256], b[256], set[256];
578
579 G_debug(3, "building color table");
580
581 mapset = G_find_raster2(filename, "");
582 if (!mapset) {
583 G_warning(_("Raster map <%s> not found"), filename);
584 return 0;
585 }
586
587 Rast_read_colors(filename, mapset, &colrules);
588 Rast_get_c_color_range(&min, &max, &colrules);
589
590 if (min < 0 || max > 255) {
591 G_warning(
592 _("Color table range doesn't match data (mincol=%d, maxcol=%d"),
593 min, max);
594
595 min = min < 0 ? 0 : min;
596 max = max > 255 ? 255 : max;
597 }
598
599 G_zero(cats, 256 * sizeof(CELL));
600
601 for (i = min; i <= max; i++) {
602 cats[i] = i;
603 }
604
605 Rast_lookup_c_colors(cats, r, g, b, set, 256, &colrules);
606
607 for (i = 0; i < 256; i++) {
608
609 if (set[i]) {
610 buff[i] =
611 (r[i] & 0xff) | ((g[i] & 0xff) << 8) | ((b[i] & 0xff) << 16);
612 }
613 else {
614 buff[i] = NO_DATA_COL;
615 }
616 }
617
618 return (1);
619}
620
621/*!
622 \brief Pack color table
623
624 Passed an array of 32 bit ints that is converted from cell values
625 to packed colors (0xbbggrr)
626
627 \param filename raster map name
628 \param buff
629 \param rows number of rows
630 \param cols number of cols
631 */
632void Gs_pack_colors(const char *filename, int *buff, int rows, int cols)
633{
634 const char *mapset;
635 struct Colors colrules;
636 unsigned char *r, *g, *b, *set;
637 int *cur, i, j;
638
639 mapset = G_find_raster2(filename, "");
640 if (!mapset) {
641 G_warning(_("Raster map <%s> not found"), filename);
642 return;
643 }
644
645 r = (unsigned char *)G_malloc(cols);
646 g = (unsigned char *)G_malloc(cols);
647 b = (unsigned char *)G_malloc(cols);
648 set = (unsigned char *)G_malloc(cols);
649
650 Rast_read_colors(filename, mapset, &colrules);
651
652 cur = buff;
653
654 G_message(_("Translating colors from raster map <%s>..."),
655 G_fully_qualified_name(filename, mapset));
656
657 for (i = 0; i < rows; i++) {
658 Rast_lookup_c_colors(cur, r, g, b, set, cols, &colrules);
659 G_percent(i, rows, 2);
660
661 for (j = 0; j < cols; j++) {
662 if (set[j]) {
663 cur[j] = (r[j] & 0xff) | ((g[j] & 0xff) << 8) |
664 ((b[j] & 0xff) << 16);
665 }
666 else {
667 cur[j] = NO_DATA_COL;
668 }
669 }
670
671 cur = &(cur[cols]);
672 }
673 G_percent(1, 1, 1);
674
675 Rast_free_colors(&colrules);
676
677 G_free(r);
678 G_free(g);
679 G_free(b);
680
681 G_free(set);
682
683 return;
684}
685
686/*!
687 \brief Pack color table (floating-point map)
688
689 Passed a array of floats that will be converted from cell values
690 to packed colors (0xbbggrr) and float to int
691 Floating point data not freed here, use:
692 gsds_free_data_buff(id, ATTY_FLOAT)
693
694 \param filename raster map name
695 \param fbuf
696 \param ibuf
697 \param rows number of rows
698 \param cols number of cols
699 */
700void Gs_pack_colors_float(const char *filename, float *fbuf, int *ibuf,
701 int rows, int cols)
702{
703 const char *mapset;
704 struct Colors colrules;
705 unsigned char *r, *g, *b, *set;
706 int i, j, *icur;
707 FCELL *fcur;
708
709 mapset = G_find_raster2(filename, "");
710 if (!mapset) {
711 G_warning(_("Raster map <%s> not found"), filename);
712 return;
713 }
714
715 r = (unsigned char *)G_malloc(cols);
716 g = (unsigned char *)G_malloc(cols);
717 b = (unsigned char *)G_malloc(cols);
718 set = (unsigned char *)G_malloc(cols);
719
720 Rast_read_colors(filename, mapset, &colrules);
721
722 fcur = fbuf;
723 icur = ibuf;
724
725 G_message(_("Translating colors from raster map <%s>..."),
726 G_fully_qualified_name(filename, mapset));
727
728 for (i = 0; i < rows; i++) {
729 Rast_lookup_f_colors(fcur, r, g, b, set, cols, &colrules);
730 G_percent(i, rows, 2);
731
732 for (j = 0; j < cols; j++) {
733 if (set[j]) {
734 icur[j] = (r[j] & 0xff) | ((g[j] & 0xff) << 8) |
735 ((b[j] & 0xff) << 16);
736 }
737 else {
738 icur[j] = NO_DATA_COL;
739 }
740 }
741
742 icur = &(icur[cols]);
743 fcur = &(fcur[cols]);
744 }
745 G_percent(1, 1, 1);
746
747 Rast_free_colors(&colrules);
748
749 G_free(r);
750 G_free(g);
751 G_free(b);
752 G_free(set);
753
754 return;
755}
756
757/*!
758 \brief Get categories/labels
759
760 Formats label as in d.what.rast -> (catval) catlabel
761
762 \param filename raster map name
763 \param drow
764 \param dcol
765 \param catstr category string
766
767 \return 1 on success
768 \return 0 on failure
769 */
770int Gs_get_cat_label(const char *filename, int drow, int dcol, char *catstr)
771{
772 struct Categories cats;
773 const char *mapset;
774 CELL *buf;
775 DCELL *dbuf;
776 RASTER_MAP_TYPE map_type;
777 int fd = -1;
778
779 if ((mapset = G_find_raster2(filename, "")) == NULL) {
780 G_warning(_("Raster map <%s> not found"), filename);
781 return 0;
782 }
783
784 if (-1 != Rast_read_cats(filename, mapset, &cats)) {
785 fd = Rast_open_old(filename, mapset);
786 map_type = Rast_get_map_type(fd);
787
788 if (map_type == CELL_TYPE) {
789 buf = Rast_allocate_c_buf();
790
791 Rast_get_c_row(fd, buf, drow);
792 if (Rast_is_c_null_value(&buf[dcol])) {
793 sprintf(catstr, "(NULL) %s", Rast_get_c_cat(&buf[dcol], &cats));
794 }
795 else {
796 sprintf(catstr, "(%d) %s", buf[dcol],
797 Rast_get_c_cat(&buf[dcol], &cats));
798 }
799
800 G_free(buf);
801 }
802
803 else {
804 /* fp map */
805 dbuf = Rast_allocate_d_buf();
806
807 Rast_get_d_row(fd, dbuf, drow);
808 if (Rast_is_d_null_value(&dbuf[dcol])) {
809 sprintf(catstr, "(NULL) %s",
810 Rast_get_d_cat(&dbuf[dcol], &cats));
811 }
812 else {
813 sprintf(catstr, "(%g) %s", dbuf[dcol],
814 Rast_get_d_cat(&dbuf[dcol], &cats));
815 }
816
817 G_free(dbuf);
818 }
819 }
820 else {
821 strcpy(catstr, "no category label");
822 return 0;
823 }
824
825 /* TODO: may want to keep these around for multiple queries */
826 Rast_free_cats(&cats);
827
828 if (fd >= 0)
829 Rast_close(fd);
830
831 return (1);
832}
833
834/*!
835 \brief Save 3dview
836
837 \param vname view name
838 \param gv pointer to geoview struct
839 \param gd pointer to geodisplay struct (unused)
840 \param w current window
841 \param defsurf default geosurf struct
842
843 \return -1 on error
844 \return ?
845 */
846int Gs_save_3dview(const char *vname, geoview *gv, geodisplay *gd UNUSED,
847 struct Cell_head *w, geosurf *defsurf)
848{
849 const char *mapset;
850 struct G_3dview v;
851 float zmax, zmin;
852
853 GS_get_zrange(&zmin, &zmax, 0);
854
856 mapset = G_mapset();
857
858 if (mapset != NULL) {
859 if (defsurf) {
860 if (defsurf->draw_mode & DM_WIRE_POLY) {
861 v.display_type = 3;
862 }
863 else if (defsurf->draw_mode & DM_WIRE ||
864 defsurf->draw_mode & DM_COL_WIRE) {
865 v.display_type = 1;
866 }
867 else if (defsurf->draw_mode & DM_POLY) {
868 v.display_type = 2;
869 }
870
871 v.mesh_freq = defsurf->x_modw; /* mesh resolution */
872 v.poly_freq = defsurf->x_mod; /* poly resolution */
873 v.dozero = !(defsurf->nz_topo);
874 v.colorgrid = (defsurf->draw_mode & DM_COL_WIRE) ? 1 : 0;
875 v.shading = (defsurf->draw_mode & DM_GOURAUD) ? 1 : 0;
876 }
877
878 if (gv->infocus) {
879 GS_v3eq(v.from_to[TO], gv->real_to);
880 v.from_to[TO][Z] -= zmin;
881 GS_v3mult(v.from_to[TO], gv->scale);
882 v.from_to[TO][Z] *= gv->vert_exag;
883 }
884 else {
885 GS_v3eq(v.from_to[TO], gv->from_to[TO]);
886 }
887
888 gsd_model2real(v.from_to[TO]);
889
890 GS_v3eq(v.from_to[FROM], gv->from_to[FROM]);
891 gsd_model2real(v.from_to[FROM]);
892
893 v.exag = gv->vert_exag;
894 v.fov = gv->fov / 10.;
895 v.twist = gv->twist;
896 v.fringe = 0; /* not implemented here */
897
898 v.lightson = 1; /* always true, currently */
899
900 if (gv->lights[0].position[W] == 1) {
901 /* local */
902 v.lightpos[X] = gv->lights[0].position[X];
903 v.lightpos[Y] = gv->lights[0].position[Y];
904 v.lightpos[Z] = gv->lights[0].position[Z];
905 gsd_model2real(v.lightpos);
906 v.lightpos[W] = 1.0; /* local */
907 }
908 else {
909 v.lightpos[X] = gv->lights[0].position[X];
910 v.lightpos[Y] = gv->lights[0].position[Y];
911 v.lightpos[Z] = gv->lights[0].position[Z];
912 v.lightpos[W] = 0.0; /* inf */
913 }
914
915 v.lightcol[0] = gv->lights[0].color[0];
916 v.lightcol[1] = gv->lights[0].color[1];
917 v.lightcol[2] = gv->lights[0].color[2];
918
919 v.ambient = (gv->lights[0].ambient[0] + gv->lights[0].ambient[1] +
920 gv->lights[0].ambient[2]) /
921 3.;
922 v.shine = gv->lights[0].shine;
923
924 v.surfonly = 0; /* N/A - now uses constant color */
925 strcpy((v.pgm_id), "Nvision-ALPHA!");
926
927 return (G_put_3dview(vname, &v, w));
928 }
929 else {
930 return (-1);
931 }
932}
933
934/*!
935 \brief Load 3dview
936
937 \param vname view name
938 \param gv pointer to geoview struct
939 \param gd pointer to geodisplay struct (unused)
940 \param w current window
941 \param defsurf default geosurf struct
942
943 \return 1
944 */
945int Gs_load_3dview(const char *vname, geoview *gv, geodisplay *gd UNUSED,
946 struct Cell_head *w, const geosurf *defsurf)
947{
948 const char *mapset;
949 struct G_3dview v;
950 int ret = -1;
951
952 mapset = G_find_file2("3d.view", vname, "");
953
954 if (mapset != NULL) {
955 ret = G_get_3dview(vname, mapset, &v);
956 }
957
958 if (ret >= 0) {
959 if (strcmp((v.pgm_id), "Nvision-ALPHA!")) {
960 G_warning(_("View not saved by this program,"
961 "there may be some inconsistancies"));
962 }
963
964 /* set poly and mesh resolutions */
965 v.mesh_freq = (int)(v.mesh_freq * v.vwin.ns_res / w->ns_res);
966 v.poly_freq = (int)(v.poly_freq * v.vwin.ns_res / w->ns_res);
967
968 /* Set To and FROM positions */
969 /* TO */
970 float pt[3];
971
972 pt[0] = (v.from_to[TO][X] - w->west) - w->ew_res / 2.;
973 pt[1] = (v.from_to[TO][Y] - w->south) - w->ns_res / 2.;
974 pt[2] = v.from_to[TO][Z];
975 GS_set_focus(pt);
976
977 /* FROM */
978 pt[0] = (float)v.from_to[FROM][X];
979 pt[1] = (float)v.from_to[FROM][Y];
980 pt[2] = (float)v.from_to[FROM][Z];
981 GS_moveto_real(pt);
982
983 if (defsurf) {
984 int dmode = 0;
985
986 GS_setall_drawres(v.poly_freq, v.poly_freq, v.mesh_freq,
987 v.mesh_freq);
988
989 while (v.display_type >= 10) {
990 /* globe stuff not used */
991 v.display_type -= 10;
992 }
993
994 /* set drawing modes */
995 if (v.colorgrid) {
996 dmode |= DM_COL_WIRE;
997 }
998
999 if (v.shading) {
1000 dmode |= DM_GOURAUD;
1001 }
1002
1003 switch (v.display_type) {
1004 case 1:
1005 dmode |= DM_WIRE;
1006
1007 break;
1008 case 2:
1009 dmode |= DM_POLY;
1010
1011 break;
1012 case 3:
1013 dmode |= DM_WIRE_POLY;
1014
1015 break;
1016 }
1017 GS_setall_drawmode(dmode);
1018
1019 /* should also set nozeros here */
1020 }
1021
1022 /* set exaggeration */
1023 if (v.exag)
1024 GS_set_global_exag(v.exag);
1025
1026 /* Set FOV */
1027 if (v.fov) {
1028 GS_set_fov(
1029 (int)(v.fov > 0 ? v.fov * 10. + 0.5 : v.fov * 10. - 0.5));
1030 }
1031 else {
1032 /* TODO: do ortho */
1033 }
1034
1035 /* Set twist */
1036 if (v.twist)
1037 GS_set_twist((int)(v.twist > 0 ? v.twist + 0.5 : v.twist - 0.5));
1038
1039 /* TODO: OK to here - need to unravel/reverse lights stuff*** */
1040
1041 if (v.lightson) {
1042 /* Lights are on */
1043
1044 /* Light Position */
1045 gv->lights[0].position[X] = v.lightpos[X];
1046 gv->lights[0].position[Y] = v.lightpos[Y];
1047 gv->lights[0].position[Z] = v.lightpos[Z];
1048
1049 /* Light Color */
1050 gv->lights[0].color[0] = v.lightcol[0];
1051 gv->lights[0].color[1] = v.lightcol[1];
1052 gv->lights[0].color[2] = v.lightcol[2];
1053
1054 /* Light Shininess */
1055 gv->lights[0].shine = v.shine;
1056
1057 /* Light Ambient */
1058 gv->lights[0].ambient[0] = gv->lights[0].ambient[1] =
1059 gv->lights[0].ambient[2] = v.ambient * 3.;
1060
1061 } /* Done with lights */
1062
1064
1065 } /* Done with file */
1066 return (1);
1067}
1068
1069/*!
1070 \brief Update no_zero ranges for attribute (actually no_null now)
1071
1072 \param gs pointer to geosurf struct
1073 \param desc attribute id (descriptor)
1074
1075 \return -1 on error
1076 \return 1 on success
1077 */
1078int Gs_update_attrange(geosurf *gs, int desc)
1079{
1080 size_t size;
1081 float min = 0.0;
1082 float max = 0.0;
1083 typbuff *tb;
1084 struct BM *nm;
1085 int found;
1086
1087 gs->att[desc].max_nz = gs->att[desc].min_nz = gs->att[desc].range_nz = 0.0;
1088
1089 if (CONST_ATT == gs_get_att_src(gs, desc)) {
1090 gs->att[desc].max_nz = gs->att[desc].min_nz = gs->att[desc].constant;
1091 min = max = gs->att[desc].constant;
1092 gs->att[desc].range_nz = 0.0;
1093 }
1094 else if (CF_COLOR_PACKED & gsds_get_changed(gs->att[desc].hdata)) {
1095 gs->att[desc].max_nz = 0xFFFFFF;
1096 gs->att[desc].min_nz = 0x010101;
1097 gs->att[desc].range_nz = 0xFFFFFF;
1098 }
1099 else {
1100 if (NULL == (tb = gsds_get_typbuff(gs->att[desc].hdata, 0))) {
1101 return (-1);
1102 }
1103
1104 nm = tb->nm;
1105
1106 if (tb->ib) {
1107 int *p;
1108
1109 size = (size_t)gs->rows * gs->cols;
1110 p = tb->ib;
1111 INIT_MINMAX(p, nm, size, min, max, found);
1112
1113 if (!found) {
1114 /* all nulls! */
1115 return (-1);
1116 }
1117
1118 size = (size_t)gs->rows * gs->cols;
1119 p = tb->ib;
1120 SET_MINMAX(p, nm, size, min, max);
1121 }
1122 else if (tb->sb) {
1123 short *p;
1124
1125 size = (size_t)gs->rows * gs->cols;
1126 p = tb->sb;
1127 INIT_MINMAX(p, nm, size, min, max, found);
1128
1129 if (!found) {
1130 /* all nulls! */
1131 return (-1);
1132 }
1133
1134 size = (size_t)gs->rows * gs->cols;
1135 p = tb->sb;
1136 SET_MINMAX(p, nm, size, min, max);
1137 }
1138 else if (tb->cb) {
1139 char *p;
1140
1141 size = (size_t)gs->rows * gs->cols;
1142 p = (char *)tb->cb;
1143 INIT_MINMAX(p, nm, size, min, max, found);
1144
1145 if (!found) {
1146 /* all nulls! */
1147 return (-1);
1148 }
1149
1150 size = (size_t)gs->rows * gs->cols;
1151 p = (char *)tb->cb;
1152 SET_MINMAX(p, nm, size, min, max);
1153 }
1154 else if (tb->fb) {
1155 float *p;
1156
1157 size = (size_t)gs->rows * gs->cols;
1158 p = tb->fb;
1159 INIT_MINMAX(p, nm, size, min, max, found);
1160
1161 if (!found) {
1162 /* all nulls! */
1163 return (-1);
1164 }
1165
1166 size = (size_t)gs->rows * gs->cols;
1167 p = tb->fb;
1168 SET_MINMAX(p, nm, size, min, max);
1169 }
1170
1171 gs->att[desc].max_nz = max;
1172 gs->att[desc].min_nz = min;
1173 gs->att[desc].range_nz = gs->att[desc].max_nz - gs->att[desc].min_nz;
1174 }
1175
1176 if (ATT_TOPO == desc) {
1177 gs->zmin = min;
1178 gs->zmax = max;
1179 gs->zrange = gs->zmax - gs->zmin;
1180 gs->zminmasked = gs->zmin;
1181 gs->zmax_nz = gs->zmax;
1182 gs->zmin_nz = gs->zmin;
1183 gs->zrange_nz = gs->zmax_nz - gs->zmin_nz;
1184 }
1185
1186 G_debug(3, "Gs_update_attrange(): min=%f max=%f", gs->zmin, gs->zmax);
1187
1188 return (1);
1189}
void G_free(void *buf)
Free allocated memory.
Definition alloc.c:150
int BM_set(struct BM *map, int x, int y, int val)
Sets bitmap value to 'val' at location 'x' 'y'.
Definition bitmap.c:185
#define NULL
Definition ccmath.h:32
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition debug.c:66
double b
double r
const char * G_find_file2(const char *element, const char *name, const char *mapset)
Searches for a file from the mapset search list or in a specified mapset. (look but don't touch)
Definition find_file.c:234
const char * G_find_raster2(const char *name, const char *mapset)
Find a raster map (look but don't touch)
Definition find_rast.c:76
int G_begin_distance_calculations(void)
Begin distance calculations.
double G_distance(double e1, double n1, double e2, double n2)
Returns distance in meters.
void G_message(const char *msg,...)
Print a message to stderr.
Definition gis/error.c:89
void G_warning(const char *msg,...)
Print a warning message to stderr.
Definition gis/error.c:203
int GS_setall_drawres(int xres, int yres, int xwire, int ywire)
Set all draw resolutions.
Definition gs2.c:2196
void GS_set_global_exag(float exag)
Set global z-exag value.
Definition gs2.c:1975
void GS_set_focus(float *realto)
Set focus.
Definition gs2.c:2517
void GS_alldraw_wire(void)
Draw all wires.
Definition gs2.c:1917
int GS_get_zrange(float *min, float *max, int doexag)
Get z-extent for all loaded surfaces.
Definition gs2.c:2685
int GS_setall_drawmode(int mode)
Set all draw-modes.
Definition gs2.c:2059
void GS_moveto_real(float *pt)
Move position to (real)
Definition gs2.c:2643
void GS_set_fov(int fov)
Set field of view.
Definition gs2.c:2838
void GS_set_twist(int t)
Set viewpoint twist value.
Definition gs2.c:2872
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:307
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_save_3dview(const char *vname, geoview *gv, geodisplay *gd UNUSED, struct Cell_head *w, geosurf *defsurf)
Save 3dview.
Definition gs3.c:846
int Gs_numtype(const char *filename, int *negflag)
Get map data type.
Definition gs3.c:225
void Gs_pack_colors(const char *filename, int *buff, int rows, int cols)
Pack color table.
Definition gs3.c:632
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:700
#define INIT_MINMAX(p, nm, size, min, max, found)
Used in the function Gs_update_attrange()
Definition gs3.c:35
int Gs_load_3dview(const char *vname, geoview *gv, geodisplay *gd UNUSED, struct Cell_head *w, const geosurf *defsurf)
Load 3dview.
Definition gs3.c:945
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:412
#define NO_DATA_COL
Definition gs3.c:66
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:770
#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:571
int Gs_update_attrange(geosurf *gs, int desc)
Update no_zero ranges for attribute (actually no_null now)
Definition gs3.c:1078
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:173
int gs_get_att_src(geosurf *gs, int desc)
Get attribute source.
Definition gs.c:656
void GS_v3mult(float *v1, float k)
Multiple vectors.
Definition gs_util.c:229
void GS_v3eq(float *v1, float *v2)
Copy vector values.
Definition gs_util.c:178
void gsd_model2real(Point3 point)
Convert model to real coordinates.
Definition gsd_views.c:393
typbuff * gsds_get_typbuff(int id, IFLAG change_flag)
Get data buffer.
Definition gsds.c:281
int gsds_get_changed(int id)
ADD.
Definition gsds.c:613
const char * G_mapset(void)
Get current mapset name.
Definition mapset.c:33
float g
Definition named_colr.c:7
char * G_fully_qualified_name(const char *name, const char *mapset)
Get fully qualified element name.
Definition nme_in_mps.c:101
void G_percent(long n, long d, int s)
Print percent complete messages.
Definition percent.c:61
#define min(a, b)
#define max(a, b)
int G_get_3dview(const char *fname, const char *mapset, struct G_3dview *View)
Gets a 3D View.
Definition view.c:243
int G_get_3dview_defaults(struct G_3dview *v, struct Cell_head *w)
Sets default for v based on w.
Definition view.c:58
int G_put_3dview(const char *fname, const struct G_3dview *View, const struct Cell_head *Win)
Saves info to a 3d.view file in the current mapset.
Definition view.c:163
#define X(j)
#define Y(j)
void G_zero(void *buf, int i)
Zero out a buffer, buf, of length i.
Definition zero.c:23