gvld.c 19 KB

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