draw_cap_ogl.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. #include "vizual.h"
  2. /* LOCALLY Global structures */
  3. static file_info *Headp;
  4. static struct dspec *B_spec;
  5. static struct Cap *Cap;
  6. static struct poly_info Polys[3 * (MAXTHRESH + 1)];
  7. static int x, y;
  8. static double Xlinterp();
  9. #define ANTICLOCKWISE 0
  10. #define CLOCKWISE 1
  11. /************************************** get_min_max *************************/
  12. /* get min and max values from the original data */
  13. static get_min_max(minmax, size, array)
  14. double *minmax;
  15. int size;
  16. double array[4];
  17. {
  18. register int i;
  19. double min, max;
  20. min = max = *array;
  21. for (i = 0; i < size; i++) {
  22. if (array[i] > max)
  23. max = array[i];
  24. else if (array[i] < min)
  25. min = array[i];
  26. }
  27. minmax[0] = min;
  28. minmax[1] = max;
  29. }
  30. /*************************************** side_to_xy **************************/
  31. static side_to_xy(xyray, pre, zz, side)
  32. double *xyray;
  33. struct poly_info *pre;
  34. double zz;
  35. int side;
  36. {
  37. double x1, x2;
  38. double y1, y2;
  39. int side2;
  40. double interp;
  41. side2 = next_higher(side, pre->vnum);
  42. x1 = pre->verts[side << 1];
  43. y1 = pre->verts[(side << 1) + 1];
  44. x2 = pre->verts[side2 << 1];
  45. y2 = pre->verts[(side2 << 1) + 1];
  46. /*
  47. debugf("%lf x1 %lf y1\n",x1,y1);
  48. debugf("%lf x2 %lf y2\n",x2,y2);
  49. */
  50. interp = Xlinterp(pre->data[side], zz, pre->data[side2]);
  51. if (x1 != x2)
  52. xyray[0] = x1 + (interp * (x2 - x1));
  53. else
  54. xyray[0] = x1;
  55. if (y1 != y2)
  56. xyray[1] = y1 + (interp * (y2 - y1));
  57. else
  58. xyray[1] = y2;
  59. }
  60. /********************************** split_poly *****************************/
  61. /* recursively subdivides polygons until no more threshold divide
  62. ** them then draws the polygon and falls thru to left over polygon
  63. ** code */
  64. void split_poly(ta, pnum, t)
  65. int pnum; /* index to current polygon */
  66. int ta; /* current threshold array */
  67. int t; /* current threshold index */
  68. {
  69. double minmax[2];
  70. double zz; /* current threshold */
  71. int num;
  72. int hits;
  73. int xing[4]; /* a list of the sides with hits */
  74. int tnum;
  75. int i;
  76. int new_pnum;
  77. int side;
  78. static int first;
  79. int n_verts;
  80. cmndln_info *tp;
  81. int drawn;
  82. num = 0;
  83. hits = 0;
  84. drawn = 0;
  85. tp = &(B_spec->threshes[ta]);
  86. if (t >= tp->nthres)
  87. return;
  88. zz = (double)tp->tvalue[t];
  89. if (t) { /* don't draw below 1st threshold */
  90. if (B_spec->in_out == INSIDE)
  91. tnum = t + B_spec->low;
  92. else if (ta == 0)
  93. /* tnum == t; *//* fix ? MN 2001 */
  94. tnum = t;
  95. else
  96. tnum = t + B_spec->hi;
  97. }
  98. /* calc min/max for each new poly */
  99. get_min_max(minmax, Polys[pnum].vnum, Polys[pnum].data);
  100. if (zz > (double)minmax[1]) { /* if entirely contained */
  101. if (t) {
  102. draw_cappolys(Headp, B_spec, Cap, &Polys[pnum], x, y, 1, tnum);
  103. }
  104. /*and we are done */
  105. return;
  106. }
  107. /* thresh in square */
  108. else if (WITHIN((double)minmax[0], zz, (double)minmax[1])) {
  109. /* this code from contour program: determine number of crossings (hits)
  110. ** if non-zero and even, then have 1 or 2 valid contours in cell
  111. */
  112. for (i = 0; i < Polys[pnum].vnum; i++) {
  113. if ((Polys[pnum].data[i] <= zz &&
  114. zz < Polys[pnum].data[(i + 1) % Polys[pnum].vnum]) ||
  115. (Polys[pnum].data[i] > zz &&
  116. zz >= Polys[pnum].data[(i + 1) % Polys[pnum].vnum])) {
  117. hits |= (1 << i); /* record which lines were crossed */
  118. xing[num] = i;
  119. num++;
  120. }
  121. }
  122. if (!num || num & 0x01) { /* zero or odd no contour in cell */
  123. /* just go on to next thresh */
  124. split_poly(ta, pnum, t + 1);
  125. }
  126. /* else split into two polygons */
  127. else {
  128. /* NUMBER OF XINGS = 2 */
  129. /* split the polygon and the reiterate */
  130. side = xing[0];
  131. /* first is set to true if the first split polygon is to be drawn */
  132. first = (zz > Polys[pnum].data[side]) ? 0 : 1;
  133. new_pnum = pnum + 1;
  134. n_verts = 0;
  135. /* 1st vert will be the location where the first xing occurs */
  136. /* not only are the vertices stored in the poly_info variable
  137. ** but also the data values at these vertices must be stored */
  138. Polys[new_pnum].data[n_verts] = zz;
  139. side_to_xy(&(Polys[new_pnum].verts[n_verts << 1]), &(Polys[pnum]),
  140. zz, side);
  141. n_verts++;
  142. side = next_higher(side, Polys[pnum].vnum);
  143. while (side != xing[1]) {
  144. Polys[new_pnum].data[n_verts] = Polys[pnum].data[side];
  145. Polys[new_pnum].verts[n_verts << 1] =
  146. Polys[pnum].verts[side << 1];
  147. Polys[new_pnum].verts[(n_verts << 1) + 1] =
  148. Polys[pnum].verts[(side << 1) + 1];
  149. n_verts++;
  150. side = next_higher(side, Polys[pnum].vnum);
  151. }
  152. Polys[new_pnum].data[n_verts] = Polys[pnum].data[side];
  153. Polys[new_pnum].verts[n_verts << 1] =
  154. Polys[pnum].verts[side << 1];
  155. Polys[new_pnum].verts[(n_verts << 1) + 1] =
  156. Polys[pnum].verts[(side << 1) + 1];
  157. n_verts++;
  158. Polys[new_pnum].data[n_verts] = zz;
  159. side_to_xy(&(Polys[new_pnum].verts[n_verts << 1]), &(Polys[pnum]),
  160. zz, side);
  161. n_verts++;
  162. Polys[new_pnum].vnum = n_verts;
  163. Polys[new_pnum].data[n_verts] = Polys[new_pnum].data[0];
  164. if (first) {
  165. if (t)
  166. draw_cappolys(Headp, B_spec, Cap, &Polys[new_pnum], x, y,
  167. 1, tnum);
  168. drawn = 1;
  169. }
  170. else {
  171. split_poly(ta, new_pnum, t + 1);
  172. }
  173. /*============================================================================*/
  174. /* NOW DO THE SECOND HALF OF THE SPLIT */
  175. side = xing[1];
  176. n_verts = 0;
  177. /* 1st vert will be the location that xing occurs */
  178. Polys[new_pnum].data[n_verts] = zz;
  179. side_to_xy(&Polys[new_pnum].verts[n_verts << 1], &(Polys[pnum]),
  180. zz, side);
  181. n_verts++;
  182. side = next_higher(side, Polys[pnum].vnum);
  183. while (side != xing[0]) {
  184. Polys[new_pnum].data[n_verts] = Polys[pnum].data[side];
  185. Polys[new_pnum].verts[n_verts << 1] =
  186. Polys[pnum].verts[side << 1];
  187. Polys[new_pnum].verts[(n_verts << 1) + 1] =
  188. Polys[pnum].verts[(side << 1) + 1];
  189. n_verts++;
  190. side = next_higher(side, Polys[pnum].vnum);
  191. }
  192. Polys[new_pnum].data[n_verts] = Polys[pnum].data[side];
  193. Polys[new_pnum].verts[n_verts << 1] =
  194. Polys[pnum].verts[side << 1];
  195. Polys[new_pnum].verts[(n_verts << 1) + 1] =
  196. Polys[pnum].verts[(side << 1) + 1];
  197. n_verts++;
  198. Polys[new_pnum].data[n_verts] = zz;
  199. side_to_xy(&Polys[new_pnum].verts[n_verts << 1], &(Polys[pnum]),
  200. zz, side);
  201. n_verts++;
  202. Polys[new_pnum].vnum = n_verts;
  203. Polys[new_pnum].data[n_verts] = Polys[new_pnum].data[0];
  204. if (!first) {
  205. if (t) {
  206. draw_cappolys(Headp, B_spec, Cap, &Polys[new_pnum], x, y,
  207. 1, tnum);
  208. }
  209. /* mark a flag */
  210. drawn = 1;
  211. }
  212. else {
  213. split_poly(ta, new_pnum, t + 1);
  214. }
  215. }
  216. } /*end WITHIN code */
  217. /* if no hits then ready to fall thru to left over node
  218. code which will be the tail end of the split_poly routine */
  219. if ((t < tp->nthres) && !drawn) {
  220. split_poly(ta, pnum, t + 1);
  221. }
  222. return;
  223. }
  224. /************************************** Xlinterp ****************************/
  225. /* rescale zz to a number between 0. and 1. */
  226. static double Xlinterp(zmin, zz, zmax)
  227. double zmin, zz, zmax;
  228. {
  229. if (zmin == zmax) /* div by zero. should never get here */
  230. return zmin;
  231. return (zz - zmin) / (zmax - zmin);
  232. }
  233. /******************************* next_higher *******************************/
  234. /* given sides 0,1,2,3, return number of next side in clockwise order */
  235. int next_higher(side, verts)
  236. int side, verts;
  237. {
  238. return ((side + 1) % verts);
  239. }
  240. int draw_cap(XHeadp, XB_spec, XCap)
  241. file_info *XHeadp;
  242. struct dspec *XB_spec;
  243. struct Cap *XCap;
  244. {
  245. int row, xdim;
  246. int ta;
  247. cmndln_info *tp;
  248. int org_tnum;
  249. /* if flat shading */
  250. Headp = XHeadp;
  251. if (Headp->linefax.litmodel == 1)
  252. glDisable(GL_COLOR_MATERIAL);
  253. else {
  254. glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
  255. glEnable(GL_COLOR_MATERIAL);
  256. }
  257. B_spec = XB_spec;
  258. Cap = XCap;
  259. xdim = Cap->Cols;
  260. for (y = Cap->miny; y < Cap->maxy; y++) { /* for each cell */
  261. row = y * Cap->Cols; /*shouldn't this be Rows? JCM NO. DPG */
  262. for (x = Cap->minx; x < Cap->maxx; x++) {
  263. Polys[0].data[0] = Polys[0].data[4] =
  264. (double)Cap->D_buff[row + xdim + x];
  265. /*BL*/ Polys[0].data[1] = (double)Cap->D_buff[row + xdim + x + 1]; /* BR */
  266. Polys[0].data[2] = (double)Cap->D_buff[row + x + 1]; /* TR */
  267. Polys[0].data[3] = (double)Cap->D_buff[row + x]; /* TL */
  268. /* for each threshold array */
  269. for (ta = 0; ta < 2 && (tp = &(B_spec->threshes[ta]))->nthres;
  270. ta++) {
  271. { /* build initial poly */
  272. Polys[0].verts[0] = 0.0;
  273. Polys[0].verts[1] = 1.0;
  274. Polys[0].verts[2] = 1.0;
  275. Polys[0].verts[3] = 1.0;
  276. Polys[0].verts[4] = 1.0;
  277. Polys[0].verts[5] = 0.0;
  278. Polys[0].verts[6] = 0.0;
  279. Polys[0].verts[7] = 0.0;
  280. Polys[0].verts[8] = 0.0;
  281. Polys[0].verts[9] = 1.0;
  282. Polys[0].vnum = 4;
  283. }
  284. /* First time */
  285. if (B_spec->in_out == INSIDE)
  286. org_tnum = B_spec->low;
  287. else
  288. org_tnum = ta == 0 ? 0 : B_spec->hi;
  289. split_poly(ta, 0, 0);
  290. }
  291. }
  292. }
  293. glDisable(GL_COLOR_MATERIAL);
  294. }