main.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  1. /****************************************************************************
  2. *
  3. * MODULE: r3.out.vtk
  4. *
  5. * AUTHOR(S): Original author
  6. * Soeren Gebbert soerengebbert at gmx de
  7. * 27 Feb 2006 Berlin
  8. * PURPOSE: Converts 3D raster maps (RASTER3D) into the VTK-Ascii format
  9. *
  10. * COPYRIGHT: (C) 2005 by the GRASS Development Team
  11. *
  12. * This program is free software under the GNU General Public
  13. * License (>=v2). Read the file COPYING that comes with GRASS
  14. * for details.
  15. *
  16. *****************************************************************************/
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <grass/gis.h>
  21. #include <grass/raster.h>
  22. #include <grass/raster3d.h>
  23. #include <grass/glocale.h>
  24. #include "globalDefs.h"
  25. #include "parameters.h"
  26. #include "writeVTKData.h"
  27. #include "writeVTKHead.h"
  28. #include "errorHandling.h"
  29. paramType param; /*Parameters */
  30. double x_extent;
  31. double y_extent;
  32. /** prototypes ***************************************************************/
  33. /*Open the rgb voxel maps and write the data to the output */
  34. static void open_write_rgb_maps(input_maps * in, RASTER3D_Region region, FILE * fp,
  35. int dp);
  36. /*Open the rgb voxel maps and write the data to the output */
  37. static void open_write_vector_maps(input_maps * in, RASTER3D_Region region,
  38. FILE * fp, int dp);
  39. /*opens a raster input map */
  40. static int open_input_map(const char *name, const char *mapset);
  41. /*Check if all maps are available */
  42. static void check_input_maps(void);
  43. /*Initiate the input maps structure */
  44. static input_maps *create_input_maps_struct(void);
  45. /* ************************************************************************* */
  46. /* Open the raster input map *********************************************** */
  47. /* ************************************************************************* */
  48. input_maps *create_input_maps_struct(void)
  49. {
  50. input_maps *in;
  51. in = (input_maps *) calloc(1, sizeof (input_maps));
  52. in->map = NULL;
  53. in->map_r = NULL;
  54. in->map_g = NULL;
  55. in->map_b = NULL;
  56. in->map_x = NULL;
  57. in->map_y = NULL;
  58. in->map_z = NULL;
  59. in->top = -1;
  60. in->bottom = -1;
  61. in->topMapType = 0;
  62. in->bottomMapType = 0;
  63. in->elevmaps = NULL;
  64. in->elevmaptypes = NULL;
  65. in->numelevmaps = 0;
  66. return in;
  67. }
  68. /* ************************************************************************* */
  69. /* Open the raster input map *********************************************** */
  70. /* ************************************************************************* */
  71. int open_input_map(const char *name, const char *mapset)
  72. {
  73. G_debug(3, "Open raster file %s in mapset %s", name, mapset);
  74. /* open raster map */
  75. return Rast_open_old(name, mapset);
  76. }
  77. /* ************************************************************************* */
  78. /* Check the input maps **************************************************** */
  79. /* ************************************************************************* */
  80. void check_input_maps(void)
  81. {
  82. int i = 0;
  83. const char *mapset, *name;
  84. /*Check top and bottom if surface is requested */
  85. if (param.structgrid->answer) {
  86. if (!param.top->answer || !param.bottom->answer)
  87. Rast3d_fatal_error(_("Specify top and bottom map"));
  88. mapset = NULL;
  89. name = NULL;
  90. name = param.top->answer;
  91. mapset = G_find_raster2(name, "");
  92. if (mapset == NULL) {
  93. Rast3d_fatal_error(_("Top cell map <%s> not found"),
  94. param.top->answer);
  95. }
  96. mapset = NULL;
  97. name = NULL;
  98. name = param.bottom->answer;
  99. mapset = G_find_raster2(name, "");
  100. if (mapset == NULL) {
  101. Rast3d_fatal_error(_("Bottom cell map <%s> not found"),
  102. param.bottom->answer);
  103. }
  104. }
  105. /*If input maps are provided, check them */
  106. if (param.input->answers != NULL) {
  107. for (i = 0; param.input->answers[i] != NULL; i++) {
  108. if (NULL == G_find_raster3d(param.input->answers[i], ""))
  109. Rast3d_fatal_error(_("3D raster map <%s> not found"),
  110. param.input->answers[i]);
  111. }
  112. }
  113. /*Check for rgb maps. */
  114. if (param.rgbmaps->answers != NULL) {
  115. for (i = 0; i < 3; i++) {
  116. if (param.rgbmaps->answers[i] != NULL) {
  117. if (NULL == G_find_raster3d(param.rgbmaps->answers[i], ""))
  118. Rast3d_fatal_error(_("3D raster map RGB map <%s> not found"),
  119. param.rgbmaps->answers[i]);
  120. } else {
  121. Rast3d_fatal_error(_("Please provide three RGB 3D raster maps"));
  122. }
  123. }
  124. }
  125. /*Check for vector maps. */
  126. if (param.vectormaps->answers != NULL) {
  127. for (i = 0; i < 3; i++) {
  128. if (param.vectormaps->answers[i] != NULL) {
  129. if (NULL == G_find_raster3d(param.vectormaps->answers[i], ""))
  130. Rast3d_fatal_error(_("3D vector map <%s> not found"),
  131. param.vectormaps->answers[i]);
  132. } else {
  133. Rast3d_fatal_error(_("Please provide three 3D raster maps for the xyz-vector maps [x,y,z]"));
  134. }
  135. }
  136. }
  137. if (param.input->answers == NULL && param.rgbmaps->answers == NULL &&
  138. param.vectormaps->answers == NULL) {
  139. G_warning(_("No 3D raster data, RGB or xyz-vector maps are provided! Will only write the geometry."));
  140. }
  141. return;
  142. }
  143. /* ************************************************************************* */
  144. /* Prepare the VTK RGB voxel data for writing ****************************** */
  145. /* ************************************************************************* */
  146. void open_write_rgb_maps(input_maps * in, RASTER3D_Region region, FILE * fp,
  147. int dp)
  148. {
  149. int i, changemask[3] = {0, 0, 0};
  150. void *maprgb = NULL;
  151. if (param.rgbmaps->answers != NULL) {
  152. /*Loop over all input maps! */
  153. for (i = 0; i < 3; i++) {
  154. G_debug(3, "Open RGB 3D raster map <%s>",
  155. param.rgbmaps->answers[i]);
  156. maprgb = NULL;
  157. /*Open the map */
  158. maprgb =
  159. Rast3d_open_cell_old(param.rgbmaps->answers[i],
  160. G_find_raster3d(param.rgbmaps->answers[i], ""),
  161. &region, RASTER3D_TILE_SAME_AS_FILE,
  162. RASTER3D_USE_CACHE_DEFAULT);
  163. if (maprgb == NULL) {
  164. G_warning(_("Unable to open 3D raster map <%s>"),
  165. param.rgbmaps->answers[i]);
  166. fatal_error(_("No RGB Data will be created."), in);
  167. }
  168. /*if requested set the Mask on */
  169. if (param.mask->answer) {
  170. if (Rast3d_mask_file_exists()) {
  171. changemask[i] = 0;
  172. if (Rast3d_mask_is_off(maprgb)) {
  173. Rast3d_mask_on(maprgb);
  174. changemask[i] = 1;
  175. }
  176. }
  177. }
  178. if (i == 0)
  179. in->map_r = maprgb;
  180. if (i == 1)
  181. in->map_g = maprgb;
  182. if (i == 2)
  183. in->map_b = maprgb;
  184. }
  185. G_debug(3, "Writing VTK VoxelData");
  186. write_vtk_rgb_data(in->map_r, in->map_g, in->map_b, fp, "RGB_Voxel",
  187. region, dp);
  188. for (i = 0; i < 3; i++) {
  189. if (i == 0)
  190. maprgb = in->map_r;
  191. if (i == 1)
  192. maprgb = in->map_g;
  193. if (i == 2)
  194. maprgb = in->map_b;
  195. /*We set the Mask off, if it was off before */
  196. if (param.mask->answer) {
  197. if (Rast3d_mask_file_exists())
  198. if (Rast3d_mask_is_on(maprgb) && changemask[i])
  199. Rast3d_mask_off(maprgb);
  200. }
  201. /* Close the 3d raster map */
  202. if (!Rast3d_close(maprgb)) {
  203. fatal_error(_("Unable to close 3D raster map"), in);
  204. }
  205. /*Set the pointer to null so we noe later that these files are already closed */
  206. if (i == 0)
  207. in->map_r = NULL;
  208. if (i == 1)
  209. in->map_g = NULL;
  210. if (i == 2)
  211. in->map_b = NULL;
  212. }
  213. }
  214. return;
  215. }
  216. /* ************************************************************************* */
  217. /* Prepare the VTK vector data for writing ********************************* */
  218. /* ************************************************************************* */
  219. void open_write_vector_maps(input_maps * in, RASTER3D_Region region, FILE * fp,
  220. int dp)
  221. {
  222. int i, changemask[3] = {0, 0, 0};
  223. void *mapvect = NULL;
  224. if (param.vectormaps->answers != NULL) {
  225. /*Loop over all input maps! */
  226. for (i = 0; i < 3; i++) {
  227. G_debug(3, "Open vector 3D raster map <%s>",
  228. param.vectormaps->answers[i]);
  229. mapvect = NULL;
  230. /*Open the map */
  231. mapvect =
  232. Rast3d_open_cell_old(param.vectormaps->answers[i],
  233. G_find_raster3d(param.vectormaps->answers[i],
  234. ""), &region,
  235. RASTER3D_TILE_SAME_AS_FILE, RASTER3D_USE_CACHE_DEFAULT);
  236. if (mapvect == NULL) {
  237. G_warning(_("Unable to open 3D raster map <%s>"),
  238. param.vectormaps->answers[i]);
  239. fatal_error(_("No vector data will be created."), in);
  240. }
  241. /*if requested set the Mask on */
  242. if (param.mask->answer) {
  243. if (Rast3d_mask_file_exists()) {
  244. changemask[i] = 0;
  245. if (Rast3d_mask_is_off(mapvect)) {
  246. Rast3d_mask_on(mapvect);
  247. changemask[i] = 1;
  248. }
  249. }
  250. }
  251. if (i == 0)
  252. in->map_x = mapvect;
  253. if (i == 1)
  254. in->map_y = mapvect;
  255. if (i == 2)
  256. in->map_z = mapvect;
  257. }
  258. G_debug(3, "Writing VTK Vector Data");
  259. write_vtk_vector_data(in->map_x, in->map_y, in->map_z, fp,
  260. "Vector_Data", region, dp);
  261. for (i = 0; i < 3; i++) {
  262. if (i == 0)
  263. mapvect = in->map_x;
  264. if (i == 1)
  265. mapvect = in->map_y;
  266. if (i == 2)
  267. mapvect = in->map_z;
  268. /*We set the Mask off, if it was off before */
  269. if (param.mask->answer) {
  270. if (Rast3d_mask_file_exists())
  271. if (Rast3d_mask_is_on(mapvect) && changemask[i])
  272. Rast3d_mask_off(mapvect);
  273. }
  274. /* Close the 3d raster map */
  275. if (!Rast3d_close(mapvect)) {
  276. fatal_error(_("Unable to close 3D raster map"), in);
  277. }
  278. /*Set the pointer to null so we know later that these files are already closed */
  279. if (i == 0)
  280. in->map_x = NULL;
  281. if (i == 1)
  282. in->map_y = NULL;
  283. if (i == 2)
  284. in->map_z = NULL;
  285. }
  286. }
  287. return;
  288. }
  289. /* ************************************************************************* */
  290. /* Main function, opens most of the input and output files ***************** */
  291. /* ************************************************************************* */
  292. int main(int argc, char *argv[])
  293. {
  294. char *output = NULL;
  295. RASTER3D_Region region;
  296. struct Cell_head window2d;
  297. struct Cell_head default_region;
  298. FILE *fp = NULL;
  299. struct GModule *module;
  300. int dp, i, changemask = 0;
  301. int rows, cols;
  302. const char *mapset, *name;
  303. double scale = 1.0, llscale = 1.0;
  304. input_maps *in;
  305. /* Initialize GRASS */
  306. G_gisinit(argv[0]);
  307. module = G_define_module();
  308. G_add_keyword(_("raster3d"));
  309. G_add_keyword(_("export"));
  310. G_add_keyword(_("voxel"));
  311. G_add_keyword("VTK");
  312. module->description =
  313. _("Converts 3D raster maps into the VTK-ASCII format.");
  314. /* Get parameters from user */
  315. set_params();
  316. /* Have GRASS get inputs */
  317. if (G_parser(argc, argv))
  318. exit(EXIT_FAILURE);
  319. /*The precision of the output */
  320. if (param.decimals->answer) {
  321. if (sscanf(param.decimals->answer, "%d", &dp) != 1)
  322. G_fatal_error(_("failed to interpret dp as an integer"));
  323. if (dp > 20 || dp < 0)
  324. G_fatal_error(_("dp has to be from 0 to 20"));
  325. } else {
  326. dp = 8; /*This value is taken from the lib settings in G_format_easting */
  327. }
  328. /*Check the input */
  329. check_input_maps();
  330. /*Correct the coordinates, so the precision of VTK is not hurt :( */
  331. if (param.coorcorr->answer) {
  332. /*Get the default region for coordiante correction */
  333. G_get_default_window(&default_region);
  334. /*Use the center of the current region as extent */
  335. y_extent = (default_region.north + default_region.south) / 2;
  336. x_extent = (default_region.west + default_region.east) / 2;
  337. } else {
  338. x_extent = 0;
  339. y_extent = 0;
  340. }
  341. /*open the output */
  342. if (param.output->answer) {
  343. fp = fopen(param.output->answer, "w");
  344. if (fp == NULL) {
  345. perror(param.output->answer);
  346. G_usage();
  347. exit(EXIT_FAILURE);
  348. }
  349. } else
  350. fp = stdout;
  351. /* Figure out the region from the map */
  352. Rast3d_init_defaults();
  353. Rast3d_get_window(&region);
  354. /*initiate the input mpas structure */
  355. in = create_input_maps_struct();
  356. /* read and compute the scale factor */
  357. sscanf(param.elevscale->answer, "%lf", &scale);
  358. /*if LL projection, convert the elevation values to degrees */
  359. if (param.scalell->answer && region.proj == PROJECTION_LL) {
  360. llscale = M_PI / (180) * 6378137;
  361. scale /= llscale;
  362. }
  363. /*Open the top and bottom file */
  364. if (param.structgrid->answer) {
  365. /*Check if the g3d-region is equal to the 2d rows and cols */
  366. rows = Rast_window_rows();
  367. cols = Rast_window_cols();
  368. /*If not equal, set the 2D windows correct */
  369. if (rows != region.rows || cols != region.cols) {
  370. G_message(_("The 2D and 3D region settings are different. "
  371. "Using the 2D window settings to adjust the 2D part of the 3D region."));
  372. G_get_set_window(&window2d);
  373. window2d.ns_res = region.ns_res;
  374. window2d.ew_res = region.ew_res;
  375. window2d.rows = region.rows;
  376. window2d.cols = region.cols;
  377. Rast_set_window(&window2d);
  378. }
  379. /*open top */
  380. mapset = NULL;
  381. name = NULL;
  382. name = param.top->answer;
  383. mapset = G_find_raster2(name, "");
  384. in->top = open_input_map(name, mapset);
  385. in->topMapType = Rast_get_map_type(in->top);
  386. /*open bottom */
  387. mapset = NULL;
  388. name = NULL;
  389. name = param.bottom->answer;
  390. mapset = G_find_raster2(name, "");
  391. in->bottom = open_input_map(name, mapset);
  392. in->bottomMapType = Rast_get_map_type(in->bottom);
  393. /* Write the vtk-header and the points */
  394. if (param.point->answer) {
  395. write_vtk_structured_grid_header(fp, output, region);
  396. write_vtk_points(in, fp, region, dp, 1, scale);
  397. } else {
  398. write_vtk_unstructured_grid_header(fp, output, region);
  399. write_vtk_points(in, fp, region, dp, 0, scale);
  400. write_vtk_unstructured_grid_cells(fp, region);
  401. }
  402. Rast_close(in->top);
  403. in->top = -1;
  404. Rast_close(in->bottom);
  405. in->bottom = -1;
  406. } else {
  407. /* Write the structured point vtk-header */
  408. write_vtk_structured_point_header(fp, output, region, dp, scale);
  409. }
  410. /*Write the normal VTK data (cell or point data) */
  411. /*Loop over all 3d input maps! */
  412. if (param.input->answers != NULL) {
  413. for (i = 0; param.input->answers[i] != NULL; i++) {
  414. G_debug(3, "Open 3D raster map <%s>", param.input->answers[i]);
  415. /*Open the map */
  416. in->map =
  417. Rast3d_open_cell_old(param.input->answers[i],
  418. G_find_raster3d(param.input->answers[i], ""),
  419. &region, RASTER3D_TILE_SAME_AS_FILE,
  420. RASTER3D_USE_CACHE_DEFAULT);
  421. if (in->map == NULL) {
  422. G_warning(_("Unable to open 3D raster map <%s>"),
  423. param.input->answers[i]);
  424. fatal_error(" ", in);
  425. }
  426. /*if requested set the Mask on */
  427. if (param.mask->answer) {
  428. if (Rast3d_mask_file_exists()) {
  429. changemask = 0;
  430. if (Rast3d_mask_is_off(in->map)) {
  431. Rast3d_mask_on(in->map);
  432. changemask = 1;
  433. }
  434. }
  435. }
  436. /* Write the point or cell data */
  437. write_vtk_data(fp, in->map, region, param.input->answers[i], dp);
  438. /*We set the Mask off, if it was off before */
  439. if (param.mask->answer) {
  440. if (Rast3d_mask_file_exists())
  441. if (Rast3d_mask_is_on(in->map) && changemask)
  442. Rast3d_mask_off(in->map);
  443. }
  444. /* Close the 3d raster map */
  445. if (!Rast3d_close(in->map)) {
  446. in->map = NULL;
  447. fatal_error(_("Unable to close 3D raster map, the VTK file may be incomplete"),
  448. in);
  449. }
  450. in->map = NULL;
  451. }
  452. }
  453. /*Write the RGB voxel data */
  454. open_write_rgb_maps(in, region, fp, dp);
  455. open_write_vector_maps(in, region, fp, dp);
  456. /*Close the output file */
  457. if (param.output->answer && fp != NULL)
  458. if (fclose(fp))
  459. fatal_error(_("Unable to close VTK-ASCII file"), in);
  460. /*close all open maps and free memory */
  461. release_input_maps_struct(in);
  462. return 0;
  463. }