gvld.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892
  1. /*!
  2. \file lib/ogsf/gvld.c
  3. \brief OGSF library - loading and manipulating volumes (lower level functions)
  4. GRASS OpenGL gsurf OGSF Library
  5. (C) 1999-2008 by the GRASS Development Team
  6. This program is free software under the
  7. GNU General Public License (>=v2).
  8. Read the file COPYING that comes with GRASS
  9. for details.
  10. \author Tomas Paudits (February 2004)
  11. \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
  12. */
  13. #include <math.h>
  14. #include <grass/gis.h>
  15. #include <grass/ogsf.h>
  16. #include "mc33_table.h"
  17. /* usefull macros */
  18. #define READ() gvl_read_char(pos[i]++, gvl->isosurf[i]->data)
  19. /*!
  20. \brief Draw volume set (slices and isosurfaces)
  21. \param gvl pointer to geovol struct
  22. \return -1 on failure
  23. \return 1 on success
  24. */
  25. int gvld_vol(geovol *gvl)
  26. {
  27. G_debug(5, "gvld_vol(): id=%d", gvl->gvol_id);
  28. /* SLICES */
  29. /* calculate slices data, if slices changed */
  30. if (0 > gvl_slices_calc(gvl))
  31. return (-1);
  32. /* draw slices */
  33. if (0 > gvld_slices(gvl))
  34. return (-1);
  35. /* ISOSURFACES */
  36. /* calculate isosurfaces data, if isosurfaces changed */
  37. if (0 > gvl_isosurf_calc(gvl))
  38. return (-1);
  39. /* draw isosurfaces */
  40. if (0 > gvld_isosurf(gvl))
  41. return (-1);
  42. return (1);
  43. }
  44. /*!
  45. \brief Draw volume in wire mode (bounding box)
  46. \param gvl pointer to geovol struct
  47. \return -1 on failure
  48. \return 1 on success
  49. */
  50. int gvld_wire_vol(geovol * gvl)
  51. {
  52. G_debug(5, "gvld_wire_vol(): id=%d", gvl->gvol_id);
  53. gvld_wind3_box(gvl);
  54. if (0 > gvld_wire_slices(gvl))
  55. return (-1);
  56. if (0 > gvld_wire_isosurf(gvl))
  57. return (-1);
  58. return (1);
  59. }
  60. /*!
  61. \brief Draw volume isosurfaces
  62. \param gvl pointer to geovol struct
  63. \return -1 on failure
  64. \return 1 on success
  65. */
  66. int gvld_isosurf(geovol * gvl)
  67. {
  68. float tx, ty, tz;
  69. int cols, rows, depths;
  70. int x, y, z, i, iv;
  71. float xc, yc, zc;
  72. float xres, yres, zres;
  73. unsigned r, g, b;
  74. int j, p, num, c_ndx, crnt_ev;
  75. float n[3], pt[4];
  76. int n_i = gvl->n_isosurfs;
  77. int *check_color, *check_transp, *check_material, *check_emis,
  78. *check_shin;
  79. float *kem, *ksh, pkem, pksh;
  80. unsigned int *ktrans, *curcolor;
  81. int pktransp = 0;
  82. int *pos, *nz, *e_dl, tmp_pos, edge_pos[13];
  83. GLdouble modelMatrix[16], projMatrix[16];
  84. GLint viewport[4];
  85. GLint window[4];
  86. geovol_isosurf *isosurf;
  87. /* Allocate memory for arrays */
  88. check_color = G_malloc(n_i * sizeof(int));
  89. check_transp = G_malloc(n_i * sizeof(int));
  90. check_material = G_malloc(n_i * sizeof(int));
  91. check_emis = G_malloc(n_i * sizeof(int));
  92. check_shin = G_malloc(n_i * sizeof(int));
  93. kem = G_malloc(n_i * sizeof(float));
  94. ksh = G_malloc(n_i * sizeof(float));
  95. ktrans = G_malloc(n_i * sizeof(unsigned int));
  96. curcolor = G_malloc(n_i * sizeof(unsigned int));
  97. pos = G_malloc(n_i * sizeof(int));
  98. nz = G_malloc(n_i * sizeof(int));
  99. e_dl = G_malloc(n_i * sizeof(int));
  100. G_debug(5, "gvld_isosurf():");
  101. for (i = 0; i < gvl->n_isosurfs; i++) {
  102. G_debug(5, " start : gvl: %s isosurf : %d\n",
  103. gvl_file_get_name(gvl->hfile), i);
  104. }
  105. /* shade */
  106. gsd_shademodel(gvl->isosurf_draw_mode & DM_GOURAUD);
  107. /* scaling */
  108. GS_get_scale(&tx, &ty, &tz, 1);
  109. /* set number of cols, rows, dephs */
  110. cols = gvl->cols / gvl->isosurf_x_mod;
  111. rows = gvl->rows / gvl->isosurf_y_mod;
  112. depths = gvl->depths / gvl->isosurf_z_mod;
  113. /* set x,y,z resolution */
  114. xres =
  115. /*((float) gvl->cols) / ((float) cols) */ gvl->isosurf_x_mod *
  116. gvl->xres;
  117. yres =
  118. /*((float) gvl->rows) / ((float) rows) */ gvl->isosurf_y_mod *
  119. gvl->yres;
  120. zres =
  121. /*((float) gvl->depths) / ((float) depths) */ gvl->isosurf_z_mod *
  122. gvl->zres;
  123. /* get viewport */
  124. gsd_getwindow(window, viewport, modelMatrix, projMatrix);
  125. /* adjust window */
  126. window[0] += (int)(yres * 2);
  127. window[1] -= (int)(yres * 2);
  128. window[2] -= (int)(xres * 2);
  129. window[3] += (int)(xres * 2);
  130. gsd_colormode(CM_DIFFUSE);
  131. gsd_pushmatrix();
  132. gsd_do_scale(1);
  133. gsd_translate(gvl->x_trans, gvl->y_trans, gvl->z_trans);
  134. pkem = 1.0;
  135. pksh = 1.0;
  136. /* set default attribute values for isosurfaces */
  137. for (i = 0; i < gvl->n_isosurfs; i++) {
  138. isosurf = gvl->isosurf[i];
  139. /* init isosurf one cube edge datalength */
  140. e_dl[i] = 4;
  141. /* transparency */
  142. check_transp[i] = 0;
  143. ktrans[i] = (255 << 24);
  144. if (CONST_ATT == isosurf->att[ATT_TRANSP].att_src &&
  145. isosurf->att[ATT_TRANSP].constant != 0.0) {
  146. ktrans[i] = (255 - (int)isosurf->att[ATT_TRANSP].constant) << 24;
  147. }
  148. else if (MAP_ATT == isosurf->att[ATT_TRANSP].att_src) {
  149. check_transp[i] = 1;
  150. e_dl[i]++;
  151. }
  152. /* emis */
  153. check_emis[i] = 0;
  154. kem[i] = 0.0;
  155. if (CONST_ATT == isosurf->att[ATT_EMIT].att_src) {
  156. kem[i] = isosurf->att[ATT_EMIT].constant / 255.;
  157. }
  158. else if (MAP_ATT == isosurf->att[ATT_EMIT].att_src) {
  159. check_emis[i] = 1;
  160. e_dl[i]++;
  161. }
  162. /* shin */
  163. check_shin[i] = 0;
  164. ksh[i] = 0.0;
  165. if (CONST_ATT == isosurf->att[ATT_SHINE].att_src) {
  166. ksh[i] = isosurf->att[ATT_SHINE].constant / 255.;
  167. }
  168. else if (MAP_ATT == isosurf->att[ATT_SHINE].att_src) {
  169. check_shin[i] = 1;
  170. e_dl[i]++;
  171. }
  172. /* color */
  173. check_color[i] = 0;
  174. curcolor[i] = 0.0;
  175. if (CONST_ATT == isosurf->att[ATT_COLOR].att_src) {
  176. curcolor[i] = (int)isosurf->att[ATT_COLOR].constant;
  177. }
  178. else if (MAP_ATT == isosurf->att[ATT_COLOR].att_src) {
  179. check_color[i] = 1;
  180. e_dl[i] += 3;
  181. }
  182. /* check material */
  183. check_material[i] = (check_shin[i] || check_emis[i] ||
  184. (kem[i] && check_color[i]));
  185. /* set position in data */
  186. pos[i] = 0;
  187. nz[i] = 0;
  188. }
  189. G_debug(5, " initialize OK");
  190. for (z = 0; z < depths - 1; z++) {
  191. zc = z * zres;
  192. if (GS_check_cancel()) {
  193. for (i = 0; i < gvl->n_isosurfs; i++) {
  194. G_debug(5, " break : isosurf : %d datalength : %d B\n",
  195. i, pos[i]);
  196. }
  197. gsd_set_material(1, 1, 0., 0., 0x0);
  198. gsd_popmatrix();
  199. gsd_blend(0);
  200. gsd_zwritemask(0xffffffff);
  201. return (-1);
  202. }
  203. for (y = 0; y < rows - 1; y++) {
  204. yc = ((rows - 1) * yres) - (y * yres);
  205. for (x = 0; x < cols - 1; x++) {
  206. xc = x * xres;
  207. for (i = 0; i < gvl->n_isosurfs; i++) {
  208. /* read cube index */
  209. if (nz[i] != 0) {
  210. nz[i]--;
  211. continue;
  212. }
  213. else {
  214. c_ndx = READ();
  215. if (c_ndx == 0) {
  216. nz[i] = READ() - 1;
  217. continue;
  218. }
  219. else {
  220. c_ndx = (c_ndx - 1) * 256 + READ();
  221. }
  222. }
  223. /* save position */
  224. tmp_pos = pos[i];
  225. /* set position for each cube edge data */
  226. iv = 0;
  227. for (j = 0; j < cell_table[c_ndx].nedges; j++) {
  228. if (cell_table[c_ndx].edges[j] == 12)
  229. iv = 1;
  230. edge_pos[cell_table[c_ndx].edges[j]] =
  231. pos[i] + j * e_dl[i];
  232. }
  233. /* enable/disable blending and depth buffer writing */
  234. if (check_transp[i] || (ktrans[i] >> 24) < 255) {
  235. if (!pktransp) {
  236. gsd_blend(1);
  237. gsd_zwritemask(0);
  238. }
  239. }
  240. else if (pktransp) {
  241. gsd_blend(0);
  242. gsd_zwritemask(0xffffffff);
  243. pktransp = 0;
  244. }
  245. /* draw cube polygons */
  246. for (p = 0, num = 0; num < cell_table[c_ndx].npolys;
  247. num++) {
  248. gsd_bgnpolygon();
  249. for (j = 0; j < 3; j++) {
  250. crnt_ev = cell_table[c_ndx].polys[p];
  251. /* set position in data to current edge data */
  252. pos[i] = edge_pos[crnt_ev];
  253. /* triagle vertex */
  254. if (crnt_ev == 12) {
  255. pt[X] = xc + (READ() / 255. * xres);
  256. pt[Y] = yc + (-(READ() / 255. * yres));
  257. pt[Z] = zc + (READ() / 255. * zres);
  258. }
  259. else {
  260. pt[edge_vert_pos[crnt_ev][0]] = READ() / 255.;
  261. pt[edge_vert_pos[crnt_ev][1]] =
  262. edge_vert_pos[crnt_ev][2];
  263. pt[edge_vert_pos[crnt_ev][3]] =
  264. edge_vert_pos[crnt_ev][4];
  265. pt[X] = xc + (pt[X] * xres);
  266. pt[Y] = yc + (-(pt[Y] * yres));
  267. pt[Z] = zc + (pt[Z] * zres);
  268. }
  269. n[X] = (READ() / 127. - 1.) / xres;
  270. n[Y] = (-(READ() / 127. - 1.)) / yres;
  271. n[Z] = (READ() / 127. - 1.) / zres;
  272. if (gvl->isosurf[i]->inout_mode) {
  273. n[X] *= -1;
  274. n[Y] *= -1;
  275. n[Z] *= -1;
  276. }
  277. if (check_color[i]) {
  278. r = READ();
  279. g = READ();
  280. b = READ();
  281. curcolor[i] =
  282. (r & 0xff) | ((g & 0xff) << 8) |
  283. ((b & 0xff) << 16);
  284. }
  285. if (check_transp[i])
  286. ktrans[i] = READ() << 24;;
  287. if (check_shin[i])
  288. ksh[i] = ((float)READ()) / 255.;
  289. if (check_emis[i])
  290. kem[i] = ((float)READ()) / 255.;
  291. if (pksh != ksh[i] || pkem != kem[i] ||
  292. (kem[i] && check_color[i])) {
  293. pksh = ksh[i];
  294. pkem = kem[i];
  295. gsd_set_material(1, 1, ksh[i], kem[i],
  296. curcolor[i]);
  297. }
  298. gsd_litvert_func(n, ktrans[i] | curcolor[i], pt);
  299. p++;
  300. }
  301. gsd_endpolygon();
  302. }
  303. /* set position to next cube */
  304. pos[i] =
  305. tmp_pos + cell_table[c_ndx].nedges * e_dl[i] +
  306. (iv ? 2 : 0);
  307. }
  308. }
  309. }
  310. }
  311. for (i = 0; i < gvl->n_isosurfs; i++) {
  312. G_debug(5, " end : isosurf : %d datalength : %d B\n", i, pos[i]);
  313. }
  314. gsd_set_material(1, 1, 0., 0., 0x0);
  315. gsd_popmatrix();
  316. gsd_blend(0);
  317. gsd_zwritemask(0xffffffff);
  318. return (0);
  319. }
  320. /*!
  321. \brief Draw volume isosurface in draw mode
  322. \param gvl pointer to geovol struct
  323. \return 0
  324. */
  325. int gvld_wire_isosurf(geovol * gvl)
  326. {
  327. return (0);
  328. }
  329. /************************************************************************/
  330. /* SLICES */
  331. /************************************************************************/
  332. #define DISTANCE_2(x1, y1, x2, y2) sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))
  333. /*!
  334. \brief Draw slices
  335. \param gvl pointer to geovol struct
  336. \return 0
  337. */
  338. int gvld_slices(geovol * gvl)
  339. {
  340. float tx, ty, tz;
  341. int i;
  342. GLdouble modelMatrix[16], projMatrix[16];
  343. GLint viewport[4];
  344. GLint window[4];
  345. G_debug(5, "gvld_slices");
  346. /* shade */
  347. gsd_shademodel(gvl->slice_draw_mode & DM_GOURAUD);
  348. /* scaling */
  349. GS_get_scale(&tx, &ty, &tz, 1);
  350. /* get viewport */
  351. gsd_getwindow(window, viewport, modelMatrix, projMatrix);
  352. gsd_colormode(CM_COLOR);
  353. gsd_pushmatrix();
  354. gsd_do_scale(1);
  355. gsd_translate(gvl->x_trans, gvl->y_trans, gvl->z_trans);
  356. for (i = 0; i < gvl->n_slices; i++) {
  357. gsd_blend(0);
  358. gsd_zwritemask(0xffffffff);
  359. if (gvl->slice[i]->transp == 0)
  360. gvld_slice(gvl, i);
  361. }
  362. for (i = 0; i < gvl->n_slices; i++) {
  363. gsd_blend(1);
  364. gsd_zwritemask(0x0);
  365. if (gvl->slice[i]->transp > 0)
  366. gvld_slice(gvl, i);
  367. }
  368. gsd_set_material(1, 1, 0., 0., 0x0);
  369. gsd_popmatrix();
  370. gsd_blend(0);
  371. gsd_zwritemask(0xffffffff);
  372. return (0);
  373. }
  374. /*!
  375. \brief Draw slice
  376. \param gvl pointer to geovol struct
  377. \param ndx
  378. \return 1
  379. */
  380. int gvld_slice(geovol * gvl, int ndx)
  381. {
  382. geovol_slice *slice;
  383. int color, offset, transp;
  384. float n[3], pt[4];
  385. float x, nextx, y, nexty, z, stepx, stepy, stepz;
  386. int cols, rows, c, r;
  387. float f_cols, f_rows, distxy, distz, modx, mody, modz, modxy;
  388. int ptX, ptY, ptZ;
  389. double resx, resy, resz;
  390. /* current slice */
  391. slice = gvl->slice[ndx];
  392. /* distance between slice def. pts */
  393. distxy = DISTANCE_2(slice->x2, slice->y2, slice->x1, slice->y1);
  394. distz = fabsf(slice->z2 - slice->z1);
  395. /* distance between slice def pts is zero - zero slice */
  396. if (distxy == 0. || distz == 0.) {
  397. return (1);
  398. }
  399. /* set slice mod, resolution and set correct coords */
  400. if (slice->dir == X) {
  401. modx = gvl->slice_y_mod;
  402. mody = gvl->slice_z_mod;
  403. modz = gvl->slice_x_mod;
  404. resx = gvl->yres;
  405. resy = gvl->zres;
  406. resz = gvl->xres;
  407. ptX = Y;
  408. ptY = Z;
  409. ptZ = X;
  410. }
  411. else if (slice->dir == Y) {
  412. modx = gvl->slice_x_mod;
  413. mody = gvl->slice_z_mod;
  414. modz = gvl->slice_y_mod;
  415. resx = gvl->xres;
  416. resy = gvl->zres;
  417. resz = gvl->yres;
  418. ptX = X;
  419. ptY = Z;
  420. ptZ = Y;
  421. }
  422. else {
  423. modx = gvl->slice_x_mod;
  424. mody = gvl->slice_y_mod;
  425. modz = gvl->slice_z_mod;
  426. resx = gvl->xres;
  427. resy = gvl->yres;
  428. resz = gvl->zres;
  429. ptX = X;
  430. ptY = Y;
  431. ptZ = Z;
  432. }
  433. /* x,y mod */
  434. modxy =
  435. DISTANCE_2((slice->x2 - slice->x1) / distxy * modx,
  436. (slice->y2 - slice->y1) / distxy * mody, 0., 0.);
  437. /* cols/rows of slice */
  438. f_cols = distxy / modxy;
  439. cols = f_cols > (int)f_cols ? (int)f_cols + 1 : (int)f_cols;
  440. f_rows = distz / modz;
  441. rows = f_rows > (int)f_rows ? (int)f_rows + 1 : (int)f_rows;
  442. /* step in x,y for each row of slice */
  443. stepx = (slice->x2 - slice->x1) / f_cols;
  444. stepy = (slice->y2 - slice->y1) / f_cols;
  445. stepz = (slice->z2 - slice->z1) / f_rows;
  446. /* set x,y intially to first slice pt */
  447. x = (slice->x1);
  448. y = (slice->y1);
  449. /* set next draw pt */
  450. if (f_cols < 1.) {
  451. nextx = x + stepx * f_cols;
  452. nexty = y + stepy * f_cols;
  453. }
  454. else {
  455. nextx = x + stepx;
  456. nexty = y + stepy;
  457. }
  458. /* set transparency */
  459. if (slice->transp > 0) {
  460. transp = (255 - slice->transp) << 24;
  461. }
  462. else {
  463. transp = 0x0;
  464. }
  465. /* loop in slice cols */
  466. for (c = 0; c < cols; c++) {
  467. /* set z to slice z1 pt */
  468. z = slice->z1;
  469. /* begin draw one row - triangle strip */
  470. gsd_bgntmesh();
  471. /* loop in slice rows */
  472. for (r = 0; r < rows + 1; r++) {
  473. /* offset to data - 1. column */
  474. offset = (c + 1) * (rows + 1) * 3 + r * 3;
  475. /* get color from slice data */
  476. color = (slice->data[offset] & 0xff) |
  477. ((slice->data[offset + 1] & 0xff) << 8) |
  478. ((slice->data[offset + 2] & 0xff) << 16);
  479. /* triagle vertices */
  480. pt[ptX] = nextx * resx;
  481. pt[ptY] = nexty * resy;
  482. pt[ptZ] = z * resz;
  483. pt[Y] = (gvl->rows - 1) * gvl->yres - pt[Y];
  484. gsd_litvert_func(n, (unsigned int)transp | color, pt);
  485. /* offset to data - 2. column */
  486. offset = c * (rows + 1) * 3 + r * 3;
  487. /* get color from slice data */
  488. color = (slice->data[offset] & 0xff) |
  489. ((slice->data[offset + 1] & 0xff) << 8) |
  490. ((slice->data[offset + 2] & 0xff) << 16);
  491. /* set triangle vertices */
  492. pt[ptX] = x * resx;
  493. pt[ptY] = y * resy;
  494. pt[ptZ] = z * resz;
  495. pt[Y] = (gvl->rows - 1) * gvl->yres - pt[Y];
  496. gsd_litvert_func(n, (unsigned int)transp | color, pt);
  497. if (r + 1 > f_rows) {
  498. z += stepz * (f_rows - (float)r);
  499. }
  500. else {
  501. z += stepz;
  502. }
  503. }
  504. gsd_endtmesh();
  505. /* step */
  506. if (c + 2 > f_cols) {
  507. x += stepx;
  508. nextx += stepx * (f_cols - (float)(c + 1));
  509. y += stepy;
  510. nexty += stepy * (f_cols - (float)(c + 1));
  511. }
  512. else {
  513. x += stepx;
  514. nextx += stepx;
  515. y += stepy;
  516. nexty += stepy;
  517. }
  518. }
  519. gsd_blend(0);
  520. gsd_zwritemask(0xffffffff);
  521. return (1);
  522. }
  523. /*!
  524. \brief Draw wire slices
  525. \param gvl pointer to geovol struct
  526. \return 0
  527. */
  528. int gvld_wire_slices(geovol * gvl)
  529. {
  530. float pt[3];
  531. int i;
  532. int ptX, ptY, ptZ;
  533. double resx, resy, resz;
  534. geovol_slice *slice;
  535. G_debug(5, "gvld_wire_slices");
  536. gsd_pushmatrix();
  537. /* shading */
  538. gsd_shademodel(DM_FLAT);
  539. /* set color mode */
  540. gsd_colormode(CM_COLOR);
  541. /* do scale and set volume position */
  542. gsd_do_scale(1);
  543. gsd_translate(gvl->x_trans, gvl->y_trans, gvl->z_trans);
  544. /* set color and line width */
  545. gsd_color_func(0x0);
  546. gsd_linewidth(1);
  547. /* loop in slices */
  548. for (i = 0; i < gvl->n_slices; i++) {
  549. slice = gvl->slice[i];
  550. /* initialize correct coords */
  551. if (slice->dir == X) {
  552. resx = gvl->yres;
  553. resy = gvl->zres;
  554. resz = gvl->xres;
  555. ptX = Y;
  556. ptY = Z;
  557. ptZ = X;
  558. }
  559. else if (slice->dir == Y) {
  560. resx = gvl->xres;
  561. resy = gvl->zres;
  562. resz = gvl->yres;
  563. ptX = X;
  564. ptY = Z;
  565. ptZ = Y;
  566. }
  567. else {
  568. resx = gvl->xres;
  569. resy = gvl->yres;
  570. resz = gvl->zres;
  571. ptX = X;
  572. ptY = Y;
  573. ptZ = Z;
  574. }
  575. gsd_bgnline();
  576. /* first slice edge */
  577. pt[ptX] = slice->x1 * resx;
  578. pt[ptY] = slice->y1 * resy;
  579. pt[ptZ] = slice->z1 * resz;;
  580. pt[Y] = (gvl->rows - 1) * gvl->yres - pt[Y];
  581. gsd_vert_func(pt);
  582. pt[ptX] = slice->x1 * resx;
  583. pt[ptY] = slice->y1 * resy;
  584. pt[ptZ] = slice->z2 * resz;;
  585. pt[Y] = (gvl->rows - 1) * gvl->yres - pt[Y];
  586. gsd_vert_func(pt);
  587. pt[ptX] = slice->x2 * resx;
  588. pt[ptY] = slice->y2 * resy;
  589. pt[ptZ] = slice->z2 * resz;;
  590. pt[Y] = (gvl->rows - 1) * gvl->yres - pt[Y];
  591. gsd_vert_func(pt);
  592. pt[ptX] = slice->x2 * resx;
  593. pt[ptY] = slice->y2 * resy;
  594. pt[ptZ] = slice->z1 * resz;;
  595. pt[Y] = (gvl->rows - 1) * gvl->yres - pt[Y];
  596. gsd_vert_func(pt);
  597. pt[ptX] = slice->x1 * resx;
  598. pt[ptY] = slice->y1 * resy;
  599. pt[ptZ] = slice->z1 * resz;;
  600. pt[Y] = (gvl->rows - 1) * gvl->yres - pt[Y];
  601. gsd_vert_func(pt);
  602. gsd_endline();
  603. }
  604. gsd_set_material(1, 1, 0., 0., 0x0);
  605. gsd_popmatrix();
  606. return (0);
  607. }
  608. /*!
  609. \brief Draw volume bounding box
  610. \param gvl pointer to geovol struct
  611. \return 0
  612. */
  613. int gvld_wind3_box(geovol * gvl)
  614. {
  615. float pt[3];
  616. G_debug(5, "gvld_wind3_box(): id=%d", gvl->gvol_id);
  617. gsd_pushmatrix();
  618. /* shading */
  619. gsd_shademodel(DM_FLAT);
  620. /* set color mode */
  621. gsd_colormode(CM_COLOR);
  622. /* do scale and set volume position */
  623. gsd_do_scale(1);
  624. gsd_translate(gvl->x_trans, gvl->y_trans, gvl->z_trans);
  625. /* set color and line width */
  626. gsd_color_func(0x0);
  627. gsd_linewidth(1);
  628. /* draw box */
  629. /* front edges */
  630. gsd_bgnline();
  631. pt[X] = 0;
  632. pt[Y] = 0;
  633. pt[Z] = 0;
  634. gsd_vert_func(pt);
  635. pt[X] = (gvl->cols - 1) * gvl->xres;
  636. pt[Y] = 0;
  637. pt[Z] = 0;
  638. gsd_vert_func(pt);
  639. pt[X] = (gvl->cols - 1) * gvl->xres;
  640. pt[Y] = (gvl->rows - 1) * gvl->yres;
  641. pt[Z] = 0;
  642. gsd_vert_func(pt);
  643. pt[X] = 0;
  644. pt[Y] = (gvl->rows - 1) * gvl->yres;
  645. pt[Z] = 0;
  646. gsd_vert_func(pt);
  647. pt[X] = 0;
  648. pt[Y] = 0;
  649. pt[Z] = 0;
  650. gsd_vert_func(pt);
  651. gsd_endline();
  652. /* back edges */
  653. gsd_bgnline();
  654. pt[X] = 0;
  655. pt[Y] = 0;
  656. pt[Z] = (gvl->depths - 1) * gvl->zres;
  657. gsd_vert_func(pt);
  658. pt[X] = (gvl->cols - 1) * gvl->xres;
  659. pt[Y] = 0;
  660. pt[Z] = (gvl->depths - 1) * gvl->zres;
  661. gsd_vert_func(pt);
  662. pt[X] = (gvl->cols - 1) * gvl->xres;
  663. pt[Y] = (gvl->rows - 1) * gvl->yres;
  664. pt[Z] = (gvl->depths - 1) * gvl->zres;
  665. gsd_vert_func(pt);
  666. pt[X] = 0;
  667. pt[Y] = (gvl->rows - 1) * gvl->yres;
  668. pt[Z] = (gvl->depths - 1) * gvl->zres;
  669. gsd_vert_func(pt);
  670. pt[X] = 0;
  671. pt[Y] = 0;
  672. pt[Z] = (gvl->depths - 1) * gvl->zres;
  673. gsd_vert_func(pt);
  674. gsd_endline();
  675. /* others edges */
  676. gsd_bgnline();
  677. pt[X] = 0;
  678. pt[Y] = 0;
  679. pt[Z] = 0;
  680. gsd_vert_func(pt);
  681. pt[X] = 0;
  682. pt[Y] = 0;
  683. pt[Z] = (gvl->depths - 1) * gvl->zres;
  684. gsd_vert_func(pt);
  685. gsd_endline();
  686. gsd_bgnline();
  687. pt[X] = (gvl->cols - 1) * gvl->xres;
  688. pt[Y] = 0;
  689. pt[Z] = 0;
  690. gsd_vert_func(pt);
  691. pt[X] = (gvl->cols - 1) * gvl->xres;
  692. pt[Y] = 0;
  693. pt[Z] = (gvl->depths - 1) * gvl->zres;
  694. gsd_vert_func(pt);
  695. gsd_endline();
  696. gsd_bgnline();
  697. pt[X] = 0;
  698. pt[Y] = (gvl->rows - 1) * gvl->yres;
  699. pt[Z] = 0;
  700. gsd_vert_func(pt);
  701. pt[X] = 0;
  702. pt[Y] = (gvl->rows - 1) * gvl->yres;
  703. pt[Z] = (gvl->depths - 1) * gvl->zres;
  704. gsd_vert_func(pt);
  705. gsd_endline();
  706. gsd_bgnline();
  707. pt[X] = (gvl->cols - 1) * gvl->xres;
  708. pt[Y] = (gvl->rows - 1) * gvl->yres;
  709. pt[Z] = 0;
  710. gsd_vert_func(pt);
  711. pt[X] = (gvl->cols - 1) * gvl->xres;
  712. pt[Y] = (gvl->rows - 1) * gvl->yres;
  713. pt[Z] = (gvl->depths - 1) * gvl->zres;
  714. gsd_vert_func(pt);
  715. gsd_endline();
  716. gsd_popmatrix();
  717. return (0);
  718. }