main.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /****************************************************************************
  2. *
  3. * MODULE: r3.mkdspf
  4. * AUTHOR(S): Helena Mitasova and Bill Brown (original contributor)
  5. * Roberto Flor <flor itc.it>, Bernhard Reiter <bernhard intevation.de>,
  6. * Brad Douglas <rez touchofmadness.com>, Glynn Clements <glynn gclements.plus.com>,
  7. * Radim Blazek <radim.blazek gmail.com>, Markus Neteler <neteler itc.it>
  8. * PURPOSE:
  9. * COPYRIGHT: (C) 2000-2006 by the GRASS Development Team
  10. *
  11. * This program is free software under the GNU General Public
  12. * License (>=v2). Read the file COPYING that comes with GRASS
  13. * for details.
  14. *
  15. *****************************************************************************/
  16. /* This program implements the marching cubes surface tiler described by
  17. * Lorenson & Cline in the Siggraph 87 Conference Proceedings.
  18. *
  19. * This program reads in data from a grid3 formatted file containing 3D data
  20. * and creates a display file.
  21. *
  22. * The display file consists of cell_info structures.
  23. * The cell_info structure:
  24. * threshold (specified on commandline)
  25. * number of polygons
  26. * polygon vertice coordinates
  27. * surface or vertex normals (depending on lighting model specified)
  28. *
  29. * The user must specify the data file name and the thresholds and lighting
  30. * model desired.
  31. *
  32. * Based on a program outline written by Mike Krogh, NCSA, Feb.,1990
  33. *
  34. * written by Jan Moorman for D. Lawrance, Mednet NCSA.
  35. * rewritten for CERL, August 1990
  36. *
  37. * rewritten by Bill Brown
  38. * for UI Geographic Modeling Systems Laboratory February 1996
  39. * to use new GRASS 3dgrid data files & API
  40. */
  41. #include <stdlib.h>
  42. #include <math.h>
  43. #include "vizual.h"
  44. #include <grass/gis.h>
  45. #include <grass/raster3d.h>
  46. #include "local_proto.h"
  47. #include <grass/glocale.h>
  48. file_info Headfax; /* contains info about command line */
  49. Cube_data CUBE; /* and the data for a single cube */
  50. int NTHRESH;
  51. int main(int argc, char *argv[])
  52. {
  53. char element[GNAME_MAX+10];
  54. const char *dspout;
  55. void *g3map;
  56. RASTER3D_Region g3reg;
  57. const char *mapset;
  58. double dmin, dmax;
  59. struct GModule *module;
  60. struct Option *levels;
  61. struct Option *out;
  62. struct Option *min;
  63. struct Option *max;
  64. struct Option *step;
  65. struct Option *tnum;
  66. struct Option *name;
  67. struct Flag *shade;
  68. struct Flag *quiet;
  69. G_gisinit(argv[0]);
  70. module = G_define_module();
  71. G_add_keyword(_("raster3d"));
  72. G_add_keyword(_("display"));
  73. G_add_keyword(_("voxel"));
  74. module->description =
  75. _("Creates a display file from an existing 3D raster map according to specified threshold levels.");
  76. name = G_define_option();
  77. name->key = "input";
  78. name->type = TYPE_STRING;
  79. name->required = YES;
  80. name->gisprompt = "old,grid3,3d-raster";
  81. /* should still find the DIRECTORY */
  82. name->description = _("Name of an existing 3D raster map");
  83. out = G_define_standard_option(G_OPT_F_OUTPUT);
  84. out->key = "dspf";
  85. out->required = YES;
  86. out->description = _("Name for output display file");
  87. levels = G_define_option();
  88. levels->key = "levels";
  89. levels->type = TYPE_DOUBLE;
  90. levels->required = NO;
  91. levels->multiple = YES;
  92. levels->description = _("List of thresholds for isosurfaces");
  93. min = G_define_option();
  94. min->key = "min";
  95. min->type = TYPE_DOUBLE;
  96. min->required = NO;
  97. min->description = _("Minimum isosurface level");
  98. max = G_define_option();
  99. max->key = "max";
  100. max->type = TYPE_DOUBLE;
  101. max->required = NO;
  102. max->description = _("Maximum isosurface level");
  103. step = G_define_option();
  104. step->key = "step";
  105. step->type = TYPE_DOUBLE;
  106. step->required = NO;
  107. step->description = _("Positive increment between isosurface levels");
  108. tnum = G_define_option();
  109. tnum->key = "tnum";
  110. tnum->type = TYPE_INTEGER;
  111. tnum->required = NO;
  112. tnum->answer = "7";
  113. tnum->description = _("Number of isosurface threshold levels");
  114. quiet = G_define_flag();
  115. quiet->key = 'q';
  116. quiet->description = _("Suppress progress report & min/max information");
  117. shade = G_define_flag();
  118. shade->key = 'f';
  119. shade->description = _("Use flat shading rather than gradient");
  120. if (G_parser(argc, argv))
  121. exit(EXIT_FAILURE);
  122. Rast3d_init_defaults();
  123. Rast3d_get_window(&g3reg);
  124. G_message(_("Region from getWindow: %d %d %d"),
  125. g3reg.rows, g3reg.cols, g3reg.depths);
  126. if (NULL ==
  127. (dspout =
  128. check_get_any_dspname(out->answer, name->answer, G_mapset())))
  129. exit(EXIT_FAILURE);
  130. Rast3d_set_error_fun(Rast3d_print_error);
  131. /* open g3 file for reading and writing */
  132. if (NULL == (mapset = G_find_file2("grid3", name->answer, "")))
  133. G_fatal_error(_("Not able to find grid3 file for [%s]"),
  134. name->answer);
  135. g3map = Rast3d_open_cell_old(name->answer, mapset, &g3reg,
  136. RASTER3D_TILE_SAME_AS_FILE, RASTER3D_USE_CACHE_DEFAULT);
  137. /*
  138. g3map = Rast3d_open_cell_old (name->answer, mapset, RASTER3D_DEFAULT_WINDOW,
  139. RASTER3D_TILE_SAME_AS_FILE,
  140. RASTER3D_USE_CACHE_DEFAULT);
  141. */
  142. if (NULL == g3map)
  143. G_fatal_error(_("Unable to open 3D raster map <%s>"), name->answer);
  144. if (0 == Rast3d_range_load(g3map))
  145. G_fatal_error(_("Unable to read range of 3D raster map <%s>"), name->answer);
  146. /* TODO: look at this - should use current 3dregion rather than
  147. region represented by original 3dgrid file */
  148. /*
  149. Rast3d_get_region_struct_map (g3map, &g3reg);
  150. */
  151. /* DONT USE Headfax any more ?
  152. g3read_header(&Headfax);
  153. */
  154. Rast3d_range_min_max(g3map, &dmin, &dmax);
  155. viz_make_header(&Headfax, dmin, dmax, &g3reg);
  156. /* puts command line options into cmndln_info structure */
  157. /* need to send it answers */
  158. viz_calc_tvals(&Headfax.linefax, levels->answers, min->answer,
  159. max->answer, step->answer, tnum->answer,
  160. quiet->answer ? 1 : 0);
  161. if (shade->answer) {
  162. Headfax.linefax.litmodel = 1; /* flat */
  163. }
  164. else
  165. Headfax.linefax.litmodel = 2; /* gradient */
  166. /* open display file for writing */
  167. sprintf(element, "grid3/%s/dsp", name->answer);
  168. if ((Headfax.dspfoutfp = G_fopen_new(element, dspout)) == NULL)
  169. G_fatal_error(_("Unable to open display file <%s>"), dspout);
  170. /* write display file header info */
  171. /* have to adjust dimensions -dpg */
  172. {
  173. Headfax.xdim -= 1;
  174. Headfax.ydim -= 1;
  175. Headfax.zdim -= 1;
  176. G_message("DSPF DIMS: %d %d %d", Headfax.ydim + 1, Headfax.xdim + 1,
  177. Headfax.zdim + 1);
  178. if (dfwrite_header(&Headfax) < 0) {
  179. fclose(Headfax.dspfoutfp);
  180. exit(EXIT_FAILURE);
  181. }
  182. Headfax.xdim += 1;
  183. Headfax.ydim += 1;
  184. Headfax.zdim += 1;
  185. }
  186. if (!quiet->answer)
  187. G_message(_("Writing %s from %s..."), dspout, name->answer);
  188. viz_iso_surface(g3map, &g3reg, &Headfax.linefax, quiet->answer ? 1 : 0);
  189. if (!quiet->answer)
  190. fprintf(stderr, "\n");
  191. /* tries to write a header! */
  192. Rast3d_close(g3map);
  193. fclose(Headfax.dspfoutfp);
  194. exit(EXIT_SUCCESS);
  195. }