00001
00017 #include <stdio.h>
00018 #include <string.h>
00019 #include <stdlib.h>
00020 #include <grass/gis.h>
00021 #include <grass/glocale.h>
00022
00023
00024 #define REQ_KEYS 8
00025
00026 static int compare_wind(const struct Cell_head *, const struct Cell_head *);
00027 static int get_bool(const char *);
00028 static void pr_winerr(int, const char *);
00029 static void edge_sort(float sides[4]);
00030 static int read_old_format(struct G_3dview *, FILE *);
00031
00032 static int vers_major = 4;
00033 static int vers_minor = 1;
00034 static int Suppress_warn = 0;
00035
00036
00047 int G_3dview_warning(int b)
00048 {
00049 Suppress_warn = b ? 0 : 1;
00050
00051 return 0;
00052 }
00053
00054
00063 int G_get_3dview_defaults(struct G_3dview *v, struct Cell_head *w)
00064 {
00065 if (!v || !w)
00066 return (-1);
00067
00068 v->exag = 1.0;
00069 v->fov = 40.0;
00070 v->from_to[0][0] = (w->east + w->west) / 2.0;
00071 v->from_to[0][1] = w->south - (w->north - w->south);
00072 v->from_to[0][2] = w->north - w->south;
00073 v->from_to[1][0] = (w->east + w->west) / 2.0;
00074 v->from_to[1][1] = (w->north + w->south) / 2.0;
00075 v->from_to[1][2] = 0.0;
00076
00077 v->twist = 0.0;
00078 v->mesh_freq = 15;
00079 v->poly_freq = 1;
00080 v->display_type = 2;
00081 v->colorgrid = v->fringe = v->surfonly = v->lightson = v->doavg = 0;
00082 v->dozero = v->shading = 1;
00083 strcpy(v->bg_col, "black");
00084 strcpy(v->grid_col, "white");
00085 strcpy(v->other_col, "red");
00086 v->ambient = v->shine = 0.3;
00087 v->lightcol[0] = v->lightcol[1] = v->lightcol[2] = 0.8;
00088 v->lightpos[0] = w->west;
00089 v->lightpos[1] = w->north;
00090 v->lightpos[2] = (w->east - w->west) / 2.0;
00091 v->lightpos[3] = 1.0;
00092
00093 v->vwin.north = w->north;
00094 v->vwin.south = w->south;
00095 v->vwin.east = w->east;
00096 v->vwin.west = w->west;
00097 v->vwin.format = w->format;
00098 v->vwin.compressed = w->compressed;
00099 v->vwin.proj = w->proj;
00100 v->vwin.zone = w->zone;
00101 v->vwin.ew_res = w->ew_res;
00102 v->vwin.ns_res = w->ns_res;
00103 v->vwin.cols = w->cols;
00104 v->vwin.rows = w->rows;
00105
00106 return (1);
00107
00108 }
00109
00110
00171 int G_put_3dview(const char *fname, const char *mapset,
00172 const struct G_3dview *View, const struct Cell_head *Win)
00173 {
00174 FILE *fp;
00175
00176 if (NULL == (fp = G_fopen_new("3d.view", fname))) {
00177 G_warning(_("Unable to open %s for writing"), fname);
00178 return (-1);
00179 }
00180
00181 fprintf(fp, "# %01d.%02d\n", vers_major, vers_minor);
00182 fprintf(fp, "PGM_ID: %s\n", View->pgm_id);
00183
00184 if (Win) {
00185 fprintf(fp, "north: %f\n", Win->north);
00186 fprintf(fp, "south: %f\n", Win->south);
00187 fprintf(fp, "east: %f\n", Win->east);
00188 fprintf(fp, "west: %f\n", Win->west);
00189 fprintf(fp, "rows: %d\n", Win->rows);
00190 fprintf(fp, "cols: %d\n", Win->cols);
00191 }
00192 else {
00193 fprintf(fp, "north: %f\n", View->vwin.north);
00194 fprintf(fp, "south: %f\n", View->vwin.south);
00195 fprintf(fp, "east: %f\n", View->vwin.east);
00196 fprintf(fp, "west: %f\n", View->vwin.west);
00197 fprintf(fp, "rows: %d\n", View->vwin.rows);
00198 fprintf(fp, "cols: %d\n", View->vwin.cols);
00199 }
00200
00201 fprintf(fp, "TO_EASTING: %f\n", View->from_to[1][0]);
00202 fprintf(fp, "TO_NORTHING: %f\n", View->from_to[1][1]);
00203 fprintf(fp, "TO_HEIGHT: %f\n", View->from_to[1][2]);
00204 fprintf(fp, "FROM_EASTING: %f\n", View->from_to[0][0]);
00205 fprintf(fp, "FROM_NORTHING: %f\n", View->from_to[0][1]);
00206 fprintf(fp, "FROM_HEIGHT: %f\n", View->from_to[0][2]);
00207 fprintf(fp, "Z_EXAG: %f\n", View->exag);
00208 fprintf(fp, "TWIST: %f\n", View->twist);
00209 fprintf(fp, "FIELD_VIEW: %f\n", View->fov);
00210 fprintf(fp, "MESH_FREQ: %d\n", View->mesh_freq);
00211 fprintf(fp, "POLY_RES: %d\n", View->poly_freq);
00212 fprintf(fp, "DOAVG: %d\n", View->doavg);
00213 fprintf(fp, "DISPLAY_TYPE: %d\n", View->display_type);
00214 fprintf(fp, "DOZERO: %d\n", View->dozero);
00215
00216 fprintf(fp, "COLORGRID: %d\n", View->colorgrid);
00217 fprintf(fp, "SHADING: %d\n", View->shading);
00218 fprintf(fp, "FRINGE: %d\n", View->fringe);
00219 fprintf(fp, "BG_COL: %s\n", View->bg_col);
00220 fprintf(fp, "GRID_COL: %s\n", View->grid_col);
00221 fprintf(fp, "OTHER_COL: %s\n", View->other_col);
00222 fprintf(fp, "SURFACEONLY: %d\n", View->surfonly);
00223 fprintf(fp, "LIGHTS_ON: %d\n", View->lightson);
00224 fprintf(fp, "LIGHTPOS: %f %f %f %f\n", View->lightpos[0],
00225 View->lightpos[1], View->lightpos[2], View->lightpos[3]);
00226 fprintf(fp, "LIGHTCOL: %f %f %f\n", View->lightcol[0], View->lightcol[1],
00227 View->lightcol[2]);
00228 fprintf(fp, "LIGHTAMBIENT: %f\n", View->ambient);
00229 fprintf(fp, "SHINE: %f\n", View->shine);
00230
00231 fclose(fp);
00232
00233 return (1);
00234 }
00235
00236
00252 int G_get_3dview(const char *fname, const char *mapset, struct G_3dview *View)
00253 {
00254 struct Cell_head curwin;
00255 FILE *fp;
00256 char buffer[80], keystring[24], boo[8], nbuf[128], ebuf[128];
00257 int lap, v_maj, v_min, wind_keys = 0, reqkeys = 0;
00258 int current = 0;
00259
00260 mapset = G_find_file2("3d.view", fname, mapset);
00261 if (mapset != NULL) {
00262 if (NULL == (fp = G_fopen_old("3d.view", fname, mapset))) {
00263 G_warning(_("Unable to open %s for reading"), fname);
00264 return (-1);
00265 }
00266
00267 G_get_set_window(&curwin);
00268 G_get_3dview_defaults(View, &curwin);
00269
00270 if (NULL != fgets(buffer, 80, fp)) {
00271 if (buffer[0] != '#') {
00272 rewind(fp);
00273 if (0 <= read_old_format(View, fp))
00274 return (0);
00275 else
00276 return (-1);
00277 }
00278 else {
00279 sscanf(buffer, "#%d.%d\n", &v_maj, &v_min);
00280 if (v_maj == vers_major && v_min == vers_minor)
00281 current = 1;
00282 }
00283 }
00284
00285 while (NULL != fgets(buffer, 75, fp)) {
00286 if (buffer[0] != '#') {
00287
00288 sscanf(buffer, "%[^:]:", keystring);
00289
00290 if (!strcmp(keystring, "PGM_ID")) {
00291 sscanf(buffer, "%*s%s", (View->pgm_id));
00292 continue;
00293 }
00294 if (!strcmp(keystring, "north")) {
00295 sscanf(buffer, "%*s%lf", &(View->vwin.north));
00296 ++wind_keys;
00297 continue;
00298 }
00299 if (!strcmp(keystring, "south")) {
00300 sscanf(buffer, "%*s%lf", &(View->vwin.south));
00301 ++wind_keys;
00302 continue;
00303 }
00304 if (!strcmp(keystring, "east")) {
00305 sscanf(buffer, "%*s%lf", &(View->vwin.east));
00306 ++wind_keys;
00307 continue;
00308 }
00309 if (!strcmp(keystring, "west")) {
00310 sscanf(buffer, "%*s%lf", &(View->vwin.west));
00311 ++wind_keys;
00312 continue;
00313 }
00314 if (!strcmp(keystring, "rows")) {
00315 sscanf(buffer, "%*s%d", &(View->vwin.rows));
00316 ++wind_keys;
00317 continue;
00318 }
00319 if (!strcmp(keystring, "cols")) {
00320 sscanf(buffer, "%*s%d", &(View->vwin.cols));
00321 ++wind_keys;
00322 continue;
00323 }
00324 if (!strcmp(keystring, "TO_EASTING")) {
00325 sscanf(buffer, "%*s%f", &(View->from_to[1][0]));
00326 ++reqkeys;
00327 continue;
00328 }
00329 if (!strcmp(keystring, "TO_NORTHING")) {
00330 sscanf(buffer, "%*s%f", &(View->from_to[1][1]));
00331 ++reqkeys;
00332 continue;
00333 }
00334 if (!strcmp(keystring, "TO_HEIGHT")) {
00335 sscanf(buffer, "%*s%f", &(View->from_to[1][2]));
00336 ++reqkeys;
00337 continue;
00338 }
00339 if (!strcmp(keystring, "FROM_EASTING")) {
00340 sscanf(buffer, "%*s%f", &(View->from_to[0][0]));
00341 ++reqkeys;
00342 continue;
00343 }
00344 if (!strcmp(keystring, "FROM_NORTHING")) {
00345 sscanf(buffer, "%*s%f", &(View->from_to[0][1]));
00346 ++reqkeys;
00347 continue;
00348 }
00349 if (!strcmp(keystring, "FROM_HEIGHT")) {
00350 sscanf(buffer, "%*s%f", &(View->from_to[0][2]));
00351 ++reqkeys;
00352 continue;
00353 }
00354 if (!strcmp(keystring, "Z_EXAG")) {
00355 sscanf(buffer, "%*s%f", &(View->exag));
00356 ++reqkeys;
00357 continue;
00358 }
00359 if (!strcmp(keystring, "MESH_FREQ")) {
00360 sscanf(buffer, "%*s%d", &(View->mesh_freq));
00361 continue;
00362 }
00363 if (!strcmp(keystring, "POLY_RES")) {
00364 sscanf(buffer, "%*s%d", &(View->poly_freq));
00365 continue;
00366 }
00367 if (!strcmp(keystring, "DOAVG")) {
00368 sscanf(buffer, "%*s%d", &(View->doavg));
00369 continue;
00370 }
00371 if (!strcmp(keystring, "FIELD_VIEW")) {
00372 sscanf(buffer, "%*s%f", &(View->fov));
00373 ++reqkeys;
00374 continue;
00375 }
00376 if (!strcmp(keystring, "TWIST")) {
00377 sscanf(buffer, "%*s%f", &(View->twist));
00378 continue;
00379 }
00380 if (!strcmp(keystring, "DISPLAY_TYPE")) {
00381 sscanf(buffer, "%*s%d", &View->display_type);
00382 continue;
00383 }
00384 if (!strcmp(keystring, "DOZERO")) {
00385 sscanf(buffer, "%*s%s", boo);
00386 View->dozero = get_bool(boo);
00387 continue;
00388 }
00389 if (!strcmp(keystring, "COLORGRID")) {
00390 sscanf(buffer, "%*s%s", boo);
00391 View->colorgrid = get_bool(boo);
00392 continue;
00393 }
00394 if (!strcmp(keystring, "FRINGE")) {
00395 sscanf(buffer, "%*s%s", boo);
00396 View->fringe = get_bool(boo);
00397 continue;
00398 }
00399 if (!strcmp(keystring, "SHADING")) {
00400 sscanf(buffer, "%*s%s", boo);
00401 View->shading = get_bool(boo);
00402 continue;
00403 }
00404 if (!strcmp(keystring, "BG_COL")) {
00405 sscanf(buffer, "%*s%s", View->bg_col);
00406 continue;
00407 }
00408 if (!strcmp(keystring, "GRID_COL")) {
00409 sscanf(buffer, "%*s%s", View->grid_col);
00410 continue;
00411 }
00412 if (!strcmp(keystring, "OTHER_COL")) {
00413 sscanf(buffer, "%*s%s", View->other_col);
00414 continue;
00415 }
00416 if (!strcmp(keystring, "SURFACEONLY")) {
00417 sscanf(buffer, "%*s%s", boo);
00418 View->surfonly = get_bool(boo);
00419 continue;
00420 }
00421 if (!strcmp(keystring, "LIGHTS_ON")) {
00422 sscanf(buffer, "%*s%s", boo);
00423 View->lightson = get_bool(boo);
00424 continue;
00425 }
00426 if (!strcmp(keystring, "LIGHTPOS")) {
00427 sscanf(buffer, "%*s%f%f%f%f", &(View->lightpos[0]),
00428 &(View->lightpos[1]), &(View->lightpos[2]),
00429 &(View->lightpos[3]));
00430 continue;
00431 }
00432 if (!strcmp(keystring, "LIGHTCOL")) {
00433 sscanf(buffer, "%*s%f%f%f", &(View->lightcol[0]),
00434 &(View->lightcol[1]), &(View->lightcol[2]));
00435 continue;
00436 }
00437 if (!strcmp(keystring, "LIGHTAMBIENT")) {
00438 sscanf(buffer, "%*s%f", &(View->ambient));
00439 continue;
00440 }
00441 if (!strcmp(keystring, "SHINE")) {
00442 sscanf(buffer, "%*s%f", &(View->shine));
00443 continue;
00444 }
00445 }
00446 }
00447
00448 fclose(fp);
00449
00450 if (reqkeys != REQ_KEYS)
00451 return (-1);
00452
00453
00454 if (wind_keys == 6) {
00455 View->vwin.ew_res = (View->vwin.east - View->vwin.west) /
00456 View->vwin.cols;
00457 View->vwin.ns_res = (View->vwin.north - View->vwin.south) /
00458 View->vwin.rows;
00459 }
00460 else
00461 return (0);
00462
00463 if (!Suppress_warn) {
00464 if (95 > (lap = compare_wind(&(View->vwin), &curwin))) {
00465
00466 fprintf(stderr, _("GRASS window when view was saved:\n"));
00467 G_format_northing(View->vwin.north, nbuf, G_projection());
00468 fprintf(stderr, "north: %s\n", nbuf);
00469 G_format_northing(View->vwin.south, nbuf, G_projection());
00470 fprintf(stderr, "south: %s\n", nbuf);
00471 G_format_easting(View->vwin.east, ebuf, G_projection());
00472 fprintf(stderr, "east: %s\n", ebuf);
00473 G_format_easting(View->vwin.west, ebuf, G_projection());
00474 fprintf(stderr, "west: %s\n", ebuf);
00475 pr_winerr(lap, fname);
00476 }
00477 }
00478 }
00479 else {
00480 G_warning(_("Unable to open %s for reading"), fname);
00481 return (-1);
00482 }
00483
00484 if (current)
00485 return (2);
00486
00487 return (1);
00488 }
00489
00490
00491
00492
00493 static int compare_wind(const struct Cell_head *savedwin,
00494 const struct Cell_head *curwin)
00495 {
00496 float e_ings[4], n_ings[4], area_lap, area_saved;
00497 int outside = 0;
00498
00499 if (savedwin->north < curwin->south)
00500 outside = 1;
00501 if (savedwin->south > curwin->north)
00502 outside = 1;
00503 if (savedwin->east < curwin->west)
00504 outside = 1;
00505 if (savedwin->west > curwin->east)
00506 outside = 1;
00507 if (outside)
00508 return (0);
00509
00510 e_ings[0] = savedwin->west;
00511 e_ings[1] = savedwin->east;
00512 e_ings[2] = curwin->west;
00513 e_ings[3] = curwin->east;
00514 edge_sort(e_ings);
00515
00516 n_ings[0] = savedwin->south;
00517 n_ings[1] = savedwin->north;
00518 n_ings[2] = curwin->south;
00519 n_ings[3] = curwin->north;
00520 edge_sort(n_ings);
00521
00522 area_lap = (e_ings[2] - e_ings[1]) * (n_ings[2] - n_ings[1]);
00523 area_saved = (savedwin->east - savedwin->west) *
00524 (savedwin->north - savedwin->south);
00525
00526 return ((int)(area_lap * 100.0 / area_saved));
00527 }
00528
00529
00530 static int get_bool(const char *str)
00531 {
00532 if (str[0] == 'y' || str[0] == 'Y')
00533 return (1);
00534 if (str[0] == 'n' || str[0] == 'N')
00535 return (0);
00536
00537 return (atoi(str) ? 1 : 0);
00538 }
00539
00540
00541 static void pr_winerr(int vis,
00542 const char *viewname)
00543 {
00544 switch (vis) {
00545 case 0:
00546 G_warning(_(" Window saved in \"%s\" is completely outside of current GRASS window."),
00547 viewname);
00548 break;
00549 default:
00550 G_warning(_(" Only %d%% of window saved in \"%s\" overlaps with current GRASS window."),
00551 vis, viewname);
00552 break;
00553 }
00554 }
00555
00556
00557
00558
00559 static void edge_sort(float sides[4])
00560 {
00561 int i, j;
00562 float temp;
00563
00564 for (i = 0; i < 4; ++i) {
00565 for (j = i + 1; j < 4; ++j) {
00566 if (sides[j] < sides[i]) {
00567 temp = sides[i];
00568 sides[i] = sides[j];
00569 sides[j] = temp;
00570 }
00571 }
00572 }
00573 }
00574
00575
00576 static int read_old_format(struct G_3dview *v, FILE * fp)
00577 {
00578 char buffer[80];
00579 int req_keys = 0;
00580 double td;
00581 char boo[8];
00582
00583 strcpy((v->pgm_id), "d.3d");
00584 if (1 == sscanf(fgets(buffer, 80, fp), "%f", &(v->from_to[1][0])))
00585 ++req_keys;
00586 if (1 == sscanf(fgets(buffer, 80, fp), "%f", &(v->from_to[1][1])))
00587 ++req_keys;
00588 if (1 == sscanf(fgets(buffer, 80, fp), "%f", &(v->from_to[1][2])))
00589 ++req_keys;
00590 if (1 == sscanf(fgets(buffer, 80, fp), "%f", &(v->from_to[0][0])))
00591 ++req_keys;
00592 if (1 == sscanf(fgets(buffer, 80, fp), "%f", &(v->from_to[0][1])))
00593 ++req_keys;
00594 if (1 == sscanf(fgets(buffer, 80, fp), "%f", &(v->from_to[0][2])))
00595 ++req_keys;
00596 if (1 == sscanf(fgets(buffer, 80, fp), "%f", &(v->exag)))
00597 ++req_keys;
00598 sscanf(fgets(buffer, 80, fp), "%d", &(v->mesh_freq));
00599 if (1 == sscanf(fgets(buffer, 80, fp), "%f", &(v->fov)))
00600 ++req_keys;
00601 if (1 == sscanf(fgets(buffer, 80, fp), "%lf", &td)) {
00602 v->vwin.rows = (v->vwin.north - v->vwin.south) / td;
00603 v->vwin.cols = (v->vwin.east - v->vwin.west) / td;
00604 v->vwin.ew_res = v->vwin.ns_res = td;
00605 }
00606
00607 sscanf(fgets(buffer, 80, fp), "%s", boo);
00608 v->display_type = get_bool(boo) ? 1 : 3;
00609 sscanf(fgets(buffer, 80, fp), "%s", boo);
00610 v->dozero = get_bool(boo);
00611 sscanf(fgets(buffer, 80, fp), "%s", v->grid_col);
00612 if (!strcmp(v->grid_col, "color"))
00613 v->colorgrid = 1;
00614
00615 sscanf(fgets(buffer, 80, fp), "%s", v->other_col);
00616 sscanf(fgets(buffer, 80, fp), "%s", v->bg_col);
00617 sscanf(fgets(buffer, 80, fp), "%s", boo);
00618 v->doavg = get_bool(boo);
00619
00620 if (v->exag) {
00621 v->from_to[0][2] /= v->exag;
00622 v->from_to[1][2] /= v->exag;
00623 }
00624
00625
00626 fclose(fp);
00627 if (req_keys == REQ_KEYS)
00628 return (1);
00629 else
00630 return (-1);
00631 }