iso_surface.c 19 KB

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