iso_surface.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689
  1. #include <stdlib.h>
  2. #include <math.h>
  3. #include "vizual.h"
  4. #include <grass/gis.h>
  5. #include <grass/raster.h>
  6. #include <grass/raster3d.h>
  7. #include "local_proto.h"
  8. #define XDIMYDIM (Headfax.xdim*Headfax.ydim)
  9. float TEMP_VERT[13][3];
  10. float TEMP_NORM[13][3];
  11. static float DATA[8];
  12. /* function prototypes */
  13. static void percent(int z, int zloop);
  14. static void calc_cube_info(float *data[], int z1);
  15. static void xings_fnorm(int c_ndx, int t_ndx);
  16. static void calc_fnorm(int c_ndx);
  17. static void xings_grad(float *data[], int c_ndx, int x1, int y1,
  18. int z1, int t_ndx);
  19. static void normalize(float n[3]);
  20. void viz_iso_surface(void *g3map, RASTER3D_Region * g3reg,
  21. cmndln_info * linefax, int quiet)
  22. {
  23. float *data[4]; /* will hold 4 slices of xy data */
  24. int zloop;
  25. int z; /* looping variables */
  26. int slice;
  27. float *temp;
  28. zloop = Headfax.zdim - 1; /*crop to permit use of gradients */
  29. /* for gradient shading processing 4 slices of xy data at a time */
  30. for (z = 0; z < zloop; z++) { /*dpg */
  31. if (!quiet)
  32. percent(z, zloop);
  33. if (!z) { /* first time thru need to read in four slices of data */
  34. for (slice = 0; slice < 4; slice++) {
  35. data[slice] = (float *)G_malloc(sizeof(float) * XDIMYDIM);
  36. if (slice)
  37. /*read in data */
  38. r3read_level(g3map, g3reg, &Headfax, data[slice],
  39. slice - 1);
  40. }
  41. }
  42. else {
  43. temp = data[0];
  44. data[0] = data[1];
  45. data[1] = data[2];
  46. data[2] = data[3];
  47. data[3] = temp;
  48. if (z < zloop - 1)
  49. r3read_level(g3map, g3reg, &Headfax, data[3], z + 2);
  50. }
  51. calc_cube_info(data, z);
  52. }
  53. }
  54. /************************ percent *******************************************/
  55. static void percent(int z, int zloop)
  56. {
  57. int percent;
  58. static int flag = 1;
  59. if (flag) {
  60. fprintf(stderr, "display file completed:");
  61. flag = 0;
  62. }
  63. percent = (z * 100) / zloop;
  64. fprintf(stderr, " %3d %%", percent);
  65. fprintf(stderr, "\b\b\b\b\b\b\b");
  66. }
  67. /************************ calc_cube_info ************************************/
  68. static void calc_cube_info(float *data[], int z1)
  69. {
  70. int x1, y1;
  71. int x2, y2;
  72. int xloop, yloop;
  73. int y1dist, y2dist;
  74. int c_ndx; /*index into cell table */
  75. int t_ndx = 0; /*index into array of thresholds */
  76. int a = 0; /*keeps track of how many thresholds are contained in a cell */
  77. cmndln_info *linefax;
  78. cube_info *CUBEFAX;
  79. int vnum; /* index to loop through vertices of cube */
  80. CUBEFAX = CUBE.data; /* make old code fit new structure */
  81. linefax = &Headfax.linefax;
  82. xloop = (Headfax.xdim);
  83. yloop = (Headfax.ydim);
  84. /* the following commands turn on appropriate bits in the c_ndx variable
  85. * based on vertex value.
  86. */
  87. /* loop down in y */
  88. for (y1 = 0; y1 < yloop - 1; y1++) { /* dpg */
  89. y2 = y1 + 1;
  90. y1dist = y1 * (Headfax.xdim);
  91. y2dist = y2 * (Headfax.xdim);
  92. /* loop across in x */
  93. /* loop for each threshold for each cube */
  94. for (x1 = 0; x1 < xloop - 1; x1++) { /* dpg */
  95. a = 0; /* set to zero for each cell */
  96. for (t_ndx = 0; t_ndx < (linefax->nthres); t_ndx++) {
  97. x2 = x1 + 1;
  98. DATA[0] = data[1][y2dist + x1];
  99. DATA[1] = data[1][y2dist + x2];
  100. DATA[2] = data[1][y1dist + x2];
  101. DATA[3] = data[1][y1dist + x1];
  102. DATA[4] = data[2][y2dist + x1];
  103. DATA[5] = data[2][y2dist + x2];
  104. DATA[6] = data[2][y1dist + x2];
  105. DATA[7] = data[2][y1dist + x1];
  106. c_ndx = 0;
  107. for (vnum = 0; vnum < 8; vnum++) {
  108. if (DATA[vnum] >= linefax->tvalue[t_ndx])
  109. c_ndx |= 1 << vnum;
  110. }
  111. /* currently masks in grid3 files are in xy-plane, so check for cube with one
  112. or more (vertical) edges masked out & don't draw polys. This gets rid of
  113. walls around masked surfaces, but leaves edges jagged */
  114. #ifdef OLDSTUFF
  115. if (!DATA[0] && !DATA[4])
  116. c_ndx = 0;
  117. else if (!DATA[1] && !DATA[5])
  118. c_ndx = 0;
  119. else if (!DATA[2] && !DATA[6])
  120. c_ndx = 0;
  121. else if (!DATA[3] && !DATA[7])
  122. c_ndx = 0;
  123. #endif
  124. /* CHANGED: use NULLS instead of zeros - if any are null, polygons
  125. are undefined - or else need to define polygons which exclude nulls under
  126. various combinations e.g., give each null a tetrahedron of influence */
  127. if (Rast_is_f_null_value((FCELL *) (DATA + 0)) ||
  128. Rast_is_f_null_value((FCELL *) (DATA + 1)) ||
  129. Rast_is_f_null_value((FCELL *) (DATA + 2)) ||
  130. Rast_is_f_null_value((FCELL *) (DATA + 3)) ||
  131. Rast_is_f_null_value((FCELL *) (DATA + 4)) ||
  132. Rast_is_f_null_value((FCELL *) (DATA + 5)) ||
  133. Rast_is_f_null_value((FCELL *) (DATA + 6)) ||
  134. Rast_is_f_null_value((FCELL *) (DATA + 7)))
  135. c_ndx = 0;
  136. /* c_ndx numbers (1 - 254) contain polygons */
  137. /*if (c_ndx > 0 && c_ndx < 254) this is the hole bug */
  138. if (c_ndx > 0 && c_ndx < 255) { /* -dpg */
  139. CUBEFAX[a].t_ndx = t_ndx;
  140. NTHRESH = a;
  141. a++;
  142. switch (linefax->litmodel) {
  143. case 1:
  144. xings_fnorm(c_ndx, t_ndx);
  145. break;
  146. case 2:
  147. case 3:
  148. xings_grad(data, c_ndx, x1, y1, z1, t_ndx);
  149. break;
  150. }
  151. fill_cfax(&CUBE, linefax->litmodel, c_ndx,
  152. TEMP_VERT, TEMP_NORM);
  153. }
  154. }
  155. if (!a)
  156. CUBEFAX[0].npoly = 0; /* sets 'empty' flag */
  157. CUBE.n_thresh = a;
  158. write_cube(&CUBE, x1, &Headfax);
  159. }
  160. }
  161. }
  162. /*********************************** xings_fnorm****************************/
  163. /* This subroutine is called once for each cell(cube) at given threshold value.
  164. ** This is the subroutine that is called if flat shading is to be used.
  165. ** Subroutine vertices are determined for the polygons that will be
  166. ** saved in a display file as well as the normal to the polygon
  167. */
  168. static void xings_fnorm(int c_ndx, int t_ndx)
  169. {
  170. cmndln_info *linefax;
  171. register int i; /* loop count variable incremented to to examine each edge */
  172. /* listed for c_ndx of cube being examined */
  173. linefax = &Headfax.linefax;
  174. for (i = 0; i < cell_table[c_ndx].nedges; i++) {
  175. switch (cell_table[c_ndx].edges[i]) {
  176. case 1:
  177. TEMP_VERT[1][0] =
  178. LINTERP(DATA[0], DATA[1], linefax->tvalue[t_ndx]);
  179. TEMP_VERT[1][1] = 255;
  180. TEMP_VERT[1][2] = 0;
  181. break;
  182. case 2:
  183. TEMP_VERT[2][0] = 255;
  184. TEMP_VERT[2][1] =
  185. LINTERP(DATA[2], DATA[1], linefax->tvalue[t_ndx]);
  186. TEMP_VERT[2][2] = 0;
  187. break;
  188. case 3:
  189. TEMP_VERT[3][0] =
  190. LINTERP(DATA[3], DATA[2], linefax->tvalue[t_ndx]);
  191. TEMP_VERT[3][1] = 0;
  192. TEMP_VERT[3][2] = 0;
  193. break;
  194. case 4:
  195. TEMP_VERT[4][0] = 0;
  196. TEMP_VERT[4][1] =
  197. LINTERP(DATA[3], DATA[0], linefax->tvalue[t_ndx]);
  198. TEMP_VERT[4][2] = 0;
  199. break;
  200. case 5:
  201. TEMP_VERT[5][0] =
  202. LINTERP(DATA[4], DATA[5], linefax->tvalue[t_ndx]);
  203. TEMP_VERT[5][1] = 255;
  204. TEMP_VERT[5][2] = 255;
  205. break;
  206. case 6:
  207. TEMP_VERT[6][0] = 255;
  208. TEMP_VERT[6][1] =
  209. LINTERP(DATA[6], DATA[5], linefax->tvalue[t_ndx]);
  210. TEMP_VERT[6][2] = 255;
  211. break;
  212. case 7:
  213. TEMP_VERT[7][0] =
  214. LINTERP(DATA[7], DATA[6], linefax->tvalue[t_ndx]);
  215. TEMP_VERT[7][1] = 0;
  216. TEMP_VERT[7][2] = 255;
  217. break;
  218. case 8:
  219. TEMP_VERT[8][0] = 0;
  220. TEMP_VERT[8][1] =
  221. LINTERP(DATA[7], DATA[4], linefax->tvalue[t_ndx]);
  222. TEMP_VERT[8][2] = 255;
  223. break;
  224. case 9:
  225. TEMP_VERT[9][0] = 0;
  226. TEMP_VERT[9][1] = 255;
  227. TEMP_VERT[9][2] =
  228. LINTERP(DATA[0], DATA[4], linefax->tvalue[t_ndx]);
  229. break;
  230. case 10:
  231. TEMP_VERT[10][0] = 255;
  232. TEMP_VERT[10][1] = 255;
  233. TEMP_VERT[10][2] =
  234. LINTERP(DATA[1], DATA[5], linefax->tvalue[t_ndx]);
  235. break;
  236. case 11:
  237. TEMP_VERT[11][0] = 0;
  238. TEMP_VERT[11][1] = 0;
  239. TEMP_VERT[11][2] =
  240. LINTERP(DATA[3], DATA[7], linefax->tvalue[t_ndx]);
  241. break;
  242. case 12:
  243. TEMP_VERT[12][0] = 255;
  244. TEMP_VERT[12][1] = 0;
  245. TEMP_VERT[12][2] =
  246. LINTERP(DATA[2], DATA[6], linefax->tvalue[t_ndx]);
  247. }
  248. }
  249. calc_fnorm(c_ndx);
  250. }
  251. /*************************** calc_fnorm ************************************/
  252. /* this routine calculates the normal to a polygon for flat shading */
  253. static void calc_fnorm(int c_ndx)
  254. {
  255. float x1, y1, z1, x2, y2, z2, x3, y3, z3;
  256. int i = 0;
  257. int inref;
  258. int poly_num = 0; /*the polygon number */
  259. double r2x, r2y, r2z, r1x, r1y, r1z;
  260. /* cell_table structure included in .h file */
  261. while (i < cell_table[c_ndx].npolys * 3) {
  262. /* indirect referencing into the TEMP_VERT array */
  263. inref = cell_table[c_ndx].polys[i];
  264. x1 = TEMP_VERT[inref][0];
  265. y1 = TEMP_VERT[inref][1];
  266. z1 = TEMP_VERT[inref][2];
  267. i++;
  268. inref = cell_table[c_ndx].polys[i];
  269. x2 = TEMP_VERT[inref][0];
  270. y2 = TEMP_VERT[inref][1];
  271. z2 = TEMP_VERT[inref][2];
  272. i++;
  273. inref = cell_table[c_ndx].polys[i];
  274. x3 = TEMP_VERT[inref][0];
  275. y3 = TEMP_VERT[inref][1];
  276. z3 = TEMP_VERT[inref][2];
  277. i++;
  278. /* Cramer's rule used to calculate the coefficients */
  279. r2x = x1 - x2;
  280. r2y = y1 - y2;
  281. r2z = z1 - z2;
  282. r1x = x3 - x2;
  283. r1y = y3 - y2;
  284. r1z = z3 - z2;
  285. /* assign the unit vector normal to the polygon for use in lighting */
  286. TEMP_NORM[poly_num][0] = (float)(r1y * r2z - r1z * r2y);
  287. TEMP_NORM[poly_num][1] = (float)(r1z * r2x - r1x * r2z);
  288. TEMP_NORM[poly_num][2] = (float)(r1x * r2y - r1y * r2x);
  289. normalize(TEMP_NORM[poly_num]);
  290. poly_num += 1;
  291. }
  292. }
  293. /***************************** xings_grad ********************************/
  294. /* this subroutine is called once for each cell(cube) at given threshold tvalue
  295. ** vertices are determined for the polygons that will be written to a display
  296. ** file. Gradients for each vertex are determined to be used as normals
  297. ** in lighting calculations.
  298. ** gradients are stored in temporary variables that are also written to display** file.
  299. */
  300. static void xings_grad(float *data[], int c_ndx, int x1, int y1, int z1,
  301. int t_ndx)
  302. {
  303. cmndln_info *linefax;
  304. register int i; /* loop count variable incremented to examine each edge */
  305. /* listed for c_ndx of cube being examined */
  306. int nedges; /* number of edges as listed for given c_ndx into cell_table */
  307. int crnt_edge; /* number of the current edge being examined */
  308. int x0, y0, z0; /* used to calculate desired location in data array */
  309. int x2, y2, z2;
  310. int x3, y3, z3; /* used to calculate desired location in data array */
  311. int a = 0, b = 0; /* the x,y,z components of the gradient vector */
  312. float delta = 0;
  313. /* the following variables are used to calculate gradients in the x,y,Z
  314. ** direction. gradients are going to be used to calculate relative positions of
  315. ** vertices to the light source. though not specifically necessary, the offset
  316. ** variables facilitate error checking.
  317. */
  318. float Data1xoffset, Data1yoffset, Data1zoffset;
  319. float Data2xoffset, Data2yoffset, Data2zoffset;
  320. float Data3xoffset, Data3yoffset, Data3zoffset;
  321. float Data4xoffset, Data4yoffset, Data4zoffset;
  322. float Data5xoffset, Data5yoffset, Data5zoffset;
  323. float Data6xoffset, Data6yoffset, Data6zoffset;
  324. float Data7xoffset, Data7yoffset, Data7zoffset;
  325. float Data8xoffset, Data8yoffset, Data8zoffset;
  326. /* HOLDS THE GRADIENT FOR EACH VERTEX OF THE CELL BEING EXAMINED */
  327. float Data_Grad[9][3];
  328. linefax = &Headfax.linefax;
  329. x0 = x1 - 1;
  330. y0 = y1 - 1;
  331. z0 = z1 - 1;
  332. x2 = x1 + 1;
  333. y2 = y1 + 1;
  334. z2 = z1 + 1;
  335. x3 = x2 + 1;
  336. y3 = y2 + 1;
  337. z3 = z2 + 1;
  338. if (x0 >= 0) {
  339. Data1xoffset = data[1][y2 * Headfax.xdim + x0];
  340. Data4xoffset = data[1][y1 * Headfax.xdim + x0];
  341. Data5xoffset = data[2][y2 * Headfax.xdim + x0];
  342. Data8xoffset = data[2][y1 * Headfax.xdim + x0];
  343. }
  344. else {
  345. Data1xoffset = 2.0 * data[1][y2 * Headfax.xdim + x1]
  346. - data[1][y2 * Headfax.xdim + x2];
  347. Data4xoffset = 2.0 * data[1][y1 * Headfax.xdim + x1]
  348. - data[1][y1 * Headfax.xdim + x2];
  349. Data5xoffset = 2.0 * data[2][y2 * Headfax.xdim + x1]
  350. - data[2][y2 * Headfax.xdim + x2];
  351. Data8xoffset = 2.0 * data[2][y1 * Headfax.xdim + x1]
  352. - data[2][y1 * Headfax.xdim + x2];
  353. }
  354. if (x3 < Headfax.xdim) {
  355. Data2xoffset = data[1][y2 * Headfax.xdim + x3];
  356. Data3xoffset = data[1][y1 * Headfax.xdim + x3];
  357. Data6xoffset = data[2][y2 * Headfax.xdim + x3];
  358. Data7xoffset = data[2][y1 * Headfax.xdim + x3];
  359. }
  360. else {
  361. Data2xoffset = 2.0 * data[1][y2 * Headfax.xdim + x2]
  362. - data[1][y2 * Headfax.xdim + x1];
  363. Data3xoffset = 2.0 * data[1][y1 * Headfax.xdim + x2]
  364. - data[1][y1 * Headfax.xdim + x1];
  365. Data6xoffset = 2.0 * data[2][y2 * Headfax.xdim + x2]
  366. - data[2][y2 * Headfax.xdim + x1];
  367. Data7xoffset = 2.0 * data[2][y1 * Headfax.xdim + x2]
  368. - data[2][y1 * Headfax.xdim + x1];
  369. }
  370. if (y0 >= 0) {
  371. Data3yoffset = data[1][y0 * Headfax.xdim + x2];
  372. Data4yoffset = data[1][y0 * Headfax.xdim + x1];
  373. Data7yoffset = data[2][y0 * Headfax.xdim + x2];
  374. Data8yoffset = data[2][y0 * Headfax.xdim + x1];
  375. }
  376. else {
  377. Data3yoffset = 2.0 * data[1][y1 * Headfax.xdim + x2]
  378. - data[1][y2 * Headfax.xdim + x2];
  379. Data4yoffset = 2.0 * data[1][y1 * Headfax.xdim + x1]
  380. - data[1][y2 * Headfax.xdim + x1];
  381. Data7yoffset = 2.0 * data[2][y1 * Headfax.xdim + x2]
  382. - data[2][y2 * Headfax.xdim + x2];
  383. Data8yoffset = 2.0 * data[2][y1 * Headfax.xdim + x1]
  384. - data[2][y2 * Headfax.xdim + x1];
  385. }
  386. if (y3 < Headfax.ydim) {
  387. Data1yoffset = data[1][y3 * Headfax.xdim + x1];
  388. Data2yoffset = data[1][y3 * Headfax.xdim + x2];
  389. Data5yoffset = data[2][y3 * Headfax.xdim + x1];
  390. Data6yoffset = data[2][y3 * Headfax.xdim + x2];
  391. }
  392. else {
  393. Data1yoffset = 2.0 * data[1][y2 * Headfax.xdim + x1]
  394. - data[1][y1 * Headfax.xdim + x1];
  395. Data2yoffset = 2.0 * data[1][y2 * Headfax.xdim + x2]
  396. - data[1][y1 * Headfax.xdim + x2];
  397. Data5yoffset = 2.0 * data[2][y2 * Headfax.xdim + x1]
  398. - data[2][y1 * Headfax.xdim + x1];
  399. Data6yoffset = 2.0 * data[2][y2 * Headfax.xdim + x2]
  400. - data[2][y1 * Headfax.xdim + x2];
  401. }
  402. if (z0 >= 0) {
  403. Data1zoffset = data[0][y2 * Headfax.xdim + x1];
  404. Data2zoffset = data[0][y2 * Headfax.xdim + x2];
  405. Data3zoffset = data[0][y1 * Headfax.xdim + x2];
  406. Data4zoffset = data[0][y1 * Headfax.xdim + x1];
  407. }
  408. else {
  409. Data1zoffset = 2.0 * data[1][y2 * Headfax.xdim + x1]
  410. - data[2][y2 * Headfax.xdim + x1];
  411. Data2zoffset = 2.0 * data[1][y2 * Headfax.xdim + x2]
  412. - data[2][y2 * Headfax.xdim + x2];
  413. Data3zoffset = 2.0 * data[1][y1 * Headfax.xdim + x2]
  414. - data[2][y1 * Headfax.xdim + x2];
  415. Data4zoffset = 2.0 * data[1][y1 * Headfax.xdim + x1]
  416. - data[2][y1 * Headfax.xdim + x1];
  417. }
  418. if (z3 < Headfax.zdim) {
  419. Data5zoffset = data[3][y2 * Headfax.xdim + x1];
  420. Data6zoffset = data[3][y2 * Headfax.xdim + x2];
  421. Data7zoffset = data[3][y1 * Headfax.xdim + x2];
  422. Data8zoffset = data[3][y1 * Headfax.xdim + x1];
  423. }
  424. else {
  425. Data5zoffset = 2.0 * data[2][y2 * Headfax.xdim + x1]
  426. - data[1][y2 * Headfax.xdim + x1];
  427. Data6zoffset = 2.0 * data[2][y2 * Headfax.xdim + x2]
  428. - data[1][y2 * Headfax.xdim + x2];
  429. Data7zoffset = 2.0 * data[2][y1 * Headfax.xdim + x2]
  430. - data[1][y1 * Headfax.xdim + x2];
  431. Data8zoffset = 2.0 * data[2][y1 * Headfax.xdim + x1]
  432. - data[1][y1 * Headfax.xdim + x1];
  433. }
  434. Data_Grad[1][0] = (DATA[1] - Data1xoffset) / 2;
  435. Data_Grad[1][1] = (Data1yoffset - DATA[3]) / 2;
  436. Data_Grad[1][2] = (DATA[4] - Data1zoffset) / 2;
  437. Data_Grad[2][0] = (Data2xoffset - DATA[0]) / 2;
  438. Data_Grad[2][1] = (Data2yoffset - DATA[2]) / 2;
  439. Data_Grad[2][2] = (DATA[5] - Data2zoffset) / 2;
  440. Data_Grad[3][0] = (Data3xoffset - DATA[3]) / 2;
  441. Data_Grad[3][1] = (DATA[1] - Data3yoffset) / 2;
  442. Data_Grad[3][2] = (DATA[6] - Data3zoffset) / 2;
  443. Data_Grad[4][0] = (DATA[2] - Data4xoffset) / 2;
  444. Data_Grad[4][1] = (DATA[0] - Data4yoffset) / 2;
  445. Data_Grad[4][2] = (DATA[7] - Data4zoffset) / 2;
  446. Data_Grad[5][0] = (DATA[5] - Data5xoffset) / 2;
  447. Data_Grad[5][1] = (Data5yoffset - DATA[7]) / 2;
  448. Data_Grad[5][2] = (Data5zoffset - DATA[0]) / 2;
  449. Data_Grad[6][0] = (Data6xoffset - DATA[4]) / 2;
  450. Data_Grad[6][1] = (Data6yoffset - DATA[6]) / 2;
  451. Data_Grad[6][2] = (Data6zoffset - DATA[1]) / 2;
  452. Data_Grad[7][0] = (Data7xoffset - DATA[7]) / 2;
  453. Data_Grad[7][1] = (DATA[5] - Data7yoffset) / 2;
  454. Data_Grad[7][2] = (Data7zoffset - DATA[2]) / 2;
  455. Data_Grad[8][0] = (DATA[6] - Data8xoffset) / 2;
  456. Data_Grad[8][1] = (DATA[4] - Data8yoffset) / 2;
  457. Data_Grad[8][2] = (Data8zoffset - DATA[3]) / 2;
  458. nedges = cell_table[c_ndx].nedges; /*ASSIGNED A VALUE FROM CELL_TABLE */
  459. /* loop for number of edges determined by cell c_ndx, specific edge numbeR
  460. ** is located in the cell_table[c_ndx].edges[#]. for each edge listed, the
  461. ** polygon vertices are calculated and stored in temporary array temp_vert[][],
  462. ** gradients for x,y,z components of these vertices are calculated next as
  463. ** a,b,c the length l of this gradient vector is computed and the normalizeD
  464. ** gradient vector (a/l, b/l, c/l) are stored in the temp_grad[][].
  465. */
  466. for (i = 0; i < nedges; i++) {
  467. crnt_edge = cell_table[c_ndx].edges[i];
  468. switch (crnt_edge) {
  469. case 1:
  470. delta = (linefax->tvalue[t_ndx] - DATA[0]) / (DATA[1] - DATA[0]);
  471. TEMP_VERT[1][0] = delta * 255;
  472. TEMP_VERT[1][1] = 255;
  473. TEMP_VERT[1][2] = 0;
  474. a = 2;
  475. b = 1;
  476. break;
  477. case 2:
  478. delta = (linefax->tvalue[t_ndx] - DATA[2]) / (DATA[1] - DATA[2]);
  479. TEMP_VERT[2][0] = 255;
  480. TEMP_VERT[2][1] = delta * 255;
  481. TEMP_VERT[2][2] = 0;
  482. a = 2;
  483. b = 3;
  484. break;
  485. case 3:
  486. delta = (linefax->tvalue[t_ndx] - DATA[3]) / (DATA[2] - DATA[3]);
  487. TEMP_VERT[3][0] = delta * 255;
  488. TEMP_VERT[3][1] = 0;
  489. TEMP_VERT[3][2] = 0;
  490. a = 3;
  491. b = 4;
  492. break;
  493. case 4:
  494. delta = (linefax->tvalue[t_ndx] - DATA[3]) / (DATA[0] - DATA[3]);
  495. TEMP_VERT[4][0] = 0;
  496. TEMP_VERT[4][1] = delta * 255;
  497. TEMP_VERT[4][2] = 0;
  498. a = 1;
  499. b = 4;
  500. break;
  501. case 5:
  502. delta = (linefax->tvalue[t_ndx] - DATA[4]) / (DATA[5] - DATA[4]);
  503. TEMP_VERT[5][0] = delta * 255;
  504. TEMP_VERT[5][1] = 255;
  505. TEMP_VERT[5][2] = 255;
  506. a = 6;
  507. b = 5;
  508. break;
  509. case 6:
  510. delta = (linefax->tvalue[t_ndx] - DATA[6]) / (DATA[5] - DATA[6]);
  511. TEMP_VERT[6][0] = 255;
  512. TEMP_VERT[6][1] = delta * 255;
  513. TEMP_VERT[6][2] = 255;
  514. a = 6;
  515. b = 7;
  516. break;
  517. case 7:
  518. delta = (linefax->tvalue[t_ndx] - DATA[7]) / (DATA[6] - DATA[7]);
  519. TEMP_VERT[7][0] = delta * 255;
  520. TEMP_VERT[7][1] = 0;
  521. TEMP_VERT[7][2] = 255;
  522. a = 7;
  523. b = 8;
  524. break;
  525. case 8:
  526. delta = (linefax->tvalue[t_ndx] - DATA[7]) / (DATA[4] - DATA[7]);
  527. TEMP_VERT[8][0] = 0;
  528. TEMP_VERT[8][1] = delta * 255;
  529. TEMP_VERT[8][2] = 255;
  530. a = 5;
  531. b = 8;
  532. break;
  533. case 9:
  534. delta = (linefax->tvalue[t_ndx] - DATA[0]) / (DATA[4] - DATA[0]);
  535. TEMP_VERT[9][0] = 0;
  536. TEMP_VERT[9][1] = 255;
  537. TEMP_VERT[9][2] = delta * 255;
  538. a = 5;
  539. b = 1;
  540. break;
  541. case 10:
  542. delta = (linefax->tvalue[t_ndx] - DATA[1]) / (DATA[5] - DATA[1]);
  543. TEMP_VERT[10][0] = 255;
  544. TEMP_VERT[10][1] = 255;
  545. TEMP_VERT[10][2] = delta * 255;
  546. a = 6;
  547. b = 2;
  548. break;
  549. case 11:
  550. delta = (linefax->tvalue[t_ndx] - DATA[3]) / (DATA[7] - DATA[3]);
  551. TEMP_VERT[11][0] = 0;
  552. TEMP_VERT[11][1] = 0;
  553. TEMP_VERT[11][2] = delta * 255;
  554. a = 8;
  555. b = 4;
  556. break;
  557. case 12:
  558. delta = (linefax->tvalue[t_ndx] - DATA[2]) / (DATA[6] - DATA[2]);
  559. TEMP_VERT[12][0] = 255;
  560. TEMP_VERT[12][1] = 0;
  561. TEMP_VERT[12][2] = delta * 255;
  562. a = 7;
  563. b = 3;
  564. break;
  565. }
  566. TEMP_NORM[crnt_edge][0] = delta * (Data_Grad[a][0] - Data_Grad[b][0])
  567. + Data_Grad[b][0];
  568. TEMP_NORM[crnt_edge][1] = delta * (Data_Grad[a][1] - Data_Grad[b][1])
  569. + Data_Grad[b][1];
  570. TEMP_NORM[crnt_edge][2] = delta * (Data_Grad[a][2] - Data_Grad[b][2])
  571. + Data_Grad[b][2];
  572. normalize(TEMP_NORM[crnt_edge]);
  573. }
  574. }
  575. static void normalize(float n[3])
  576. {
  577. float l;
  578. l = sqrt((n[0] * n[0]) + (n[1] * n[1]) + (n[2] * n[2]));
  579. if (!l)
  580. l = 1;
  581. n[0] /= l;
  582. n[1] /= l;
  583. n[2] /= l;
  584. }