123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351 |
- #include "vizual.h"
- /* LOCALLY Global structures */
- static file_info *Headp;
- static struct dspec *B_spec;
- static struct Cap *Cap;
- static struct poly_info Polys[3 * (MAXTHRESH + 1)];
- static int x, y;
- static double Xlinterp();
- #define ANTICLOCKWISE 0
- #define CLOCKWISE 1
- /************************************** get_min_max *************************/
- /* get min and max values from the original data */
- static get_min_max(minmax, size, array)
- double *minmax;
- int size;
- double array[4];
- {
- register int i;
- double min, max;
- min = max = *array;
- for (i = 0; i < size; i++) {
- if (array[i] > max)
- max = array[i];
- else if (array[i] < min)
- min = array[i];
- }
- minmax[0] = min;
- minmax[1] = max;
- }
- /*************************************** side_to_xy **************************/
- static side_to_xy(xyray, pre, zz, side)
- double *xyray;
- struct poly_info *pre;
- double zz;
- int side;
- {
- double x1, x2;
- double y1, y2;
- int side2;
- double interp;
- side2 = next_higher(side, pre->vnum);
- x1 = pre->verts[side << 1];
- y1 = pre->verts[(side << 1) + 1];
- x2 = pre->verts[side2 << 1];
- y2 = pre->verts[(side2 << 1) + 1];
- /*
- debugf("%lf x1 %lf y1\n",x1,y1);
- debugf("%lf x2 %lf y2\n",x2,y2);
- */
- interp = Xlinterp(pre->data[side], zz, pre->data[side2]);
- if (x1 != x2)
- xyray[0] = x1 + (interp * (x2 - x1));
- else
- xyray[0] = x1;
- if (y1 != y2)
- xyray[1] = y1 + (interp * (y2 - y1));
- else
- xyray[1] = y2;
- }
- /********************************** split_poly *****************************/
- /* recursively subdivides polygons until no more threshold divide
- ** them then draws the polygon and falls thru to left over polygon
- ** code */
- void split_poly(ta, pnum, t)
- int pnum; /* index to current polygon */
- int ta; /* current threshold array */
- int t; /* current threshold index */
- {
- double minmax[2];
- double zz; /* current threshold */
- int num;
- int hits;
- int xing[4]; /* a list of the sides with hits */
- int tnum;
- int i;
- int new_pnum;
- int side;
- static int first;
- int n_verts;
- cmndln_info *tp;
- int drawn;
- num = 0;
- hits = 0;
- drawn = 0;
- tp = &(B_spec->threshes[ta]);
- if (t >= tp->nthres)
- return;
- zz = (double)tp->tvalue[t];
- if (t) { /* don't draw below 1st threshold */
- if (B_spec->in_out == INSIDE)
- tnum = t + B_spec->low;
- else if (ta == 0)
- /* tnum == t; *//* fix ? MN 2001 */
- tnum = t;
- else
- tnum = t + B_spec->hi;
- }
- /* calc min/max for each new poly */
- get_min_max(minmax, Polys[pnum].vnum, Polys[pnum].data);
- if (zz > (double)minmax[1]) { /* if entirely contained */
- if (t) {
- draw_cappolys(Headp, B_spec, Cap, &Polys[pnum], x, y, 1, tnum);
- }
- /*and we are done */
- return;
- }
- /* thresh in square */
- else if (WITHIN((double)minmax[0], zz, (double)minmax[1])) {
- /* this code from contour program: determine number of crossings (hits)
- ** if non-zero and even, then have 1 or 2 valid contours in cell
- */
- for (i = 0; i < Polys[pnum].vnum; i++) {
- if ((Polys[pnum].data[i] <= zz &&
- zz < Polys[pnum].data[(i + 1) % Polys[pnum].vnum]) ||
- (Polys[pnum].data[i] > zz &&
- zz >= Polys[pnum].data[(i + 1) % Polys[pnum].vnum])) {
- hits |= (1 << i); /* record which lines were crossed */
- xing[num] = i;
- num++;
- }
- }
- if (!num || num & 0x01) { /* zero or odd no contour in cell */
- /* just go on to next thresh */
- split_poly(ta, pnum, t + 1);
- }
- /* else split into two polygons */
- else {
- /* NUMBER OF XINGS = 2 */
- /* split the polygon and the reiterate */
- side = xing[0];
- /* first is set to true if the first split polygon is to be drawn */
- first = (zz > Polys[pnum].data[side]) ? 0 : 1;
- new_pnum = pnum + 1;
- n_verts = 0;
- /* 1st vert will be the location where the first xing occurs */
- /* not only are the vertices stored in the poly_info variable
- ** but also the data values at these vertices must be stored */
- Polys[new_pnum].data[n_verts] = zz;
- side_to_xy(&(Polys[new_pnum].verts[n_verts << 1]), &(Polys[pnum]),
- zz, side);
- n_verts++;
- side = next_higher(side, Polys[pnum].vnum);
- while (side != xing[1]) {
- Polys[new_pnum].data[n_verts] = Polys[pnum].data[side];
- Polys[new_pnum].verts[n_verts << 1] =
- Polys[pnum].verts[side << 1];
- Polys[new_pnum].verts[(n_verts << 1) + 1] =
- Polys[pnum].verts[(side << 1) + 1];
- n_verts++;
- side = next_higher(side, Polys[pnum].vnum);
- }
- Polys[new_pnum].data[n_verts] = Polys[pnum].data[side];
- Polys[new_pnum].verts[n_verts << 1] =
- Polys[pnum].verts[side << 1];
- Polys[new_pnum].verts[(n_verts << 1) + 1] =
- Polys[pnum].verts[(side << 1) + 1];
- n_verts++;
- Polys[new_pnum].data[n_verts] = zz;
- side_to_xy(&(Polys[new_pnum].verts[n_verts << 1]), &(Polys[pnum]),
- zz, side);
- n_verts++;
- Polys[new_pnum].vnum = n_verts;
- Polys[new_pnum].data[n_verts] = Polys[new_pnum].data[0];
- if (first) {
- if (t)
- draw_cappolys(Headp, B_spec, Cap, &Polys[new_pnum], x, y,
- 1, tnum);
- drawn = 1;
- }
- else {
- split_poly(ta, new_pnum, t + 1);
- }
- /*============================================================================*/
- /* NOW DO THE SECOND HALF OF THE SPLIT */
- side = xing[1];
- n_verts = 0;
- /* 1st vert will be the location that xing occurs */
- Polys[new_pnum].data[n_verts] = zz;
- side_to_xy(&Polys[new_pnum].verts[n_verts << 1], &(Polys[pnum]),
- zz, side);
- n_verts++;
- side = next_higher(side, Polys[pnum].vnum);
- while (side != xing[0]) {
- Polys[new_pnum].data[n_verts] = Polys[pnum].data[side];
- Polys[new_pnum].verts[n_verts << 1] =
- Polys[pnum].verts[side << 1];
- Polys[new_pnum].verts[(n_verts << 1) + 1] =
- Polys[pnum].verts[(side << 1) + 1];
- n_verts++;
- side = next_higher(side, Polys[pnum].vnum);
- }
- Polys[new_pnum].data[n_verts] = Polys[pnum].data[side];
- Polys[new_pnum].verts[n_verts << 1] =
- Polys[pnum].verts[side << 1];
- Polys[new_pnum].verts[(n_verts << 1) + 1] =
- Polys[pnum].verts[(side << 1) + 1];
- n_verts++;
- Polys[new_pnum].data[n_verts] = zz;
- side_to_xy(&Polys[new_pnum].verts[n_verts << 1], &(Polys[pnum]),
- zz, side);
- n_verts++;
- Polys[new_pnum].vnum = n_verts;
- Polys[new_pnum].data[n_verts] = Polys[new_pnum].data[0];
- if (!first) {
- if (t) {
- draw_cappolys(Headp, B_spec, Cap, &Polys[new_pnum], x, y,
- 1, tnum);
- }
- /* mark a flag */
- drawn = 1;
- }
- else {
- split_poly(ta, new_pnum, t + 1);
- }
- }
- } /*end WITHIN code */
- /* if no hits then ready to fall thru to left over node
- code which will be the tail end of the split_poly routine */
- if ((t < tp->nthres) && !drawn) {
- split_poly(ta, pnum, t + 1);
- }
- return;
- }
- /************************************** Xlinterp ****************************/
- /* rescale zz to a number between 0. and 1. */
- static double Xlinterp(zmin, zz, zmax)
- double zmin, zz, zmax;
- {
- if (zmin == zmax) /* div by zero. should never get here */
- return zmin;
- return (zz - zmin) / (zmax - zmin);
- }
- /******************************* next_higher *******************************/
- /* given sides 0,1,2,3, return number of next side in clockwise order */
- int next_higher(side, verts)
- int side, verts;
- {
- return ((side + 1) % verts);
- }
- int draw_cap(XHeadp, XB_spec, XCap)
- file_info *XHeadp;
- struct dspec *XB_spec;
- struct Cap *XCap;
- {
- int row, xdim;
- int ta;
- cmndln_info *tp;
- int org_tnum;
- /* if flat shading */
- Headp = XHeadp;
- if (Headp->linefax.litmodel == 1)
- glDisable(GL_COLOR_MATERIAL);
- else {
- glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
- glEnable(GL_COLOR_MATERIAL);
- }
- B_spec = XB_spec;
- Cap = XCap;
- xdim = Cap->Cols;
- for (y = Cap->miny; y < Cap->maxy; y++) { /* for each cell */
- row = y * Cap->Cols; /*shouldn't this be Rows? JCM NO. DPG */
- for (x = Cap->minx; x < Cap->maxx; x++) {
- Polys[0].data[0] = Polys[0].data[4] =
- (double)Cap->D_buff[row + xdim + x];
- /*BL*/ Polys[0].data[1] = (double)Cap->D_buff[row + xdim + x + 1]; /* BR */
- Polys[0].data[2] = (double)Cap->D_buff[row + x + 1]; /* TR */
- Polys[0].data[3] = (double)Cap->D_buff[row + x]; /* TL */
- /* for each threshold array */
- for (ta = 0; ta < 2 && (tp = &(B_spec->threshes[ta]))->nthres;
- ta++) {
- { /* build initial poly */
- Polys[0].verts[0] = 0.0;
- Polys[0].verts[1] = 1.0;
- Polys[0].verts[2] = 1.0;
- Polys[0].verts[3] = 1.0;
- Polys[0].verts[4] = 1.0;
- Polys[0].verts[5] = 0.0;
- Polys[0].verts[6] = 0.0;
- Polys[0].verts[7] = 0.0;
- Polys[0].verts[8] = 0.0;
- Polys[0].verts[9] = 1.0;
- Polys[0].vnum = 4;
- }
- /* First time */
- if (B_spec->in_out == INSIDE)
- org_tnum = B_spec->low;
- else
- org_tnum = ta == 0 ? 0 : B_spec->hi;
- split_poly(ta, 0, 0);
- }
- }
- }
- glDisable(GL_COLOR_MATERIAL);
- }
|