view.c 17 KB

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