GRASS 8 Programmer's Manual 8.6.0dev(2026)-1878fdfec5
Loading...
Searching...
No Matches
view.c
Go to the documentation of this file.
1/*!
2 * \file lib/gis/view.c
3 *
4 * \brief GIS Library - 3D View functions.
5 *
6 * SPDX-FileCopyrightText: 2001-2014 GRASS Development Team
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 *
9 * \author Bill Brown - US Army CERL
10 *
11 * \date 1992-2008
12 */
13
14#include <stdio.h>
15#include <string.h>
16#include <stdlib.h>
17#include <grass/gis.h>
18#include <grass/glocale.h>
19
20#define REQ_KEYS 8
21
22static int compare_wind(const struct Cell_head *, const struct Cell_head *);
23static int get_bool(const char *);
24static void pr_winerr(int, const char *);
25static void edge_sort(float sides[4]);
26static int read_old_format(struct G_3dview *, FILE *);
27
28static const int vers_major = 4;
29static const int vers_minor = 1;
30
31static int Suppress_warn = 0;
32
33/**
34 * \brief Turns 3D View warnings on and off.
35 *
36 * If Suppress_warn is 0, a warning will be printed if less than 95% of
37 * the window when the view was saved overlaps the current window.
38 *
39 * \param[in] b
40 * \return
41 */
43{
44 Suppress_warn = b ? 0 : 1;
45}
46
47/**
48 * \brief Sets default for <b>v</b> based on <b>w</b>.
49 *
50 * \param[in,out] v
51 * \param[in] w
52 * \return always returns 1
53 */
54int G_get_3dview_defaults(struct G_3dview *v, struct Cell_head *w)
55{
56 if (!v || !w)
57 return (-1);
58
59 v->exag = 1.0;
60 v->fov = 40.0;
61 v->from_to[0][0] = (w->east + w->west) / 2.0;
62 v->from_to[0][1] = w->south - (w->north - w->south);
63 v->from_to[0][2] = w->north - w->south;
64 v->from_to[1][0] = (w->east + w->west) / 2.0;
65 v->from_to[1][1] = (w->north + w->south) / 2.0;
66 v->from_to[1][2] = 0.0;
67
68 v->twist = 0.0;
69 v->mesh_freq = 15;
70 v->poly_freq = 1;
71 v->display_type = 2;
72 v->colorgrid = v->fringe = v->surfonly = v->lightson = v->doavg = 0;
73 v->dozero = v->shading = 1;
74 strcpy(v->bg_col, "black");
75 strcpy(v->grid_col, "white");
76 strcpy(v->other_col, "red");
77 v->ambient = v->shine = 0.3;
78 v->lightcol[0] = v->lightcol[1] = v->lightcol[2] = 0.8;
79 v->lightpos[0] = w->west;
80 v->lightpos[1] = w->north;
81 v->lightpos[2] = (w->east - w->west) / 2.0;
82 v->lightpos[3] = 1.0; /* local source */
83
84 v->vwin.north = w->north;
85 v->vwin.south = w->south;
86 v->vwin.east = w->east;
87 v->vwin.west = w->west;
88 v->vwin.format = w->format;
89 v->vwin.compressed = w->compressed;
90 v->vwin.proj = w->proj;
91 v->vwin.zone = w->zone;
92 v->vwin.ew_res = w->ew_res;
93 v->vwin.ns_res = w->ns_res;
94 v->vwin.cols = w->cols;
95 v->vwin.rows = w->rows;
96
97 return (1);
98}
99
100/**
101 * \brief Saves info to a 3d.view file in the current mapset.
102 *
103 * The address of a window (struct Cell_head *) may be passed, or if
104 * NULL is passed, the Cell_head structure inside the G_3dview struct
105 * will be used. e.g., if you called <i>G_get_3dview_defaults</i> with
106 * the Cell_head you want saved, the G_3dview returned already contains
107 * the new Cell_head. But if you're using all the keywords, so didn't
108 * need defaults, pass this routine the address of a Cell_head.<br>
109 *
110 * User should call <i>G_get_3dview_defaults</i> before filling a
111 * G_3dview struct to be written if not using all of the optional
112 * keywords.<br>
113 *
114 * These keywords are constant in all 3d.view files:<br>
115 * PGM_ID<br>
116 * <b>cell keywords:</b><br>
117 * north<br>
118 * south<br>
119 * east<br>
120 * west<br>
121 * rows<br>
122 * cols<br>
123 * <b>required keywords:</b><br>
124 * TO_EASTING<br>
125 * TO_NORTHING<br>
126 * TO_HEIGHT<br>
127 * FROM_EASTING<br>
128 * FROM_NORTHING<br>
129 * FROM_HEIGHT<br>
130 * Z_EXAG<br>
131 * FIELD_VIEW<br>
132 * <b>optional keywords:</b> (defaults provided when reading)<br>
133 * TWIST<br>
134 * MESH_FREQ<br>
135 * POLY_RES<br>
136 * DOAVG<br>
137 * DISPLAY_TYPE<br>
138 * DOZERO<br>
139 * COLORGRID<br>
140 * SHADING<br>
141 * FRINGE<br>
142 * BG_COL<br>
143 * GRID_COL<br>
144 * OTHER_COL<br>
145 * LIGHTS_ON<br>
146 * LIGHTPOS<br>
147 * LIGHTCOL<br>
148 * LIGHTAMBIENT<br>
149 * SHINE<br>
150 * SURFACEONLY<br>
151 *
152 * \param[in] fname file name
153 * \param[in] View
154 * \param[in] Win
155 * \return 1 on success
156 * \return -1 on error
157 */
158int G_put_3dview(const char *fname, const struct G_3dview *View,
159 const struct Cell_head *Win)
160{
161 FILE *fp;
162
163 if (NULL == (fp = G_fopen_new("3d.view", fname))) {
164 G_warning(_("Unable to open %s for writing"), fname);
165 return (-1);
166 }
167
168 fprintf(fp, "# %01d.%02d\n", vers_major, vers_minor);
169 fprintf(fp, "PGM_ID: %s\n", View->pgm_id);
170
171 if (Win) {
172 fprintf(fp, "north: %f\n", Win->north);
173 fprintf(fp, "south: %f\n", Win->south);
174 fprintf(fp, "east: %f\n", Win->east);
175 fprintf(fp, "west: %f\n", Win->west);
176 fprintf(fp, "rows: %d\n", Win->rows);
177 fprintf(fp, "cols: %d\n", Win->cols);
178 }
179 else {
180 fprintf(fp, "north: %f\n", View->vwin.north);
181 fprintf(fp, "south: %f\n", View->vwin.south);
182 fprintf(fp, "east: %f\n", View->vwin.east);
183 fprintf(fp, "west: %f\n", View->vwin.west);
184 fprintf(fp, "rows: %d\n", View->vwin.rows);
185 fprintf(fp, "cols: %d\n", View->vwin.cols);
186 }
187
188 fprintf(fp, "TO_EASTING: %f\n", View->from_to[1][0]);
189 fprintf(fp, "TO_NORTHING: %f\n", View->from_to[1][1]);
190 fprintf(fp, "TO_HEIGHT: %f\n", View->from_to[1][2]);
191 fprintf(fp, "FROM_EASTING: %f\n", View->from_to[0][0]);
192 fprintf(fp, "FROM_NORTHING: %f\n", View->from_to[0][1]);
193 fprintf(fp, "FROM_HEIGHT: %f\n", View->from_to[0][2]);
194 fprintf(fp, "Z_EXAG: %f\n", View->exag);
195 fprintf(fp, "TWIST: %f\n", View->twist);
196 fprintf(fp, "FIELD_VIEW: %f\n", View->fov);
197 fprintf(fp, "MESH_FREQ: %d\n", View->mesh_freq);
198 fprintf(fp, "POLY_RES: %d\n", View->poly_freq);
199 fprintf(fp, "DOAVG: %d\n", View->doavg);
200 fprintf(fp, "DISPLAY_TYPE: %d\n", View->display_type);
201 fprintf(fp, "DOZERO: %d\n", View->dozero);
202
203 fprintf(fp, "COLORGRID: %d\n", View->colorgrid); /* 1 = use color */
204 fprintf(fp, "SHADING: %d\n", View->shading);
205 fprintf(fp, "FRINGE: %d\n", View->fringe);
206 fprintf(fp, "BG_COL: %s\n", View->bg_col);
207 fprintf(fp, "GRID_COL: %s\n", View->grid_col);
208 fprintf(fp, "OTHER_COL: %s\n", View->other_col);
209 fprintf(fp, "SURFACEONLY: %d\n", View->surfonly);
210 fprintf(fp, "LIGHTS_ON: %d\n", View->lightson);
211 fprintf(fp, "LIGHTPOS: %f %f %f %f\n", View->lightpos[0], View->lightpos[1],
212 View->lightpos[2], View->lightpos[3]);
213 fprintf(fp, "LIGHTCOL: %f %f %f\n", View->lightcol[0], View->lightcol[1],
214 View->lightcol[2]);
215 fprintf(fp, "LIGHTAMBIENT: %f\n", View->ambient);
216 fprintf(fp, "SHINE: %f\n", View->shine);
217
218 fclose(fp);
219
220 return (1);
221}
222
223/**
224 * \brief Gets a 3D View.
225 *
226 * If reading an old format, the window boundaries are not checked
227 * against the current window since boundaries weren't saved.
228 *
229 * \param[in] fname
230 * \param[in] mapset
231 * \param[in,out] View
232 * \return -1 on error
233 * \return 1 on success
234 * \return 2 if <b>fname</b> was written with this version of routine
235 * \return 0 if is older format (through 4.0)
236 */
237int G_get_3dview(const char *fname, const char *mapset, struct G_3dview *View)
238{
239 struct Cell_head curwin;
240 FILE *fp;
241 char buffer[80], keystring[24], boo[8], nbuf[128], ebuf[128];
242 int lap, v_maj, v_min, wind_keys = 0, reqkeys = 0;
243 int current = 0; /* current version flag */
244
245 mapset = G_find_file2("3d.view", fname, mapset);
246 if (mapset != NULL) {
247 if (NULL == (fp = G_fopen_old("3d.view", fname, mapset))) {
248 G_warning(_("Unable to open %s for reading"), fname);
249 return (-1);
250 }
251
254
255 if (NULL != fgets(buffer, 80, fp)) {
256 if (buffer[0] != '#') { /* old d.3d format */
257 rewind(fp);
258 if (0 <= read_old_format(View, fp))
259 return (0);
260 else
261 return (-1);
262 }
263 else {
264 sscanf(buffer, "#%d.%d\n", &v_maj, &v_min);
265 if (v_maj == vers_major && v_min == vers_minor)
266 current = 1; /* same version */
267 }
268 }
269
270 while (NULL != fgets(buffer, 75, fp)) {
271 if (buffer[0] != '#') {
272
273 sscanf(buffer, "%[^:]:", keystring);
274
275 if (!strcmp(keystring, "PGM_ID")) {
276 sscanf(buffer, "%*s%s", (View->pgm_id));
277 continue;
278 }
279 if (!strcmp(keystring, "north")) {
280 sscanf(buffer, "%*s%lf", &(View->vwin.north));
281 ++wind_keys;
282 continue;
283 }
284 if (!strcmp(keystring, "south")) {
285 sscanf(buffer, "%*s%lf", &(View->vwin.south));
286 ++wind_keys;
287 continue;
288 }
289 if (!strcmp(keystring, "east")) {
290 sscanf(buffer, "%*s%lf", &(View->vwin.east));
291 ++wind_keys;
292 continue;
293 }
294 if (!strcmp(keystring, "west")) {
295 sscanf(buffer, "%*s%lf", &(View->vwin.west));
296 ++wind_keys;
297 continue;
298 }
299 if (!strcmp(keystring, "rows")) {
300 sscanf(buffer, "%*s%d", &(View->vwin.rows));
301 ++wind_keys;
302 continue;
303 }
304 if (!strcmp(keystring, "cols")) {
305 sscanf(buffer, "%*s%d", &(View->vwin.cols));
306 ++wind_keys;
307 continue;
308 }
309 if (!strcmp(keystring, "TO_EASTING")) {
310 sscanf(buffer, "%*s%f", &(View->from_to[1][0]));
311 ++reqkeys;
312 continue;
313 }
314 if (!strcmp(keystring, "TO_NORTHING")) {
315 sscanf(buffer, "%*s%f", &(View->from_to[1][1]));
316 ++reqkeys;
317 continue;
318 }
319 if (!strcmp(keystring, "TO_HEIGHT")) {
320 sscanf(buffer, "%*s%f", &(View->from_to[1][2]));
321 ++reqkeys;
322 continue;
323 }
324 if (!strcmp(keystring, "FROM_EASTING")) {
325 sscanf(buffer, "%*s%f", &(View->from_to[0][0]));
326 ++reqkeys;
327 continue;
328 }
329 if (!strcmp(keystring, "FROM_NORTHING")) {
330 sscanf(buffer, "%*s%f", &(View->from_to[0][1]));
331 ++reqkeys;
332 continue;
333 }
334 if (!strcmp(keystring, "FROM_HEIGHT")) {
335 sscanf(buffer, "%*s%f", &(View->from_to[0][2]));
336 ++reqkeys;
337 continue;
338 }
339 if (!strcmp(keystring, "Z_EXAG")) {
340 sscanf(buffer, "%*s%f", &(View->exag));
341 ++reqkeys;
342 continue;
343 }
344 if (!strcmp(keystring, "MESH_FREQ")) {
345 sscanf(buffer, "%*s%d", &(View->mesh_freq));
346 continue;
347 }
348 if (!strcmp(keystring, "POLY_RES")) {
349 sscanf(buffer, "%*s%d", &(View->poly_freq));
350 continue;
351 }
352 if (!strcmp(keystring, "DOAVG")) {
353 sscanf(buffer, "%*s%d", &(View->doavg));
354 continue;
355 }
356 if (!strcmp(keystring, "FIELD_VIEW")) {
357 sscanf(buffer, "%*s%f", &(View->fov));
358 ++reqkeys;
359 continue;
360 }
361 if (!strcmp(keystring, "TWIST")) {
362 sscanf(buffer, "%*s%f", &(View->twist));
363 continue;
364 }
365 if (!strcmp(keystring, "DISPLAY_TYPE")) {
366 sscanf(buffer, "%*s%d", &View->display_type);
367 continue;
368 }
369 if (!strcmp(keystring, "DOZERO")) {
370 sscanf(buffer, "%*s%s", boo);
371 View->dozero = get_bool(boo);
372 continue;
373 }
374 if (!strcmp(keystring, "COLORGRID")) {
375 sscanf(buffer, "%*s%s", boo);
376 View->colorgrid = get_bool(boo);
377 continue;
378 }
379 if (!strcmp(keystring, "FRINGE")) {
380 sscanf(buffer, "%*s%s", boo);
381 View->fringe = get_bool(boo);
382 continue;
383 }
384 if (!strcmp(keystring, "SHADING")) {
385 sscanf(buffer, "%*s%s", boo);
386 View->shading = get_bool(boo);
387 continue;
388 }
389 if (!strcmp(keystring, "BG_COL")) {
390 sscanf(buffer, "%*s%s", View->bg_col);
391 continue;
392 }
393 if (!strcmp(keystring, "GRID_COL")) {
394 sscanf(buffer, "%*s%s", View->grid_col);
395 continue;
396 }
397 if (!strcmp(keystring, "OTHER_COL")) {
398 sscanf(buffer, "%*s%s", View->other_col);
399 continue;
400 }
401 if (!strcmp(keystring, "SURFACEONLY")) {
402 sscanf(buffer, "%*s%s", boo);
403 View->surfonly = get_bool(boo);
404 continue;
405 }
406 if (!strcmp(keystring, "LIGHTS_ON")) {
407 sscanf(buffer, "%*s%s", boo);
408 View->lightson = get_bool(boo);
409 continue;
410 }
411 if (!strcmp(keystring, "LIGHTPOS")) {
412 sscanf(buffer, "%*s%f%f%f%f", &(View->lightpos[0]),
413 &(View->lightpos[1]), &(View->lightpos[2]),
414 &(View->lightpos[3]));
415 continue;
416 }
417 if (!strcmp(keystring, "LIGHTCOL")) {
418 sscanf(buffer, "%*s%f%f%f", &(View->lightcol[0]),
419 &(View->lightcol[1]), &(View->lightcol[2]));
420 continue;
421 }
422 if (!strcmp(keystring, "LIGHTAMBIENT")) {
423 sscanf(buffer, "%*s%f", &(View->ambient));
424 continue;
425 }
426 if (!strcmp(keystring, "SHINE")) {
427 sscanf(buffer, "%*s%f", &(View->shine));
428 continue;
429 }
430 }
431 }
432
433 fclose(fp);
434
435 if (reqkeys != REQ_KEYS) /* required keys not found */
436 return (-1);
437
438 /* fill rest of View->vwin */
439 if (wind_keys == 6) {
440 View->vwin.ew_res =
441 (View->vwin.east - View->vwin.west) / View->vwin.cols;
442 View->vwin.ns_res =
443 (View->vwin.north - View->vwin.south) / View->vwin.rows;
444 }
445 else
446 return (0); /* older format */
447
448 if (!Suppress_warn) {
449 if (95 > (lap = compare_wind(&(View->vwin), &curwin))) {
450
451 fprintf(stderr, _("GRASS window when view was saved:\n"));
452 G_format_northing(View->vwin.north, nbuf, G_projection());
453 fprintf(stderr, "north: %s\n", nbuf);
454 G_format_northing(View->vwin.south, nbuf, G_projection());
455 fprintf(stderr, "south: %s\n", nbuf);
456 G_format_easting(View->vwin.east, ebuf, G_projection());
457 fprintf(stderr, "east: %s\n", ebuf);
458 G_format_easting(View->vwin.west, ebuf, G_projection());
459 fprintf(stderr, "west: %s\n", ebuf);
460 pr_winerr(lap, fname);
461 }
462 }
463 }
464 else {
465 G_warning(_("Unable to open %s for reading"), fname);
466 return (-1);
467 }
468
469 if (current)
470 return (2);
471
472 return (1);
473}
474
475/* returns the percentage of savedwin that overlaps curwin */
476
477static int compare_wind(const struct Cell_head *savedwin,
478 const struct Cell_head *curwin)
479{
480 float e_ings[4], n_ings[4], area_lap, area_saved;
481 int outside = 0;
482
483 if (savedwin->north < curwin->south)
484 outside = 1;
485 if (savedwin->south > curwin->north)
486 outside = 1;
487 if (savedwin->east < curwin->west)
488 outside = 1;
489 if (savedwin->west > curwin->east)
490 outside = 1;
491 if (outside)
492 return (0);
493
494 e_ings[0] = savedwin->west;
495 e_ings[1] = savedwin->east;
496 e_ings[2] = curwin->west;
497 e_ings[3] = curwin->east;
498 edge_sort(e_ings);
499
500 n_ings[0] = savedwin->south;
501 n_ings[1] = savedwin->north;
502 n_ings[2] = curwin->south;
503 n_ings[3] = curwin->north;
504 edge_sort(n_ings);
505
506 area_lap = (e_ings[2] - e_ings[1]) * (n_ings[2] - n_ings[1]);
507 area_saved =
508 (savedwin->east - savedwin->west) * (savedwin->north - savedwin->south);
509
510 return ((int)(area_lap * 100.0 / area_saved));
511}
512
513static int get_bool(const char *str)
514{
515 if (str[0] == 'y' || str[0] == 'Y')
516 return (1);
517 if (str[0] == 'n' || str[0] == 'N')
518 return (0);
519
520 return (atoi(str) ? 1 : 0);
521}
522
523static void
524pr_winerr(int vis, /* % of saved window overlapping current window */
525 const char *viewname)
526{
527 switch (vis) {
528 case 0:
529 G_warning(_(" Window saved in \"%s\" is completely outside of current "
530 "GRASS window."),
531 viewname);
532 break;
533 default:
534 G_warning(_(" Only %d%% of window saved in \"%s\" overlaps with "
535 "current GRASS window."),
536 vis, viewname);
537 break;
538 }
539}
540
541/*********************************************************************/
542/* sorts 4 floats from lowest to highest */
543
544static void edge_sort(float sides[4])
545{
546 int i, j;
547 float temp;
548
549 for (i = 0; i < 4; ++i) {
550 for (j = i + 1; j < 4; ++j) {
551 if (sides[j] < sides[i]) { /* then swap */
552 temp = sides[i];
553 sides[i] = sides[j];
554 sides[j] = temp;
555 }
556 }
557 }
558}
559
560static int read_old_format(struct G_3dview *v, FILE *fp)
561{
562 char buffer[80];
563 int req_keys = 0;
564 double td;
565 char boo[8];
566
567 strcpy((v->pgm_id), "d.3d");
568 if (1 == sscanf(fgets(buffer, 80, fp), "%f", &(v->from_to[1][0])))
569 ++req_keys;
570 if (1 == sscanf(fgets(buffer, 80, fp), "%f", &(v->from_to[1][1])))
571 ++req_keys;
572 if (1 == sscanf(fgets(buffer, 80, fp), "%f", &(v->from_to[1][2])))
573 ++req_keys;
574 if (1 == sscanf(fgets(buffer, 80, fp), "%f", &(v->from_to[0][0])))
575 ++req_keys;
576 if (1 == sscanf(fgets(buffer, 80, fp), "%f", &(v->from_to[0][1])))
577 ++req_keys;
578 if (1 == sscanf(fgets(buffer, 80, fp), "%f", &(v->from_to[0][2])))
579 ++req_keys;
580 if (1 == sscanf(fgets(buffer, 80, fp), "%f", &(v->exag)))
581 ++req_keys;
582 sscanf(fgets(buffer, 80, fp), "%d", &(v->mesh_freq));
583 if (1 == sscanf(fgets(buffer, 80, fp), "%f", &(v->fov)))
584 ++req_keys;
585 if (1 == sscanf(fgets(buffer, 80, fp), "%lf", &td)) { /* resolution */
586 v->vwin.rows = (v->vwin.north - v->vwin.south) / td;
587 v->vwin.cols = (v->vwin.east - v->vwin.west) / td;
588 v->vwin.ew_res = v->vwin.ns_res = td;
589 }
590
591 sscanf(fgets(buffer, 80, fp), "%s", boo); /* linesonly */
592 v->display_type = get_bool(boo) ? 1 : 3;
593 sscanf(fgets(buffer, 80, fp), "%s", boo);
594 v->dozero = get_bool(boo);
595 sscanf(fgets(buffer, 80, fp), "%s", v->grid_col);
596 if (!strcmp(v->grid_col, "color"))
597 v->colorgrid = 1;
598
599 sscanf(fgets(buffer, 80, fp), "%s", v->other_col);
600 sscanf(fgets(buffer, 80, fp), "%s", v->bg_col);
601 sscanf(fgets(buffer, 80, fp), "%s", boo);
602 v->doavg = get_bool(boo);
603
604 if (v->exag) { /* old 3d.view files saved height with no exag */
605 v->from_to[0][2] /= v->exag;
606 v->from_to[1][2] /= v->exag;
607 }
608
609 fclose(fp);
610 if (req_keys == REQ_KEYS)
611 return (1);
612 else
613 return (-1);
614}
#define NULL
Definition ccmath.h:32
void G_warning(const char *,...) __attribute__((format(printf
FILE * G_fopen_new(const char *, const char *)
Open a new database file.
Definition gis/open.c:218
void G_get_set_window(struct Cell_head *)
Get the current working window (region)
FILE * G_fopen_old(const char *, const char *, const char *)
Open a database file for reading.
Definition gis/open.c:250
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
void G_format_easting(double, char *, int)
Easting to ASCII.
Definition wind_format.c:47
int G_projection(void)
Query cartographic projection.
Definition proj1.c:30
void G_format_northing(double, char *, int)
Northing to ASCII.
Definition wind_format.c:27
#define _(str)
Definition glocale.h:10
#define strcpy
Definition parson.c:66
double b
Definition r_raster.c:37
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 north
Extent coordinates (north)
Definition gis.h:489
int compressed
Compression mode (raster header only)
Definition gis.h:456
int format
Max number of bytes per raster data value minus 1 (raster header only)
Definition gis.h:449
int zone
Projection zone (UTM)
Definition gis.h:477
double east
Extent coordinates (east)
Definition gis.h:493
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
int proj
Projection code.
Definition gis.h:475
double south
Extent coordinates (south)
Definition gis.h:491
double west
Extent coordinates (west)
Definition gis.h:495
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
char other_col[40]
Definition gis.h:523
int colorgrid
Definition gis.h:516
char bg_col[40]
Definition gis.h:522
char grid_col[40]
Definition gis.h:521
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
int doavg
Definition gis.h:520
int G_get_3dview(const char *fname, const char *mapset, struct G_3dview *View)
Gets a 3D View.
Definition view.c:237
void G_3dview_warning(int b)
Turns 3D View warnings on and off.
Definition view.c:42
int G_get_3dview_defaults(struct G_3dview *v, struct Cell_head *w)
Sets default for v based on w.
Definition view.c:54
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:158
#define REQ_KEYS
Definition view.c:20