/* render.c */ /* * Vis5D system for visualizing five dimensional gridded data sets. * Copyright (C) 1990 - 2000 Bill Hibbard, Johan Kellum, Brian Paul, * Dave Santek, and Andre Battaiola. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * As a special exception to the terms of the GNU General Public * License, you are permitted to link Vis5D with (and distribute the * resulting source and executables) the LUI library (copyright by * Stellar Computer Inc. and licensed for distribution with Vis5D), * the McIDAS library, and/or the NetCDF library, where those * libraries are governed by the terms of their own licenses. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include "../config.h" #include #include #include #include #include #include "anim.h" #include "api.h" #include "box.h" #include "matrix.h" #include "globals.h" #include "graphics.h" #include "grid.h" #include "labels.h" #include "map.h" #include "memory.h" #include "misc.h" #include "proj.h" #include "queue.h" #include "sounding.h" #include "sync.h" #include "topo.h" #include "vis5d.h" #include "volume.h" #include "v5d.h" extern int vis5d_verbose; #define MAX(A,B) ( (A) > (B) ? (A) : (B) ) #define MIN(A,B) ( (A) < (B) ? (A) : (B) ) #define ABS(X) ( (X) < 0.0f ? -(X) : (X) ) #define TICK_SIZE 0.05 #define CLOCK_SEGMENTS 36 #define VERT(Z) (ctx->VerticalSystem==VERT_NONEQUAL_MB ? height_to_pressure(Z) : (Z)) #define VERTPRIME(Z) (dtx->VerticalSystem==VERT_NONEQUAL_MB ? height_to_pressure(Z) : (Z)) /* Vertical spacing between rows of text: (in pixels) */ #define VSPACE 1 /*** float2string ***************************************************** Convert a float into an ascii string. **********************************************************************/ /* MJK 12.01.98 */ /* old now void float2string( float f, char *str ) { if (f==0.0 || fabs(f)<0.01) strcpy( str, "0.0" ); else if (f>=100.0 || f<=-100.0) sprintf(str, "%d", (int) f ); else sprintf(str, "%4.2f", f ); } */ /* MJK 12.01.98 */ void float2string (Display_Context dtx, int icoord, float f, char *str) { float fmin, fmax, frng; if (fabs (f) < 0.01) f = 0.0; if (dtx->CoordFlag) { switch (icoord) { case 0: fmin = 1.0; fmax = dtx->Nc; break; case 1: fmin = 1.0; fmax = dtx->Nr; break; case 2: fmin = 1.0; fmax = dtx->MaxNl; break; } } else { switch (icoord) { case 0: fmin = dtx->WestBound; fmax = dtx->EastBound; break; case 1: fmin = dtx->SouthBound; fmax = dtx->NorthBound; break; case 2: fmin = VERTPRIME(dtx->BottomBound); fmax = VERTPRIME(dtx->TopBound); break; } } frng = (fmin < fmax) ? fmax - fmin : fmin - fmax; if (frng < 500.0) sprintf (str, "%.2f", f); else sprintf (str, "%.0f", f); } /*** check_view_side ***************************************************** Determine if the plane of a clockwise series of points faces the camera. return: -1 plane faces away from the camera 0 plane includes the camera 1 plane faces the camera **********************************************************************/ int check_view_side (Context ctx, int type, int num) { int iside; float xyz[3][3], xy[3][2], area; switch (type) { /* Need to work on non-vertical slices */ case VSLICE: xyz[0][0] = ctx->Variable[num]->VSliceRequest->X2; xyz[0][1] = ctx->Variable[num]->VSliceRequest->Y2; xyz[0][2] = ctx->dpy_ctx->Zmin; xyz[1][0] = ctx->Variable[num]->VSliceRequest->X1; xyz[1][1] = ctx->Variable[num]->VSliceRequest->Y1; xyz[1][2] = ctx->dpy_ctx->Zmin; xyz[2][0] = ctx->Variable[num]->VSliceRequest->X1; xyz[2][1] = ctx->Variable[num]->VSliceRequest->Y1; xyz[2][2] = ctx->dpy_ctx->Zmax; break; default: return 0; } project (&xyz[0][0], &xy[0][0], &xy[0][1]); project (&xyz[1][0], &xy[1][0], &xy[1][1]); project (&xyz[2][0], &xy[2][0], &xy[2][1]); area = ((xy[0][0] - xy[2][0]) * (xy[0][1] + xy[2][1])) + ((xy[1][0] - xy[0][0]) * (xy[1][1] + xy[0][1])) + ((xy[2][0] - xy[1][0]) * (xy[2][1] + xy[1][1])); iside = (area > 0.0) ? -1 : (area < 0.0) ? 1 : 0; return iside; } int flip_vslice_end_for_end (Context ctx, int time, int var) { float x; x = ctx->Variable[var]->VSliceRequest->R1; ctx->Variable[var]->VSliceRequest->R1 = ctx->Variable[var]->VSliceRequest->C1; ctx->Variable[var]->VSliceRequest->C1 = x; x = ctx->Variable[var]->VSliceRequest->R2; ctx->Variable[var]->VSliceRequest->R2 = ctx->Variable[var]->VSliceRequest->C2; ctx->Variable[var]->VSliceRequest->C2 = x; x = ctx->Variable[var]->VSliceRequest->X1; ctx->Variable[var]->VSliceRequest->X1 = ctx->Variable[var]->VSliceRequest->X2; ctx->Variable[var]->VSliceRequest->X2 = x; x = ctx->Variable[var]->VSliceRequest->Y1; ctx->Variable[var]->VSliceRequest->Y1 = ctx->Variable[var]->VSliceRequest->Y2; ctx->Variable[var]->VSliceRequest->Y2 = x; x = ctx->Variable[var]->VSliceRequest->Lat1; ctx->Variable[var]->VSliceRequest->Lat1 = ctx->Variable[var]->VSliceRequest->Lat2; ctx->Variable[var]->VSliceRequest->Lat2 = x; x = ctx->Variable[var]->VSliceRequest->Lon1; ctx->Variable[var]->VSliceRequest->Lon1 = ctx->Variable[var]->VSliceRequest->Lon2; ctx->Variable[var]->VSliceRequest->Lon2 = x; request_vslice (ctx, time, var, (time == ctx->CurTime)); return 0; } /* same code as in uvwwidget.c */ char *return_var_plus_index( char *varname, int index ) { int yo; /* WLH 20 Oct 98 char whole[40]; */ /* WLH 20 Oct 98 */ char* whole; char num[40]; /* WLH 20 Oct 98 */ whole = (char *) malloc(40); if (index <0 || varname[0] == 0){ whole[0] = 0; return whole; } for (yo = 0; yo < 17; yo++){ if (varname[yo] == '\0' || varname[yo] == ' '){ yo -=1; whole[yo+1] = '.'; sprintf(num, "%d\n", index ); if (index > 99 && yo < 15){ whole[yo+2] = num[0]; whole[yo+3] = num[1]; whole[yo+4] = num[2]; whole[yo+5] = '\0'; return whole; } else if ( index > 9 && yo < 16){ whole[yo+2] = num[0]; whole[yo+3] = num[1]; whole[yo+4] = '\0'; return whole; } else{ whole[yo+2] = num[0]; whole[yo+3] = '\0'; return whole; } } whole[yo] = varname[yo]; } whole[yo] = '\0'; return whole; } /*** plot_string ****************************************************** Plot (draw) a string in 3-D. At this time, only strings of digits, periods, and dashes are implemented. Input: f - the string to plot. startx, y, z - the point in 3-D to start at. base - vector indicating text baseline. up - vector indicating upright direction for text. rjustify - non-zero value indicates right justify the text. **********************************************************************/ void plot_string( char *str, float startx, float starty, float startz, float base[], float up[], int rjustify ) { static float zero[] = { 0,0, 0,.8, .4,.8, .4,0, 0,0 }, one[] = { 0,0, 0,.8 }, two[] = { .4,0, 0,0, 0,.4, .4,.4, .4,.8, 0,.8 }, three[] = { 0,0, .4,0, .4,.4, 0,.4, .4,.4, .4,.8, 0,.8 }, four[] = { 0,.8, 0,.4, .4,.4, .4,.8, .4,0 }, five[] = { 0,0, .4,0, .4,.4, 0,.4, 0,.8, .4,.8 }, six[] = { .4,.8, 0,.8, 0,0, .4,0, .4,.4, 0,.4 }, seven[] = { 0,.7, 0,.8, .4,.8, .4,0 }, eight[] = { 0,0, 0,.8, .4,.8, .4,0, 0,0, 0,.4, .4,.4 }, nine[] = { .4,.4, 0,.4, 0,.8, .4,.8, .4,0 }, dash[] = { 0,.4, .4,.4 }, dot[] = { 0,0, 0,.1, .1,.1, .1,0, 0,0 }, /*MiB 03/2001 Longitudes*/ west[] = {0.,0.8, 0.,0., 0.2,0.4, 0.4,0.0, 0.4,0.8}, east[] = {0.4,0.8, 0.0,0.8, 0.0,0.4, 0.3,0.4, 0.0,0.4, 0.0,0.0, 0.4,0.0}, north[] = {0.,0.0, 0.,0.8, 0.4,0.0, 0.4,0.8}, south[] = {0.0,0.1, 0.1,0.0, 0.3,0.0, 0.4,0.1, 0.4,0.3, 0.0,0.5, 0.0,0.7, 0.1,0.8, 0.3,0.8, 0.4,0.7}; static float *index[16] = { zero, one, two, three, four, five, six, seven, eight, nine, dash, dot, west, east, north, south}; static float width[16] = { 0.6, 0.2, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.3, 0.6, 0.6 , 0.6, 0.6}; static int verts[16] = { 5, 2, 6, 7, 5, 6, 6, 4, 7, 5, 2, 5 ,5, 7, 4, 10}; float *temp, plot[100][3]; float cx, cy, cz; int i, j, k, len; cx = startx; cy = starty; cz = startz; len = strlen(str); if (rjustify) { /* draw right justified text */ for (i=len-1; i>=0; i--) { if (str[i]=='-') k = 10; else if (str[i]=='.') k = 11; /*MiB*/ else if (str[i]=='W') k = 12; else if (str[i]=='E') k = 13; else if (str[i]=='N') k = 14; else if (str[i]=='S') /*MiB*/ k = 15; else if (str[i]>='0' && str[i]<='9') k = str[i] - '0'; else continue; /* calculate position for this char */ cx += width[k]*base[0]; cy += width[k]*base[1]; cz += width[k]*base[2]; /* make the vertex array for this character */ temp = index[k]; for (j=0; j='0' && str[i]<='9') k = str[i] - '0'; else continue; /* make the vertex array for this character */ temp = index[k]; for (j=0; jdpy_ctx; if (dtx->numofctxs == 1){ return 1; } if (ctx->NumTimes == 1){ return 1; } ctxcurtime = ldtime = lstime = 0; for( yo = 0; yo < dtx->numofctxs; yo ++){ spandex = dtx->TimeStep[dtxcurtime].owners[yo]; ctime = dtx->TimeStep[dtxcurtime].ownerstimestep[yo]; vis5d_get_ctx_time_stamp( spandex, ctime, &dtime, &stime); if (spandex == ctx->context_index){ ctxcurtime = ctime; ctxdtime = dtime; ctxstime = stime; } else if (dtime > ldtime || (dtime == ldtime && stime > lstime)){ ldtime = dtime; lstime = stime; } } if (ctxcurtime == 0 && (ctxdtime > ldtime || (ctxdtime == ldtime && ctxstime > lstime))){ return 0; } else if (ctxcurtime == ctx->NumTimes-1 && (ctxdtime < ldtime || (ctxdtime == ldtime && ctxstime < lstime))){ return 0; } else{ return 1; } } /* * Draw the tick mark for a horizontal slice. * Input: level - grid level * z - graphics z coord * height - geographic height coord */ static void draw_horizontal_slice_tick( Display_Context dtx, float level, float z, float height ) { float v[2][3]; static float base[3] = { 0.035, -0.035, 0.0 }; static float up[3] = { 0.0, 0.0, 0.07 }; char str[1000]; /* vertices for tick mark */ v[0][0] = dtx->Xmax; v[0][1] = dtx->Ymin; v[0][2] = z; v[1][0] = dtx->Xmax + 0.05; v[1][1] = dtx->Ymin - 0.05; v[1][2] = z; polyline( v, 2 ); /* the label */ if (dtx->CoordFlag) { /* MJK 12.01.98 */ float2string(dtx, 2, level+1.0, str ); } else { /* MJK 12.01.98 */ float2string(dtx, 2, VERTPRIME(height), str ); } plot_string( str, dtx->Xmax+0.07, dtx->Ymin-0.07, z, base,up, 0 ); } /* * Draw a tick mark for a vertical slice. * Input: row, col - position in grid coords * x, y - position in graphics coords * lat,lon - position in geographic coords */ static void draw_vertical_slice_tick( Display_Context dtx, float row, float col, float x, float y, float lat, float lon ) { float v[2][3]; int cc, rr; /* base and up vectors for drawing 3-D text */ static float b2[3] = { 0.05, 0.0, 0.0 }, u2[3] = { 0.0, 0.05, 0.0 }; static float b3[3] = { -0.05, 0.0, 0.0 }, u3[3] = { 0.0, 0.05, 0.0 }; char str[1000]; cc = (int) (col); rr = (int) (row); if (cc <= 0) { /* draw on top-west edge */ v[0][0] = x; v[0][1] = y; v[0][2] = dtx->Zmax; v[1][0] = x-0.05; v[1][1] = y; v[1][2] = dtx->Zmax; polyline( v, 2 ); if (dtx->CoordFlag) { /* MJK 12.01.98 */ float2string(dtx, 1, row+1, str ); } else { /* MJK 12.01.98 */ float2string(dtx, 1, lat, str ); } plot_string( str, x-0.07, y, dtx->Zmax, b3, u3, 1 ); } else if (cc >= dtx->Nc-1) { /* draw on top-east edge */ v[0][0] = x; v[0][1] = y; v[0][2] = dtx->Zmax; v[1][0] = x+0.05; v[1][1] = y; v[1][2] = dtx->Zmax; polyline( v, 2 ); if (dtx->CoordFlag) { /* MJK 12.01.98 */ float2string(dtx, 1, row+1, str ); } else { /* MJK 12.01.98 */ float2string(dtx, 1, lat, str ); } plot_string( str, x+0.07, y, dtx->Zmax, b2, u2, 0 ); } else if (rr <=0) { /* draw on top-north edge */ v[0][0] = x; v[0][1] = y; v[0][2] = dtx->Zmax; v[1][0] = x; v[1][1] = y+0.05; v[1][2] = dtx->Zmax; polyline( v, 2 ); if (dtx->CoordFlag) { /* MJK 12.01.98 */ float2string(dtx, 0, col+1.0, str ); } else { /* MJK 12.01.98 */ float2string(dtx, 0, lon, str ); } plot_string( str, x-0.07, y+0.07, dtx->Zmax, b2,u2, 0 ); } else { /* draw on top-south edge */ v[0][0] = x; v[0][1] = y; v[0][2] = dtx->Zmax; v[1][0] = x; v[1][1] = y-0.05; v[1][2] = dtx->Zmax; polyline( v, 2 ); if (dtx->CoordFlag) { /* MJK 12.01.98 */ float2string(dtx, 0, col+1.0, str ); } else { /* MJK 12.01.98 */ float2string(dtx, 0, lon, str ); } plot_string( str, x-0.07, y-0.12, dtx->Zmax, b2,u2, 0 ); } } /* * Print the current cursor position. */ static void print_cursor_position( Display_Context dtx, int it ) { static float bx[3] = { 0.05, 0.0, 0.0 }, ux[3] = { 0.0, 0.05, 0.05 }; static float by[3] = { -0.035, 0.0, -0.035 }, uy[3] = { 0.0, 0.07, 0.0 }; static float bz[3] = { -0.035, -0.035, 0.0 }, uz[3] = { 0.0, 0.0, 0.07 }; float v[6][3]; float x, y, z, xx, yy; char str[100], xdir1[8],ydir1[8]; /* MJK 12.01.98 */ float lat, lon, hgt, row, col, lev; int ix; char fmt[] = {"%s: %9.3f %s "}; /* MiB 03/2001 Longitudes in [-180, 180] Intitialize...*/ xdir1[0] = ' '; xdir1[1] = '\0'; ydir1[0] = ' '; ydir1[1] = '\0'; /* MJK 12.01.98 begin*/ if ((dtx->DisplayProbe) || (dtx->DisplaySound)){ /* MJK 3.29.99 */ if (dtx->Reversed){ set_color (PACK_COLOR(0,0,0,255)); } else{ set_color (dtx->BoxColor); } } else{ set_color( *dtx->CursorColor ); } /* end MJK 12.01.98 */ if (dtx->Projection==PROJ_LINEAR || dtx->Projection==PROJ_GENERIC) { /* Rectangular box: put labels along edge of box in 3-D */ set_depthcue( dtx->DepthCue ); /* draw tick marks */ v[0][0] = v[1][0] = dtx->CursorX; v[0][1] = dtx->Ymin; v[1][1] = dtx->Ymin-0.05; v[0][2] = dtx->Zmin; v[1][2] = dtx->Zmin-0.05; v[2][0] = dtx->Xmin; v[3][0] = dtx->Xmin-0.05; v[2][1] = v[3][1] = dtx->CursorY; v[2][2] = dtx->Zmin; v[3][2] = dtx->Zmin-0.05; v[4][0] = dtx->Xmin; v[5][0] = dtx->Xmin-0.05; v[4][1] = dtx->Ymin; v[5][1] = dtx->Ymin-0.05; v[4][2] = v[5][2] = dtx->CursorZ; if (dtx->DisplaySound) { v[5][0] = 0; v[5][1] = 0; v[4][0] = 0; v[4][1] = 0; } disjointpolyline( v, 6 ); /* draw position labels */ if (dtx->CoordFlag) { /* display cursor position in grid coordinates */ xyzPRIME_to_gridPRIME( dtx, it, -1, dtx->CursorX, dtx->CursorY, dtx->CursorZ, &y, &x, &z ); x += 1.0; y += 1.0; z += 1.0; } else { /* display cursor position in geographic coordinates */ xyzPRIME_to_geo( dtx, it, -1, dtx->CursorX, dtx->CursorY, dtx->CursorZ, &y, &x, &z ); z = VERTPRIME(z); } /*MiB 03/2001 limit range to -180, 180 */ xx = x; if (xx < -180.){ xx = 360. + xx; } if (xx > 180.){ xx = -360. + xx; } /*MiB 03/2001 Define East/West */ if (xx > 0.){ xdir1[0] = 'W'; } else { xdir1[0] = 'E'; xx = xx *(-1.); } /*MiB 03/2001 Define North/South */ yy = y; if (yy > 0.){ ydir1[0] = 'N'; } else { ydir1[0] = 'S'; yy = yy *(-1.); } /* MJK 12.01.98 */ float2string(dtx, 0, xx, str ); /*MiB*/ strcat(str,xdir1); plot_string( str, dtx->CursorX-0.04, dtx->Ymin-0.1, dtx->Zmin-0.125, bx, ux, 0 ); float2string(dtx, 1, yy, str ); /*MiB*/ strcat(str,ydir1); plot_string( str, dtx->Xmin-0.075, dtx->CursorY-0.02, dtx->Zmin-0.075, by, uy, 1 ); float2string(dtx, 2, z, str ); if (!dtx->DisplaySound) plot_string( str, dtx->Xmin-0.07, dtx->Ymin-0.07, dtx->CursorZ+0.005, bz, uz, 1 ); set_depthcue( 0 ); } /* MJK 12.01.98 */ ix = dtx->Nr; if (dtx->Nc > ix) ix = dtx->Nc; if (dtx->MaxNl > ix) ix = dtx->MaxNl; x = ix; v[0][0] = dtx->Xmin, v[0][1] = dtx->Ymin, v[0][2] = dtx->Zmin; v[1][0] = dtx->Xmax, v[1][1] = dtx->Ymax, v[1][2] = dtx->Zmax; v[2][0] = dtx->Xmin, v[2][1] = dtx->Ymax, v[2][2] = dtx->Zmax; v[3][0] = dtx->Xmax, v[3][1] = dtx->Ymin, v[3][2] = dtx->Zmax; for (ix = 0; ix < 4; ix++) { xyzPRIME_to_geo (dtx, it, -1, v[ix][0], v[ix][1], v[ix][2], &lat, &lon, &hgt); if (lat < 0.0) lat = -lat; if (lon < 0.0) lon = -lon; hgt = VERTPRIME(hgt); if (lat > x) x = lat; if (lon > x) x = lon; if (hgt > x) x = hgt; } sprintf (str, "%.3f", x); ix = strchr (str, '.') - str; if (ix < 1) ix = 1; fmt[5] = (ix + 4) + '0'; sprintf (str, fmt, "XXX", x, "xx"); ix = dtx->WinWidth - (text_width (dtx->gfx[WINDOW_3D_FONT]->font,str)); if (dtx->CoordFlag) { /* display cursor position in grid coordinates */ xyzPRIME_to_gridPRIME (dtx, it, -1, dtx->CursorX, dtx->CursorY, dtx->CursorZ, &row, &col, &lev); sprintf( str, "Row: %g", row+1.0 ); draw_text( ix, (dtx->gfx[WINDOW_3D_FONT]->FontHeight+VSPACE), str ); sprintf( str, "Col: %g", col+1.0 ); draw_text( ix, 2*(dtx->gfx[WINDOW_3D_FONT]->FontHeight+VSPACE), str ); if (!dtx->DisplaySound) { sprintf( str, "Lev: %g", lev+1.0 ); draw_text( ix, 3*(dtx->gfx[WINDOW_3D_FONT]->FontHeight+VSPACE), str ); } } else { /* display cursor position in geographic coordinates */ xyzPRIME_to_geo (dtx, it, -1, dtx->CursorX, dtx->CursorY, dtx->CursorZ, &lat, &lon, &hgt); if (dtx->Projection == PROJ_GENERIC) { sprintf (str, fmt, "Row", lat, ""); draw_text( ix, (dtx->gfx[WINDOW_3D_FONT]->FontHeight+VSPACE), str ); sprintf (str, fmt, "Col", lon, ""); draw_text( ix, 2*(dtx->gfx[WINDOW_3D_FONT]->FontHeight+VSPACE), str ); } else { char hemi[] = {"X"}; /* hemispheres are "Wisconsin-centric" ;-) */ hemi[0] = 'N'; if (lat < 0.0) lat = -lat, hemi[0] = 'S'; sprintf (str, fmt, "Lat", lat, hemi); draw_text( ix, (dtx->gfx[WINDOW_3D_FONT]->FontHeight+VSPACE), str ); hemi[0] = 'W'; if (lon < 0.0) lon = -lon, hemi[0] = 'E'; /*MiB*/ if (lon > 180.) lon = -360. + lon, hemi[0] = 'W'; /*MiB*/ if (lon < 0.0) lon = -lon, hemi[0] = 'E'; sprintf (str, fmt, "Lon", lon, hemi); draw_text( ix, 2*(dtx->gfx[WINDOW_3D_FONT]->FontHeight+VSPACE), str ); } if (!dtx->DisplaySound) { if (dtx->VerticalSystem == VERT_NONEQUAL_MB) sprintf (str, fmt, "Hgt", VERTPRIME(hgt), "mb"); else sprintf (str, fmt, "Hgt", hgt, "km"); draw_text( ix, 3*(dtx->gfx[WINDOW_3D_FONT]->FontHeight+VSPACE), str ); } } /* end MJK 12.01.98 */ } /* * Examine the entries of a color lookup table to determine the alpha value. * If the alpha is the same for all entries return that value. If the * alpha varies between entries return -1. * Input: color_table - array of color values * size - number of entries in table * Return: -1 or constant alpha value */ int get_alpha( unsigned int color_table[], int size ) { int alpha, i; /* Check for variable vs. constant alpha */ alpha = UNPACK_ALPHA( color_table[0] ); for (i=0;idpy_ctx; for (var=0;varNumVars;var++) { if (ctx->SameIsoColorVarOwner[var] || ctx->IsoColorVar[var] < 0){ time = ctxtime; } else{ time = dtxtime; } if(ctx->DisplaySurf[var] && !ctx->Variable[var]->SurfTable[time]){ ctx->Variable[var]->SurfTable[time] = (struct isosurface *) allocate(ctx,sizeof(struct isosurface)); memset(ctx->Variable[var]->SurfTable[time], 0, sizeof(struct isosurface)); } if (ctx->DisplaySurf[var] && ctx->Variable[var]->SurfTable[time]->valid) { if (animflag) { lock = cond_read_lock( &ctx->Variable[var]->SurfTable[time]->lock ); } else { wait_read_lock( &ctx->Variable[var]->SurfTable[time]->lock ); lock = 1; } if (lock) { recent( ctx, ISOSURF, var ); colorvar = ctx->Variable[var]->SurfTable[time]->colorvar; cvowner = ctx->Variable[var]->SurfTable[time]->cvowner; /* Determine alpha for surface: -1=variable, 0..255=constant */ if (ctx->Variable[var]->SurfTable[time]->colors) { alpha = UNPACK_ALPHA( dtx->Color[ctx->context_index*MAXVARS+ var][ISOSURF] ); /* alpha = get_alpha( ctx->ColorTable[VIS5D_ISOSURF_CT]->Colors[colorvar], 255 ); WLH 16 Aug 97 */ } else { alpha = UNPACK_ALPHA( dtx->Color[ctx->context_index*MAXVARS+ var][ISOSURF] ); } if ( (tf && alpha==255) || (tf==0 && alpha<255) ) { if (ctx->Variable[var]->SurfTable[time]->colors) { int fastdraw; vis5d_check_fastdraw(dtx->dpy_context_index, &fastdraw); if ((fastdraw || animflag) && ctx->Variable[var]->SurfTable[time]->deci_verts) { if (ctx->Variable[var]->SurfTable[time]->deci_colors) { draw_colored_isosurface( ctx->Variable[var]->SurfTable[time]->deci_numverts, ctx->Variable[var]->SurfTable[time]->index, (void *) ctx->Variable[var]->SurfTable[time]->deci_verts, (void *) ctx->Variable[var]->SurfTable[time]->deci_norms, 1, (void *) ctx->Variable[var]->SurfTable[time]->deci_colors, dtx->ColorTable[VIS5D_ISOSURF_CT]->Colors[cvowner*MAXVARS+colorvar], alpha ); } else { draw_isosurface( ctx->Variable[var]->SurfTable[time]->deci_numverts, ctx->Variable[var]->SurfTable[time]->index, (void *) ctx->Variable[var]->SurfTable[time]->deci_verts, (void *) ctx->Variable[var]->SurfTable[time]->deci_norms, 1, dtx->Color[ctx->context_index*MAXVARS+var][0], NULL, GL_COMPILE ); } } else draw_colored_isosurface( ctx->Variable[var]->SurfTable[time]->numindex, ctx->Variable[var]->SurfTable[time]->index, (void *) ctx->Variable[var]->SurfTable[time]->verts, (void *) ctx->Variable[var]->SurfTable[time]->norms, 0, (void *) ctx->Variable[var]->SurfTable[time]->colors, dtx->ColorTable[VIS5D_ISOSURF_CT]->Colors[cvowner*MAXVARS+colorvar], alpha ); } else { draw_isosurface( ctx->Variable[var]->SurfTable[time]->numindex, ctx->Variable[var]->SurfTable[time]->index, (void *) ctx->Variable[var]->SurfTable[time]->verts, (void *) ctx->Variable[var]->SurfTable[time]->norms, 0, dtx->Color[ctx->context_index*MAXVARS+var][0], NULL, 0 ); } } } done_read_lock( &ctx->Variable[var]->SurfTable[time]->lock ); } } } static void render_hclips( Display_Context dtx, int animflag) { int i; for (i = 0; i < 2; i++){ if (dtx->HClipTable[i].highlight == 1){ set_color( PACK_COLOR(100,25,240,255)); set_line_width(4); } else{ set_color( PACK_COLOR(50,200,75,255)); set_line_width(1); } polyline( (void *) dtx->HClipTable[i].boxverts, dtx->HClipTable[i].numboxverts); /* MJK 3.29.99 */ if (dtx->Reversed){ set_color( PACK_COLOR(0,0,0,255) ); } else{ set_color( dtx->BoxColor ); } set_line_width(dtx->LineWidth); } } static void render_vclips( Display_Context dtx, int animflag) { int i; for (i = 0; i < 4; i++){ if (dtx->VClipTable[i].highlight == 1){ set_color( PACK_COLOR(100,25,240,255)); set_line_width(4); } else{ set_color( PACK_COLOR(50,200,75,255)); set_line_width(1); } polyline( (void *) dtx->VClipTable[i].boxverts, dtx->VClipTable[i].numboxverts); if (dtx->VClipTable[i].highlight == 1){ float vert[4][3]; float zbot, ztop, x1, x2, y1, y2; float llev, hlev; llev = (float) dtx->LowLev; hlev = (float) (dtx->Nl-1+dtx->LowLev); gridPRIME_to_xyzPRIME( dtx, 0, 0, 1, &dtx->VClipTable[i].r1, &dtx->VClipTable[i].c1, &llev, &x1, &y1, &zbot); gridPRIME_to_xyzPRIME( dtx, 0, 0, 1, &dtx->VClipTable[i].r2, &dtx->VClipTable[i].c2, &hlev, &x2, &y2, &ztop); vert[0][0] = vert[1][0] = vert[2][0] = vert[3][0] = (x1 + x2)*0.5; vert[0][1] = vert[1][1] = vert[2][1] = vert[3][1] = (y1 +y2)*0.5; vert[0][2] = ztop+TICK_SIZE; vert[1][2] = ztop; vert[2][2] = zbot; vert[3][2] = zbot-TICK_SIZE; set_line_width(5); disjointpolyline( vert, 4 ); } /* MJK 3.29.99 */ if (dtx->Reversed){ set_color( PACK_COLOR(0,0,0,255) ); } else{ set_color( dtx->BoxColor ); } set_line_width(dtx->LineWidth); } } static void render_textplots( Irregular_Context itx, int time) { int var; float a, b, c, d; vis5d_get_text_plot(itx->context_index, &var, &a, &b, &c, &d); if (itx->DisplayTextPlot && itx->TextPlotTable[time].valid){ if (itx->TextPlotTable[time].colors){ draw_colored_disjoint_lines(itx->TextPlotTable[time].numverts, (void *) itx->TextPlotTable[time].verts, (void *) itx->TextPlotTable[time].colors, itx->dpy_ctx->ColorTable[VIS5D_TEXTPLOT_CT]->Colors[itx->context_index* MAXVARS+var]); } else{ draw_disjoint_lines( itx->TextPlotTable[time].numverts, (void *) itx->TextPlotTable[time].verts, itx->dpy_ctx->TextPlotColor[itx->context_index* MAXVARS+var] , NULL, 0); } } } /* * Render all horizontal contour slices selected for display. * Input: ctx - the context * time - the time step * labels - draw labels flag. */ static void render_hslices( Context ctx, int time, int labels, int animflag ) { int var, lock; if(vis5d_verbose & VERBOSE_RENDER) printf("render_hslices %d %d %d\n",time,labels,animflag); for (var=0;varNumVars;var++) { if (ctx->DisplayHSlice[var] && ctx->Variable[var]->HSliceTable[time] && ctx->Variable[var]->HSliceTable[time]->valid) { if (animflag) { lock = cond_read_lock(&(ctx->Variable[var]->HSliceTable[time]->lock)); } else { wait_read_lock(&(ctx->Variable[var]->HSliceTable[time]->lock)); lock = 1; } if (lock) { recent( ctx, HSLICE, var ); if(ctx->Variable[var]->HSliceRequest->stipple!=VIS5D_SOLID_LINE){ glEnable(GL_LINE_STIPPLE); glLineStipple(1, (GLushort) ctx->Variable[var]->HSliceRequest->stipple); } if(ctx->Variable[var]->HSliceRequest->linewidth>1) glLineWidth(ctx->Variable[var]->HSliceRequest->linewidth); /* draw main contour lines */ draw_disjoint_lines( ctx->Variable[var]->HSliceTable[time]->num1, (void *) ctx->Variable[var]->HSliceTable[time]->verts1, ctx->dpy_ctx->Color[ctx->context_index*MAXVARS+var][HSLICE], NULL, 0 ); if (labels) { #ifdef USE_SYSTEM_FONTS /* draw hidden contour lines */ draw_disjoint_lines( ctx->Variable[var]->HSliceTable[time]->num2, (void *)ctx->Variable[var]->HSliceTable[time]->verts2, ctx->dpy_ctx->Color[ctx->context_index*MAXVARS+ var][HSLICE], NULL, 0 ); glDisable(GL_LINE_STIPPLE); plot_strings( ctx->Variable[var]->HSliceTable[time]->num3, ctx->Variable[var]->HSliceTable[time]->labels, ctx->Variable[var]->HSliceTable[time]->verts3, ctx->dpy_ctx->Color[ctx->context_index*MAXVARS+var][HSLICE], ctx->dpy_ctx->gfx[CONTOUR_LABEL_FONT]->fontbase ); #else draw_disjoint_lines( ctx->Variable[var]->HSliceTable[time]->num3, (void *)ctx->Variable[var]->HSliceTable[time]->verts3, ctx->dpy_ctx->Color[ctx->context_index*MAXVARS +var][HSLICE], NULL, 0 ); #endif } else { /* draw hidden contour lines */ draw_disjoint_lines( ctx->Variable[var]->HSliceTable[time]->num2, (void *)ctx->Variable[var]->HSliceTable[time]->verts2, ctx->dpy_ctx->Color[ctx->context_index*MAXVARS+ var][HSLICE], NULL, 0 ); } /* draw the bounding box */ glLineWidth(1); glDisable(GL_LINE_STIPPLE); /* MJK 12.01.98 */ if (!ctx->DisplaySfcHSlice[var]){ polyline( (void *) ctx->Variable[var]->HSliceTable[time]->boxverts, ctx->Variable[var]->HSliceTable[time]->numboxverts ); } done_read_lock( &ctx->Variable[var]->HSliceTable[time]->lock ); } /* draw position label */ /* MJK 12.01.98 */ if (!ctx->DisplaySfcHSlice[var]){ if (ctx->dpy_ctx->DisplayBox && !ctx->dpy_ctx->CurvedBox) { float l, z; l = ctx->Variable[var]->HSliceRequest->Level; z = height_to_zPRIME( ctx->dpy_ctx, ctx->Variable[var]->HSliceRequest->Hgt); clipping_off(); draw_horizontal_slice_tick( ctx->dpy_ctx,l, z, ctx->Variable[var]->HSliceRequest->Hgt); clipping_on(); } } } } } /* * Render all vertical contour slices selected for display. * Input: ctx - the context * time - the time step * labels - draw labels flag. */ static void render_vslices( Context ctx, int time, int labels, int animflag ) { int var, lock; float x1, x2,y1,y2,z1,z2; float r1p, r2p, c1p, c2p, lp; for (var=0;varNumVars;var++) { if (ctx->DisplayVSlice[var] && ctx->Variable[var]->VSliceTable[time]->valid) { #ifndef USE_SYSTEM_FONTS if (labels) { if (check_view_side (ctx, VSLICE, var) < 0) { printf("flip the slice ?\n"); flip_vslice_end_for_end (ctx, time, var); } } #endif if (animflag) { lock = cond_read_lock(&ctx->Variable[var]->VSliceTable[time]->lock); } else { wait_read_lock(&ctx->Variable[var]->VSliceTable[time]->lock); lock = 1; } if (lock) { recent( ctx, VSLICE, var ); if(ctx->Variable[var]->VSliceRequest->stipple!=VIS5D_SOLID_LINE){ glEnable(GL_LINE_STIPPLE); glLineStipple(1, (GLushort) ctx->Variable[var]->VSliceRequest->stipple); } if(ctx->Variable[var]->VSliceRequest->linewidth>1) glLineWidth(ctx->Variable[var]->VSliceRequest->linewidth); /* draw main contour lines */ draw_disjoint_lines( ctx->Variable[var]->VSliceTable[time]->num1, (void*) ctx->Variable[var]->VSliceTable[time]->verts1, ctx->dpy_ctx->Color[ctx->context_index*MAXVARS+ var][VSLICE], NULL, 0 ); if (labels) { #ifdef USE_SYSTEM_FONTS /* draw hidden contour lines */ draw_disjoint_lines( ctx->Variable[var]->VSliceTable[time]->num2, (void*) ctx->Variable[var]->VSliceTable[time]->verts2, ctx->dpy_ctx->Color[ctx->context_index*MAXVARS+ var][VSLICE] , NULL, 0); glDisable(GL_LINE_STIPPLE); plot_strings( ctx->Variable[var]->VSliceTable[time]->num3, ctx->Variable[var]->VSliceTable[time]->labels, (void*) ctx->Variable[var]->VSliceTable[time]->verts3, ctx->dpy_ctx->Color[ctx->context_index*MAXVARS+var][VSLICE], ctx->dpy_ctx->gfx[CONTOUR_LABEL_FONT]->fontbase ); #else /* draw contour labels */ draw_disjoint_lines( ctx->Variable[var]->VSliceTable[time]->num3, (void*) ctx->Variable[var]->VSliceTable[time]->verts3, ctx->dpy_ctx->Color[ctx->context_index*MAXVARS+ var][VSLICE] , NULL, 0); #endif } else { /* draw hidden contour lines */ draw_disjoint_lines( ctx->Variable[var]->VSliceTable[time]->num2, (void*) ctx->Variable[var]->VSliceTable[time]->verts2, ctx->dpy_ctx->Color[ctx->context_index*MAXVARS+ var][VSLICE] , NULL, 0); } /* draw the bounding box */ polyline( (void *) ctx->Variable[var]->VSliceTable[time]->boxverts, ctx->Variable[var]->VSliceTable[time]->numboxverts ); done_read_lock( &ctx->Variable[var]->VSliceTable[time]->lock ); } if (ctx->dpy_ctx->DisplayBox && !ctx->dpy_ctx->CurvedBox) { /* draw position labels */ float vert[4][3]; float zbot, ztop; zbot = gridlevelPRIME_to_zPRIME(ctx->dpy_ctx, time, var, (float) ctx->dpy_ctx->LowLev); ztop = gridlevelPRIME_to_zPRIME(ctx->dpy_ctx, time, var, (float) (ctx->dpy_ctx->Nl-1+ctx->dpy_ctx->LowLev)); set_color( ctx->dpy_ctx->Color[ctx->context_index*MAXVARS+var][VSLICE] ); r1p = ctx->Variable[var]->VSliceRequest->R1; c1p = ctx->Variable[var]->VSliceRequest->R2; r2p = ctx->Variable[var]->VSliceRequest->C1; c2p = ctx->Variable[var]->VSliceRequest->C2; lp= 0.0; gridPRIME_to_xyzPRIME( ctx->dpy_ctx, time, var, 1, &r1p, &c1p, &lp, &x1, &y1, &z1); gridPRIME_to_xyzPRIME( ctx->dpy_ctx, time, var, 1, &r2p, &c2p, &lp, &x2, &y2, &z2); clipping_off(); draw_vertical_slice_tick(ctx->dpy_ctx, r1p, c1p, x1, y1, ctx->Variable[var]->VSliceRequest->Lat1, ctx->Variable[var]->VSliceRequest->Lon1 ); draw_vertical_slice_tick(ctx->dpy_ctx, r2p, c2p, x2, y2, ctx->Variable[var]->VSliceRequest->Lat2,ctx->Variable[var]->VSliceRequest->Lon2 ); /* draw_vertical_slice_tick( ctx->dpy_ctx, ctx->Variable[var]->VSliceRequest->R1, ctx->Variable[var]->VSliceRequest->R2, ctx->Variable[var]->VSliceRequest->X1, ctx->Variable[var]->VSliceRequest->Y1, ctx->Variable[var]->VSliceRequest->Lat1, ctx->Variable[var]->VSliceRequest->Lon1 ); draw_vertical_slice_tick( ctx->dpy_ctx, ctx->Variable[var]->VSliceRequest->C1, ctx->Variable[var]->VSliceRequest->C2, ctx->Variable[var]->VSliceRequest->X2, ctx->Variable[var]->VSliceRequest->Y2, ctx->Variable[var]->VSliceRequest->Lat2, ctx->Variable[var]->VSliceRequest->Lon2 ); */ /* draw small markers at midpoint of top and bottom edges */ vert[0][0] = vert[1][0] = vert[2][0] = vert[3][0] = (x1 + x2)*0.5; /* (ctx->Variable[var]->VSliceRequest->X1 + ctx->Variable[var]->VSliceRequest->X2) * 0.5; */ vert[0][1] = vert[1][1] = vert[2][1] = vert[3][1] = (y1 +y2)*0.5; /* (ctx->Variable[var]->VSliceRequest->Y1 + ctx->Variable[var]->VSliceRequest->Y2) * 0.5; */ vert[0][2] = ztop+TICK_SIZE; vert[1][2] = ztop; vert[2][2] = zbot; vert[3][2] = zbot-TICK_SIZE; set_line_width(5); /* WLH 3-5-96 */ disjointpolyline( vert, 4 ); set_line_width(ctx->dpy_ctx->LineWidth); /* WLH 3-5-96 */ clipping_on(); } } } } /* * Render all horizontal colored slices selected for display. * Input: ctx - the context * time - the timestep * tf - transparency flag: 1=only draw opaque slices * 0=only draw transparent slices * animflag - 1=animating, 0=not animating */ static void render_chslices( Context ctx, int time, int tf, int animflag ) { int var, alpha, lock; Display_Context dtx; dtx = ctx->dpy_ctx; for (var=0;varNumVars;var++) { if (ctx->DisplayCHSlice[var]) { if (ctx->Variable[var]->CHSliceTable[time]->valid) { if (animflag) { lock = cond_read_lock( &ctx->Variable[var]->CHSliceTable[time]->lock ); } else { wait_read_lock( &ctx->Variable[var]->CHSliceTable[time]->lock ); lock = 1; } if (lock) { recent( ctx, CHSLICE, var ); if(!tf){ draw_color_quadmesh( ctx->Variable[var]->CHSliceTable[time]->rows, ctx->Variable[var]->CHSliceTable[time]->columns, (void *)ctx->Variable[var]->CHSliceTable[time]->verts, ctx->Variable[var]->CHSliceTable[time]->color_indexes, dtx->ColorTable[VIS5D_CHSLICE_CT]->Colors[ctx->context_index*MAXVARS+var], 0,NULL,0); } done_read_lock( &ctx->Variable[var]->CHSliceTable[time]->lock ); } /* draw position label */ if (tf && dtx->DisplayBox && !dtx->CurvedBox) { set_color( dtx->Color[ctx->context_index*MAXVARS+var][CHSLICE] ); clipping_off(); draw_horizontal_slice_tick( dtx, ctx->Variable[var]->CHSliceRequest->Level, ctx->Variable[var]->CHSliceRequest->Z, ctx->Variable[var]->CHSliceRequest->Hgt ); clipping_on(); } } } } } /* * Render all vertical colored slices selected for display. * Input: ctx - the context * time - the timestep * tf - transparency flag: 1=only draw opaque slices * 0=only draw transparent slices */ static void render_cvslices( Context ctx, int time, int tf, int animflag ) { int var, alpha, lock; float x1, x2,y1,y2,z1,z2; float r1p, r2p, c1p, c2p, lp; Display_Context dtx; dtx = ctx->dpy_ctx; for (var=0;varNumVars;var++) { if (ctx->DisplayCVSlice[var] && ctx->Variable[var]->CVSliceTable[time]->valid) { if (animflag) { lock = cond_read_lock(&ctx->Variable[var]->CVSliceTable[time]->lock); } else { wait_read_lock(&ctx->Variable[var]->CVSliceTable[time]->lock); lock = 1; } if (lock) { recent( ctx, CVSLICE, var ); if ( !tf) { draw_color_quadmesh( ctx->Variable[var]->CVSliceTable[time]->rows, ctx->Variable[var]->CVSliceTable[time]->columns, (void *)ctx->Variable[var]->CVSliceTable[time]->verts, ctx->Variable[var]->CVSliceTable[time]->color_indexes, dtx->ColorTable[VIS5D_CVSLICE_CT]->Colors[ctx->context_index*MAXVARS+var], 0,NULL,0 ); } done_read_lock( &ctx->Variable[var]->CVSliceTable[time]->lock ); } if (tf & dtx->DisplayBox && !dtx->CurvedBox) { /* draw position labels */ float zbot, ztop; float vert[4][3]; zbot = gridlevelPRIME_to_zPRIME(ctx->dpy_ctx, time, var, (float) ctx->dpy_ctx->LowLev); ztop = gridlevelPRIME_to_zPRIME(ctx->dpy_ctx, time, var, (float) (ctx->dpy_ctx->Nl-1+ctx->dpy_ctx->LowLev)); set_color( dtx->Color[ctx->context_index*MAXVARS+var][CVSLICE] ); r1p = ctx->Variable[var]->CVSliceRequest->R1; c1p = ctx->Variable[var]->CVSliceRequest->R2; r2p = ctx->Variable[var]->CVSliceRequest->C1; c2p = ctx->Variable[var]->CVSliceRequest->C2; lp= 0.0; gridPRIME_to_xyzPRIME( ctx->dpy_ctx, time, var, 1, &r1p, &c1p, &lp, &x1, &y1, &z1); gridPRIME_to_xyzPRIME( ctx->dpy_ctx, time, var, 1, &r2p, &c2p, &lp, &x2, &y2, &z2); clipping_off(); draw_vertical_slice_tick(ctx->dpy_ctx, r1p, c1p, x1, y1, ctx->Variable[var]->CVSliceRequest->Lat1, ctx->Variable[var]->CVSliceRequest->Lon1 ); draw_vertical_slice_tick(ctx->dpy_ctx, r2p, c2p, x2, y2, ctx->Variable[var]->CVSliceRequest->Lat2,ctx->Variable[var]->CVSliceRequest->Lon2 ); /* draw_vertical_slice_tick( dtx, ctx->Variable[var]->CVSliceRequest->R1, ctx->Variable[var]->CVSliceRequest->R2, ctx->Variable[var]->CVSliceRequest->X1, ctx->Variable[var]->CVSliceRequest->Y1, ctx->Variable[var]->CVSliceRequest->Lat1, ctx->Variable[var]->CVSliceRequest->Lon1 ); draw_vertical_slice_tick( dtx, ctx->Variable[var]->CVSliceRequest->C1, ctx->Variable[var]->CVSliceRequest->C2, ctx->Variable[var]->CVSliceRequest->X2, ctx->Variable[var]->CVSliceRequest->Y2, ctx->Variable[var]->CVSliceRequest->Lat2, ctx->Variable[var]->CVSliceRequest->Lon2 ); */ /* draw small markers at midpoint of top and bottom edges */ vert[0][0] = vert[1][0] = vert[2][0] = vert[3][0] = (x1 + x2)*0.5; vert[0][1] = vert[1][1] = vert[2][1] = vert[3][1] = (y1 +y2)*0.5; /* vert[0][0] = vert[1][0] = vert[2][0] = vert[3][0] = (ctx->Variable[var]->CVSliceRequest->X1 + ctx->Variable[var]->CVSliceRequest->X2) * 0.5; vert[0][1] = vert[1][1] = vert[2][1] = vert[3][1] = (ctx->Variable[var]->CVSliceRequest->Y1 + ctx->Variable[var]->CVSliceRequest->Y2) * 0.5; */ vert[0][2] = ztop+TICK_SIZE; vert[1][2] = ztop; vert[2][2] = zbot; vert[3][2] = zbot-TICK_SIZE; set_line_width(5); /* WLH 3-5-96 */ disjointpolyline( vert, 4 ); set_line_width(dtx->LineWidth); /* WLH 3-5-96 */ clipping_on(); } } } } /* * Render all horizontal wind vector slices which are selected for display. * Input: ctx - the context * time - the timestep */ static void render_hwind_slices( Context ctx, int time, int animflag ) { int w, lock; Display_Context dtx; dtx = ctx->dpy_ctx; for (w=0;wDisplayHWind[w] && dtx->HWindTable[w][time].valid && ctx->context_index == dtx->Uvarowner[w]) { if (animflag) { lock = cond_read_lock( &dtx->HWindTable[w][time].lock ); } else { wait_read_lock( &dtx->HWindTable[w][time].lock ); lock = 1; } /* MJK 12.01.98 */ set_color( dtx->HWindColor[w] ); if (ctx->dpy_ctx->DisplaySfcHWind[w]) { if (lock) { recent( ctx, HWIND, w ); draw_disjoint_lines( dtx->HWindTable[w][time].nvectors, (void *) dtx->HWindTable[w][time].verts, dtx->HWindColor[w] , NULL, 0); done_read_lock( &dtx->HWindTable[w][time].lock ); } } else { if (lock) { recent( ctx, HWIND, w ); /* draw the bounding box */ polyline( (void *) dtx->HWindTable[w][time].boxverts, dtx->HWindTable[w][time].numboxverts ); /* draw wind vectors */ if (dtx->HWindTable[w][time].barbs) { draw_disjoint_lines( dtx->HWindTable[w][time].nvectors, (void *) dtx->HWindTable[w][time].verts, dtx->HWindColor[w], NULL, 0 ); } else { draw_wind_lines( dtx->HWindTable[w][time].nvectors / 4, (void *) dtx->HWindTable[w][time].verts, dtx->HWindColor[w] ); } done_read_lock( &dtx->HWindTable[w][time].lock ); } /* draw position label */ if (dtx->DisplayBox && !dtx->CurvedBox) { clipping_off(); draw_horizontal_slice_tick( dtx, dtx->HWindLevel[w], dtx->HWindZ[w], dtx->HWindHgt[w]); clipping_on(); } } /* end MJK 12.01.98 */ } } } /* * Render all vertical wind vector slices which are selected for display. * Input: ctx - the context * time - the timestep */ static void render_vwind_slices( Context ctx, int time, int animflag ) { int w, lock; Display_Context dtx; float x1, x2,y1,y2,z1,z2; float r1p, r2p, c1p, c2p, lp; dtx = ctx->dpy_ctx; for (w=0;wDisplayVWind[w] && dtx->VWindTable[w][time].valid && ctx->context_index == dtx->Uvarowner[w]) { if (animflag) { lock = cond_read_lock(&dtx->VWindTable[w][time].lock); } else { wait_read_lock(&dtx->VWindTable[w][time].lock); lock = 1; } if (lock) { ctx = dtx->ctxpointerarray[0]; recent( ctx, VWIND, w ); /* draw the bounding box */ set_color( dtx->VWindColor[w] ); polyline( (void *) dtx->VWindTable[w][time].boxverts, dtx->VWindTable[w][time].numboxverts ); /* draw wind vectors */ if (dtx->VWindTable[w][time].barbs) { draw_disjoint_lines( dtx->VWindTable[w][time].nvectors, (void *) dtx->VWindTable[w][time].verts, dtx->VWindColor[w], NULL, 0 ); } else { draw_wind_lines( dtx->VWindTable[w][time].nvectors / 4, (void *) dtx->VWindTable[w][time].verts, dtx->VWindColor[w] ); } done_read_lock( &dtx->VWindTable[w][time].lock ); } if (dtx->DisplayBox && !dtx->CurvedBox) { /* position labels */ float zbot, ztop; float vert[4][3]; zbot = gridlevelPRIME_to_zPRIME(dtx, time, dtx->Uvar[w], (float) dtx->LowLev); ztop = gridlevelPRIME_to_zPRIME(dtx, time, dtx->Uvar[w], (float) (dtx->Nl +dtx->LowLev)); clipping_off(); r1p = dtx->VWindR1[w]; c1p = dtx->VWindC1[w]; r2p = dtx->VWindR2[w]; c2p = dtx->VWindC2[w]; lp= 0.0; gridPRIME_to_xyzPRIME( dtx, time, dtx->Uvar[w], 1, &r1p, &c1p, &lp, &x1, &y1, &z1); gridPRIME_to_xyzPRIME( dtx, time, dtx->Uvar[w], 1, &r2p, &c2p, &lp, &x2, &y2, &z2); draw_vertical_slice_tick( dtx, r1p, c1p, x1, y1, dtx->VWindLat1[w], dtx->VWindLon1[w] ); draw_vertical_slice_tick( dtx, r2p, c2p, x2, y2, dtx->VWindLat2[w], dtx->VWindLon2[w] ); /* draw small markers at midpoint of top and bottom edges */ vert[0][0] = vert[1][0] = vert[2][0] = vert[3][0] = (dtx->VWindX1[w] + dtx->VWindX2[w]) * 0.5; vert[0][1] = vert[1][1] = vert[2][1] = vert[3][1] = (dtx->VWindY1[w] + dtx->VWindY2[w]) * 0.5; vert[0][2] = ztop+TICK_SIZE; vert[1][2] = ztop; vert[2][2] = zbot; vert[3][2] = zbot-TICK_SIZE; set_line_width(5); /* WLH 3-5-96 */ disjointpolyline( vert, 4 ); set_line_width(dtx->LineWidth); /* WLH 3-5-96 */ clipping_on(); } } } } /* * Render all horizontal stream vector slices which are selected for display. * Input: ctx - the context * time - the timestep */ static void render_hstream_slices( Context ctx, int time, int animflag ) { int w, lock; Display_Context dtx; dtx = ctx->dpy_ctx; for (w=0;wDisplayHStream[w] && dtx->HStreamTable[w][time].valid && ctx->context_index == dtx->Uvarowner[w]) { if (animflag) { lock = cond_read_lock(&dtx->HStreamTable[w][time].lock); } else { wait_read_lock(&dtx->HStreamTable[w][time].lock); lock = 1; } if (lock) { ctx = dtx->ctxpointerarray[0]; recent( ctx, HSTREAM, w ); /* draw the bounding box */ set_color( dtx->HStreamColor[w] ); /* MJK 12.02.92 */ if (!ctx->dpy_ctx->DisplaySfcHStream[w]){ polyline( (void *) dtx->HStreamTable[w][time].boxverts, dtx->HStreamTable[w][time].numboxverts ); } /* draw main contour lines */ draw_disjoint_lines( dtx->HStreamTable[w][time].nlines, (void *) dtx->HStreamTable[w][time].verts, dtx->HStreamColor[w], NULL, 0 ); done_read_lock( &dtx->HStreamTable[w][time].lock ); } /* draw position label */ /* MJK 12.02.92 */ if (!ctx->dpy_ctx->DisplaySfcHStream[w]){ if (dtx->DisplayBox && !dtx->CurvedBox) { clipping_off(); draw_horizontal_slice_tick( dtx, dtx->HStreamLevel[w], dtx->HStreamZ[w], dtx->HStreamHgt[w]); clipping_on(); } } } } } /* * Render all vertical stream vector slices which are selected for display. * Input: ctx - the context * time - the timestep */ static void render_vstream_slices( Context ctx, int time, int animflag ) { int w, lock; Display_Context dtx; dtx = ctx->dpy_ctx; for (w=0;wDisplayVStream[w] && dtx->VStreamTable[w][time].valid && ctx->context_index == dtx->Uvarowner[w]) { if (animflag) { lock = cond_read_lock(&dtx->VStreamTable[w][time].lock); } else { wait_read_lock(&dtx->VStreamTable[w][time].lock); lock = 1; } if (lock) { ctx = dtx->ctxpointerarray[0]; recent( ctx, VSTREAM, w ); /* draw the bounding box */ set_color( dtx->VStreamColor[w] ); polyline( (void *) dtx->VStreamTable[w][time].boxverts, dtx->VStreamTable[w][time].numboxverts ); /* draw main contour lines */ draw_disjoint_lines( dtx->VStreamTable[w][time].nlines, (void *) dtx->VStreamTable[w][time].verts, dtx->VStreamColor[w] , NULL, 0); done_read_lock( &dtx->VStreamTable[w][time].lock ); } if (dtx->DisplayBox && !dtx->CurvedBox) { /* position labels */ float zbot, ztop; float vert[4][3]; zbot = gridlevelPRIME_to_zPRIME(dtx, time, dtx->Uvar[w], (float) dtx->LowLev); ztop = gridlevelPRIME_to_zPRIME(dtx, time, dtx->Uvar[w], (float) (dtx->Nl +dtx->LowLev)); clipping_off(); draw_vertical_slice_tick( dtx, dtx->VStreamR1[w], dtx->VStreamC1[w], dtx->VStreamX1[w], dtx->VStreamY1[w], dtx->VStreamLat1[w], dtx->VStreamLon1[w] ); draw_vertical_slice_tick( dtx, dtx->VStreamR2[w], dtx->VStreamC2[w], dtx->VStreamX2[w], dtx->VStreamY2[w], dtx->VStreamLat2[w], dtx->VStreamLon2[w] ); /* draw small markers at midpoint of top and bottom edges */ vert[0][0] = vert[1][0] = vert[2][0] = vert[3][0] = (dtx->VStreamX1[w] + dtx->VStreamX2[w]) * 0.5; vert[0][1] = vert[1][1] = vert[2][1] = vert[3][1] = (dtx->VStreamY1[w] + dtx->VStreamY2[w]) * 0.5; vert[0][2] = ztop+TICK_SIZE; vert[1][2] = ztop; vert[2][2] = zbot; vert[3][2] = zbot-TICK_SIZE; set_line_width(5); /* WLH 3-5-96 */ disjointpolyline( vert, 4 ); set_line_width(dtx->LineWidth); /* WLH 3-5-96 */ clipping_on(); } } } } static void render_trajectories( Context ctx, int it, int tf ) { int alpha, i, len, start; Display_Context dtx; dtx = ctx->dpy_ctx; for (i=0;iNumTraj;i++) { struct traj *t = dtx->TrajTable[i]; if (t->ctx_owner==ctx->context_index && dtx->DisplayTraj[t->group] && cond_read_lock(&t->lock)){ assert( t->lock==1 ); recent( ctx, TRAJ, t->group ); alpha = UNPACK_ALPHA( dtx->TrajColor[t->group]); if ( (tf && alpha==255) || (tf==0 && alpha<255) ) { start = t->start[it]; len = t->len[it]; if (start!=0xffff && len>0) { if (t->kind==0) { /* draw as line segments */ int colorvar = t->colorvar; if (colorvar>=0) { /* draw colored trajectory */ draw_colored_polylines( len, (void *) (t->verts + start*3), (void*)(t->colors + start), dtx->ColorTable[VIS5D_TRAJ_CT]->Colors[t->colorvarowner*MAXVARS+ colorvar]); } else { /* monocolored */ draw_polylines( len, (void *) (t->verts + start*3), dtx->TrajColor[t->group] ); } } else { /* draw as triangle strip */ int colorvar = t->colorvar; if (colorvar>=0) { /* draw colored triangles */ draw_colored_triangle_strip( len, (void*)(t->verts + start*3), (void*)(t->norms + start*3), (void*)(t->colors + start), dtx->ColorTable[VIS5D_TRAJ_CT]->Colors[t->colorvarowner*MAXVARS+ colorvar], alpha ); } else { /* monocolor */ draw_triangle_strip( len, (void*)(t->verts + start*3), (void*)(t->norms + start*3), dtx->TrajColor[t->group] ); } } } } done_read_lock( &t->lock ); } } } /* * Draw the clock in the upper-left corner of the 3-D window. * Input: ctx - the vis5d context * c - the color to use. */ /* MJK 12.02.98 begin */ static void draw_clock( Display_Context dtx, unsigned int c ) { static char day[7][20] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; static char month[12][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; static int dds[24] = {31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}; static float twopi = 2.0 * 3.141592; short pp[CLOCK_SEGMENTS+1][2]; float ang, delta; float clk_size, clk_margin, clk_radius, clk_center_x, clk_center_y; char str[15]; int i, time_str_width; int stime=0, stimeold, dtime=0, dtimeold; clk_size = 4*(dtx->gfx[WINDOW_3D_FONT]->FontHeight+VSPACE); clk_margin = clk_size / 16.0; clk_radius = (clk_size / 2.0) - clk_margin; clk_center_x = clk_size / 2.0; clk_center_y = clk_size / 2.0; /* Draw the clock. */ if (dtx->NumTimes) ang = twopi * (float) dtx->CurTime / (float) dtx->NumTimes; else ang = 0.0; pp[0][1] = clk_center_y; pp[0][0] = clk_center_x; pp[1][1] = clk_center_y - (clk_radius * cos(ang)); pp[1][0] = clk_center_x + (clk_radius * sin(ang)); pp[2][1] = pp[1][1] + 1; pp[2][0] = pp[1][0] + 1; pp[3][1] = pp[0][1] + 1; pp[3][0] = pp[0][0] + 1; pp[4][1] = pp[0][1] - 1; pp[4][0] = pp[0][0] + 1; pp[5][1] = pp[1][1] - 1; pp[5][0] = pp[1][0] + 1; set_color( c ); polyline2d( pp, 6 ); if (dtx->CircleClock){ /* Draw a circle around the clock. */ delta = twopi / ((float) CLOCK_SEGMENTS); ang = 0.0; for (i = 0; i < CLOCK_SEGMENTS; i++) { pp[i][0] = clk_center_x + (clk_radius * sin (ang)) + 0.5; pp[i][1] = clk_center_y - (clk_radius * cos (ang)) + 0.5; ang += delta; } pp[i][0] = pp[0][0]; pp[i][1] = pp[0][1]; polyline2d (pp, CLOCK_SEGMENTS+1); } clk_size += clk_margin; dtimeold = -1; stimeold = -1; if(dtx->NumTimes) vis5d_get_dtx_time_stamp( dtx->dpy_context_index, dtx->CurTime, &dtime, &stime); dtimeold = dtime; stimeold = stime; i = stimeold; sprintf( str, "%02d:%02d:%02d", i/3600, (i/60)%60, i%60 ); draw_text( clk_size, dtx->gfx[WINDOW_3D_FONT]->FontHeight+VSPACE, str ); time_str_width = text_width ( dtx->gfx[WINDOW_3D_FONT]->font, str); if (dtx->JulianDate) { sprintf( str, "%7d", v5dDaysToYYDDD( dtimeold )); } else { int iyyddd, iy, im, id, mon; iyyddd = v5dDaysToYYDDD( dtimeold ); iy = iyyddd / 1000; id = iyyddd - (iy * 1000); im = ((iy % 4) == 0 && ((iy % 100) != 0 || (iy % 400) == 0)) ? 12 : 0; for (i=im; i 0) id = id - dds[i-1]; break; } } sprintf(str, "%02d %s %02d", id, month[mon], iy); } draw_text( clk_size, 2*(dtx->gfx[WINDOW_3D_FONT]->FontHeight+VSPACE), str ); sprintf( str, "%d of %d", dtx->CurTime+1, dtx->NumTimes ); draw_text( clk_size, 3*(dtx->gfx[WINDOW_3D_FONT]->FontHeight+VSPACE), str ); if (dtx->NumTimes == 1 || ((dtx->Elapsed[dtx->NumTimes-1] - dtx->Elapsed[0]) / (dtx->NumTimes - 1)) < 48*3600 ) { /* Print day of week */ draw_text( clk_size, 4*(dtx->gfx[WINDOW_3D_FONT]->FontHeight+VSPACE), day[ (dtimeold+0) % 7 ] ); } if (dtx->group_index > 0){ sprintf( str, " Group %d", dtx->group_index); draw_text( (clk_size + time_str_width), (dtx->gfx[WINDOW_3D_FONT]->FontHeight+VSPACE), str ); } } /* MJK 12.02.98 end */ /* * Render all the 2-D text labels. */ static void render_text_labels( Display_Context dtx ) { struct label *lab; for (lab=dtx->FirstLabel; lab; lab=lab->next) { if (dtx->Reversed && lab->LabelColor==PACK_COLOR(255,255,255,255)){ set_color( PACK_COLOR(0,0,0,255) ); } else{ set_color( lab->LabelColor ); } draw_text( lab->x, lab->y, lab->text ); if (lab->state) { /* being edited -> draw cursor */ short verts[4][2]; verts[0][0] = lab->x2; verts[0][1] = lab->y1; verts[1][0] = lab->x2; verts[1][1] = lab->y2; verts[2][0] = lab->x2+1; verts[2][1] = lab->y2; verts[3][0] = lab->x2+1; verts[3][1] = lab->y1; polyline2d( verts, 4 ); } } } static void draw_fake_pointer( Display_Context dtx ) { short pp[8][2]; pp[0][0] = dtx->PointerX; pp[0][1] = dtx->PointerY; pp[1][0] = dtx->PointerX+15; pp[1][1] = dtx->PointerY+5; pp[2][0] = dtx->PointerX+5; pp[2][1] = dtx->PointerY+15; pp[3][0] = dtx->PointerX; pp[3][1] = dtx->PointerY; pp[4][0] = dtx->PointerX+20; pp[4][1] = dtx->PointerY+20; polyline2d( pp, 5 ); } /* * Print status info at bottom of window. */ static void print_info( Display_Context dtx ) { char str[1000]; int m, size, waiters; m = mem_used( dtx ); get_queue_info( &size, &waiters ); if (m>=0) sprintf(str, "Pending: %d Memory Used: %d", size, m ); else sprintf(str, "Pending: %d", size ); draw_text( 10, dtx->WinHeight - dtx->gfx[WINDOW_3D_FONT]->FontHeight, str ); } /* * Print the numeric value of each variable at the probe's current location. */ /* MJK 12.02.98 begin */ static void draw_probe( Display_Context dtx ) { float val; char str[1000]; int y, var; int x; int yo; float rr,cc,ll; /* find widest parameter name, but only once */ if (!dtx->do_not_recalc_probe_text_width){ x = -1; for (yo = 0; yo < dtx->numofctxs; yo++){ for (var=0;varctxpointerarray[yo]->NumVars; var++) { int w = text_width(dtx->gfx[WINDOW_3D_FONT]->font, dtx->ctxpointerarray[yo]->Variable[var]->VarName ); int l = strlen( dtx->ctxpointerarray[yo]->Variable[var]->VarName ); if (w < 1) w = 11 * l; if (w>x) x = w; } } if (dtx->numofctxs >0){ x += 25; } dtx->do_not_recalc_probe_text_width = 1; dtx->probe_text_width = x; } x = dtx->probe_text_width; /* Draw from bottom of window upward */ y = dtx->WinHeight - dtx->gfx[WINDOW_3D_FONT]->FontHeight; for (yo = 0; yo < dtx->numofctxs; yo++){ Context ctx; int ipvar, npvar, lpvar; ctx = dtx->ctxpointerarray[yo]; if (ctx->ProbeNumVars >= 0) { npvar = ctx->ProbeNumVars; lpvar = 1; } else { npvar = ctx->NumVars - 1; lpvar = 0; } for (ipvar = npvar; ipvar >= lpvar; ipvar--) { var = ipvar; if (ctx->ProbeNumVars > 0) { for (var=ctx->NumVars-1;var>=0;var--) { if (ctx->ProbeVar[var] == ipvar) break; } } if (var >= 0) { float r, c, l; xyzPRIME_to_grid( ctx, ctx->CurTime, var, dtx->CursorX, dtx->CursorY, dtx->CursorZ, &rr, &cc, &ll ); xyzPRIME_to_gridPRIME( ctx->dpy_ctx, dtx->CurTime, var, dtx->CursorX, dtx->CursorY, dtx->CursorZ, &r, &c, &l); if (ll < ctx->Variable[var]->LowLev || ll > ctx->Nl[var]-1 + ctx->Variable[var]->LowLev || rr < 0 || rr > ctx->Nr-1 || cc < 0 || cc > ctx->Nc-1 || !check_for_valid_time(ctx, dtx->CurTime)) { val = MISSING; } else if (dtx->CoordFlag==1) { /* discrete grid position */ int row = (int) (r+0.01); int col = (int) (c+0.01); int lev = (int) (l+0.01); if (ctx->GridSameAsGridPRIME){ val = get_grid_value( ctx, ctx->CurTime, var, row, col, lev ); } else{ vis5d_gridPRIME_to_grid(ctx->context_index, ctx->CurTime, var, (float)(row), (float)(col), (float)(lev), &rr, &cc, &ll); if (ll < ctx->Variable[var]->LowLev || ll > ctx->Nl[var]-1 + ctx->Variable[var]->LowLev || rr < 0 || rr > ctx->Nr-1 || cc < 0 || cc > ctx->Nc-1) { val = MISSING; } else{ val = get_grid_value( ctx, ctx->CurTime, var, rr, cc, ll); } } } else { if (ctx->GridSameAsGridPRIME){ val = interpolate_grid_value( ctx, ctx->CurTime, var, r, c, l ); } else{ val = interpolate_grid_value( ctx, ctx->CurTime, var, rr, cc, ll ); } } sprintf( str, "%-4s", ctx->Variable[var]->VarName ); if (dtx->numofctxs > 1){ char yodle[40]; strcpy(yodle, return_var_plus_index(str, ctx->context_index)); draw_text( 10, y, yodle ); } else{ draw_text( 10, y, str); } if (IS_MISSING(val)) sprintf( str, " = MISSING" ); else sprintf( str, " = %.3g %s", val, ctx->Variable[var]->Units ); draw_text( x+10, y, str ); y -= (dtx->gfx[WINDOW_3D_FONT]->FontHeight+VSPACE); } } } } /* MJK 12.02.98 end */ /* #define LEGEND_SPACE 20 #define LEGEND_WIDTH 25 #define LEGEND_HEIGHT 128 */ #define TICK_LENGTH 4 #define NUM_TICKS 5 /* * Draw a color legend. * Input: var = parameter index the color slice belongs to for which to * draw the legend, * type = CHSLICE or CVSLICE, * xleft = x-position for left side of color bar, * ybot = y-position for bottom of color bar. * Return: width of bar + numbers drawn, or height of bar + label. */ int draw_legend( Context ctx, int varowner, int var, int type, int xleft, int ybot ) { int y, lutindex, textwidth; int tick; short cline[2][2]; uint *lut; char scrap[100], format[20]; int legend_space, legend_width, legend_height; float label; Display_Context dtx; Context colorctx; /* MJK 12.02.98 */ int bg_r, bg_g, bg_b, bg_a, fg_r, fg_g, fg_b, fg_a; dtx = ctx->dpy_ctx; colorctx = dtx->ctxpointerarray[return_ctx_index_pos(dtx, varowner)]; legend_height = dtx->LegendSize; legend_width = (25 * dtx->LegendSize) / 128; legend_space = (20 * dtx->LegendSize) / 128; switch(type) { case VIS5D_ISOSURF: lut = dtx->ColorTable[VIS5D_ISOSURF_CT]->Colors[varowner*MAXVARS+var]; break; case VIS5D_CHSLICE: lut = dtx->ColorTable[VIS5D_CHSLICE_CT]->Colors[varowner*MAXVARS+var]; break; case VIS5D_CVSLICE: lut = dtx->ColorTable[VIS5D_CVSLICE_CT]->Colors[varowner*MAXVARS+var]; break; case VIS5D_TRAJ: lut = dtx->ColorTable[VIS5D_TRAJ_CT]->Colors[varowner*MAXVARS+var]; break; case VIS5D_VOLUME: lut = dtx->ColorTable[VIS5D_VOLUME_CT]->Colors[varowner*MAXVARS+var]; break; case VIS5D_TOPO: lut = dtx->ColorTable[VIS5D_TOPO_CT]->Colors[varowner*MAXVARS+var]; break; default: /* this should never happen */ abort(); } /* These line values never change */ cline[0][0] = xleft; cline[1][0] = xleft + legend_width; /* Draw the colors */ /* MJK 12.02.98 begin */ bg_r = UNPACK_RED(dtx->BgColor); bg_g = UNPACK_GREEN(dtx->BgColor); bg_b = UNPACK_BLUE(dtx->BgColor); for (y = 0; yReversed) { set_color(PACK_COLOR( 0, 0, 0, 255)); } else{ set_color( dtx->BoxColor ); } cline[0][0] = cline[1][0] = xleft; cline[0][1] = ybot; cline[1][1] = ybot - legend_height + 1; polyline2d(cline, 2); cline[0][0] = cline[1][0] = xleft + legend_width; polyline2d(cline, 2); cline[0][0] = xleft; cline[1][0] = xleft + legend_width; cline[0][1] = cline[1][1] = ybot; polyline2d(cline, 2); cline[0][1] = cline[1][1] = ybot - legend_height + 1; polyline2d(cline, 2); /* MJK 12.02.98 end */ /* Determine largest value physical variable can have */ label = ABS(colorctx->Variable[var]->MaxVal); if (ABS(colorctx->Variable[var]->MinVal) > label) label = ABS(colorctx->Variable[var]->MinVal); /* Create 'pretty' formatting string */ sprintf(scrap, "% .0f", label); sprintf(format, "%% %d.2f", (int)strlen(scrap)+3); /* Draw values and tick marks on the right hand side of the legend */ textwidth = 0; /* Make sure we have a tick at the top of the legend @@ */ cline[0][0] += TICK_LENGTH + legend_width; /* MJK 3.29.99 */ if (dtx->Reversed) { set_color(PACK_COLOR( 0, 0, 0, 255)); } else{ set_color( dtx->BoxColor ); } XSync( GfxDpy, 0 ); for (tick=0;tickgfx[WINDOW_3D_FONT]->FontHeight+dtx->gfx[WINDOW_3D_FONT]->FontDescent) / (NUM_TICKS-1); value = colorctx->Variable[var]->MinVal + (colorctx->Variable[var]->MaxVal-colorctx->Variable[var]->MinVal)*tick/4.0; cline[0][1] = cline[1][1] = ticky; polyline2d(cline, 2); sprintf(scrap, format, value); draw_text( xleft + legend_width + TICK_LENGTH + 2, texty, scrap ); XSync( GfxDpy, 0 ); if (text_width(dtx->gfx[WINDOW_3D_FONT]->font,scrap) > textwidth) textwidth = text_width(dtx->gfx[WINDOW_3D_FONT]->font,scrap); } /* Print name of physical variable above legend */ if (colorctx->Variable[var]->Units[0]) { sprintf( scrap, "%s (%s)", colorctx->Variable[var]->VarName, colorctx->Variable[var]->Units ); draw_text( xleft, ybot - legend_height - dtx->gfx[WINDOW_3D_FONT]->FontDescent-2, scrap ); } else { draw_text( xleft, ybot - legend_height - dtx->gfx[WINDOW_3D_FONT]->FontDescent-2, colorctx->Variable[var]->VarName); } if (dtx->LegendPosition == VIS5D_BOTTOM || dtx->LegendPosition == VIS5D_TOP) { return legend_width + TICK_LENGTH + 5 + textwidth + legend_space; } else { return legend_height + 5 + dtx->gfx[WINDOW_3D_FONT]->FontHeight + legend_space; } } /* * Draws color legends of activated color slices. * Since the space in the 3-D window is restricted only one row of legends * is drawn in the bottom of the 3-D window. The order of drawing is: * first the legends of the horizontal slices for parameter 0..NumVars-1 * and then the vertical slices for parameter 0..NumVars-1. */ static void draw_color_legends( Display_Context dtx ) { int var, set; int left; /* Left x position of current legend */ int bottom; /* Bottom y position of current legend */ int inc, vert; int vindex; int ctxnum, cvar, cvowner; Context ctx; if (dtx->LegendPosition == VIS5D_BOTTOM) { left = 50+dtx->LegendMarginX; bottom = dtx->WinHeight - 20 + dtx->LegendMarginY; vert = 0; } else if (dtx->LegendPosition == VIS5D_TOP) { left = 200+dtx->LegendMarginX; bottom = dtx->LegendSize + 5 + dtx->gfx[WINDOW_3D_FONT]->FontHeight + 25 + dtx->LegendMarginY; vert = 0; } else if (dtx->LegendPosition == VIS5D_RIGHT) { left = dtx->WinWidth - ((35 * dtx->LegendSize) / 128) - 5 * dtx->gfx[WINDOW_3D_FONT]->FontHeight+dtx->LegendMarginX; bottom = dtx->LegendSize + 5 + dtx->gfx[WINDOW_3D_FONT]->FontHeight + 50 + dtx->LegendMarginY; vert = 1; } else if (dtx->LegendPosition == VIS5D_LEFT) { left = 20+dtx->LegendMarginX; bottom = dtx->LegendSize + 5 + dtx->gfx[WINDOW_3D_FONT]->FontHeight + 100 + dtx->LegendMarginY; vert = 1; } else { printf("draw_color_legends: bad LegendPosition\n"); return; } /* Isosurface color tables */ for (ctxnum=0; ctxnumnumofctxs; ctxnum++){ ctx = dtx->ctxpointerarray[ctxnum]; for (var=0; varNumVars; var++) { cvar = ctx->IsoColorVar[var]; cvowner = ctx->IsoColorVarOwner[var]; if (ctx->DisplaySurf[var] && cvar>=0 ){ /* Draw legend at position (xstart, ystart) = upper left corner */ inc = draw_legend( ctx, cvowner, cvar, VIS5D_ISOSURF, left, bottom ); if (vert) { bottom += inc; if (bottom > dtx->WinHeight - 50) return; } else { left += inc; if (left > dtx->WinWidth - 150) return; } } } } /* Find activated horizontal color slices */ for (ctxnum=0; ctxnumnumofctxs; ctxnum++){ ctx = dtx->ctxpointerarray[ctxnum]; for (var=0; varNumVars; var++) { if (ctx->DisplayCHSlice[var]) { /* Draw legend at position (xstart, ystart) = upper left corner */ vindex = ctx->context_index; inc = draw_legend( ctx, vindex, var, VIS5D_CHSLICE, left, bottom ); if (vert) { bottom += inc; if (bottom > dtx->WinHeight - 50) return; } else { left += inc; if (left > dtx->WinWidth - 150) return; } } } } /* Find activated vertical color slices */ for (ctxnum=0; ctxnumnumofctxs; ctxnum++){ ctx = dtx->ctxpointerarray[ctxnum]; for (var=0; varNumVars; var++) { if (ctx->DisplayCVSlice[var]) { /* Draw legend at position (xstart, ystart) = upper left corner */ vindex = ctx->context_index; inc = draw_legend( ctx, vindex, var, VIS5D_CVSLICE, left, bottom ); if (vert) { bottom += inc; if (bottom > dtx->WinHeight - 50) return; } else { left += inc; if (left > dtx->WinWidth - 150) return; } } } } /* Volume */ if (dtx->CurrentVolume>=0 ) { /* Draw legend at position (xstart, ystart) = upper left corner */ inc = draw_legend( ctx, dtx->CurrentVolumeOwner, dtx->CurrentVolume, VIS5D_VOLUME, left, bottom ); if (vert) { bottom += inc; if (bottom > dtx->WinHeight - 50) return; } else { left += inc; if (left > dtx->WinWidth - 150) return; } } /* Trajectory color tables */ for (set=0; setTrajColorVar[set]; int cvowner = dtx->TrajColorVarOwner[set]; if (dtx->DisplayTraj[set] && cvar>=0 ){ /* Draw legend at position (xstart, ystart) = upper left corner */ inc = draw_legend( ctx, cvowner, cvar, VIS5D_TRAJ, left, bottom ); if (vert) { bottom += inc; if (bottom > dtx->WinHeight - 50) return; } else { left += inc; if (left > dtx->WinWidth - 150) return; } } } /* Topo color table */ if (dtx->topo->TopoColorVar>=0 && dtx->topo->DisplayTopo) { int cvar = dtx->topo->TopoColorVar; int cvowner = dtx->topo->TopoColorVarOwner; /* Draw legend at position (xstart, ystart) = upper left corner */ inc = draw_legend( ctx, cvowner, cvar, VIS5D_TOPO, left, bottom ); if (vert) { bottom += inc; if (bottom > dtx->WinHeight - 50) return; } else { left += inc; if (left > dtx->WinWidth - 150) return; } } } /* * Draw anything the user wants in 3D. * Drawing bounds are (Xmin,Ymin,Zmin) - (Xmax,Ymax,Zmax) */ static void draw_user_3d_graphics( Display_Context dtx ) { } /* * Draw anything the user wants in 2D. * Drawing bounds are (0,0) - (Width-1, Height-1), origin in upper-left corner. */ static void draw_user_2d_graphics( Display_Context dtx ) { } /* * Only draw the 3-D elements of the scene. No matrix, viewport, etc * operations are done here. This function is useful for the CAVE * since it controls the viewing parameters. * Input: ctx - the context * animflag - 1=animating, 0=not animating */ void render_3d_only( Display_Context dtx, int animflag ) { int yo, labels, i; Context ctx; Irregular_Context itx; if (animflag){ labels = !dtx->ContnumFlag; } else{ labels = dtx->ContnumFlag; } /* Loop over antialiasing passes */ for (i=0; i < (dtx->PrettyFlag ? AA_PASSES : 1); i++) { start_aa_pass(i); /*** Draw 3-D lines ***/ clipping_off(); /* MJK 12.02.98 begin */ if (dtx->DisplayCursor) { if (dtx->DisplayProbe) { /* MJK 3.29.99 */ if (dtx->Reversed){ draw_cursor (dtx, 0, dtx->CursorX, dtx->CursorY, dtx->CursorZ, PACK_COLOR(0,0,0,255)); } else{ draw_cursor (dtx, 0, dtx->CursorX, dtx->CursorY, dtx->CursorZ, dtx->BoxColor); } } else if (dtx->DisplaySound) { /* MJK 3.29.99 */ if (dtx->Reversed){ draw_cursor (dtx, 2, dtx->CursorX, dtx->CursorY, 0, PACK_COLOR(0,0,0,255)); } else{ draw_cursor (dtx, 2, dtx->CursorX, dtx->CursorY, 0, dtx->BoxColor); } } else { draw_cursor (dtx, dtx->RibbonFlag, dtx->CursorX, dtx->CursorY, dtx->CursorZ, *dtx->CursorColor); } if (dtx->DisplayBox) { print_cursor_position (dtx, dtx->CurTime); } } /* MJK 12.02.98 end */ clipping_on(); for (yo = 0; yo < dtx->numofitxs; yo++){ itx = dtx->itxpointerarray[yo]; render_textplots( itx, itx->CurTime); } for (yo= 0; yo < dtx->numofctxs; yo++){ ctx = dtx->ctxpointerarray[yo]; if (check_for_valid_time(ctx, dtx->CurTime)){ render_hslices( ctx, ctx->CurTime, labels, animflag ); render_vslices( ctx, ctx->CurTime, labels, animflag ); render_hwind_slices( ctx, ctx->CurTime, animflag ); render_vwind_slices( ctx, ctx->CurTime, animflag ); render_hstream_slices( ctx, ctx->CurTime, animflag ); render_vstream_slices( ctx, ctx->CurTime, animflag ); } } /* draw user graphics */ draw_user_3d_graphics( dtx ); /*** Draw opaque 3-D graphics ***/ /* MJK 12.02.98 begin */ set_depthcue( dtx->DepthCue ); if (dtx->topo && dtx->topo->TopoFlag && dtx->topo->DisplayTopo) { set_depthcue(0); draw_topo( dtx, dtx->CurTime, dtx->DisplayTexture, 0 ); } else if (dtx->DisplayTexture) { /* just draw flat textured image */ set_depthcue(0); draw_topo( dtx, dtx->CurTime, 1, 1 ); } if (dtx->MapFlag && dtx->DisplayMap) { if (dtx->DisplaySfcMap) { set_color( dtx->DarkMapColor ); draw_map( dtx, dtx->CurTime, 0 ); } else { set_color( dtx->LightMapColor ); draw_map( dtx, dtx->CurTime, 1 ); } /* MJK 3.29.99 */ if (dtx->Reversed){ set_color( PACK_COLOR(0,0,0,255) ); } else{ set_color( dtx->BoxColor ); } } set_depthcue(0); /* MJK 12.02.98 end */ for (yo= 0; yo < dtx->numofctxs; yo++){ ctx = dtx->ctxpointerarray[yo]; if (check_for_valid_time(ctx, dtx->CurTime)){ if(ctx->DataGridList){ glCallList(ctx->DataGridList); } render_trajectories( ctx, ctx->CurTime, 1); render_isosurfaces( ctx, dtx->CurTime, ctx->CurTime, 1, animflag ); render_chslices( ctx, ctx->CurTime, 1, animflag ); render_cvslices( ctx, ctx->CurTime, 1, animflag ); } } /*** Draw transparent 3-D objects ***/ for (yo= 0; yo < dtx->numofctxs; yo++){ ctx = dtx->ctxpointerarray[yo]; if (check_for_valid_time(ctx, dtx->CurTime)){ render_trajectories( ctx, ctx->CurTime, 0); render_isosurfaces( ctx, dtx->CurTime, ctx->CurTime, 0, animflag ); render_chslices( ctx, ctx->CurTime, 0, animflag ); render_cvslices( ctx, ctx->CurTime, 0, animflag ); } } if (dtx->VolumeFlag==1 && dtx->CurrentVolume!=-1){ ctx = dtx->ctxpointerarray[return_ctx_index_pos(dtx, dtx->CurrentVolumeOwner)]; if (check_for_valid_time(ctx, dtx->CurTime)){ draw_volume( ctx, ctx->CurTime, dtx->CurrentVolume, dtx->ColorTable[VIS5D_VOLUME_CT]->Colors[ctx->context_index*MAXVARS+ dtx->CurrentVolume] ); } } end_aa_pass(i); } /* aa passes */ } /* * Only draw the 2-D elements of the scene. No matrix, viewport, etc * operations are done here. * Input: ctx - the context */ void render_2d_only( Display_Context dtx ) { if (dtx->DisplayClock) { /* MJK 3.29.99 */ if (dtx->Reversed){ draw_clock( dtx, PACK_COLOR(0,0,0,255) ); draw_logo( dtx, PACK_COLOR(0,0,0,255) ); } else{ draw_clock( dtx, dtx->BoxColor ); draw_logo( dtx, dtx->BoxColor ); } } if (dtx->DisplayInfo) { print_info(dtx); } if (dtx->DisplayProbe) { draw_probe(dtx); } if (dtx->DisplayCursor && dtx->DisplayBox) { print_cursor_position( dtx, dtx->CurTime ); } if (dtx->PointerX>=0 && dtx->PointerY>=0){ draw_fake_pointer(dtx); /* for remote widget mode */ } /* MJK 3.29.99 */ /* Moved to render_text_labels JPE if (dtx->Reversed){ set_color( PACK_COLOR(0,0,0,255) ); } else{ set_color( dtx->LabelColor ); } */ render_text_labels(dtx); /* Draw color map legends of color slices (as much as fit in window) */ if (dtx->DisplayLegends ) { draw_color_legends(dtx); } draw_user_2d_graphics( dtx ); } /* * * draw everything that belongs inside of * the Sounding Graphics Window * * */ void render_sounding_only( Display_Context dtx, int pixmapflag ) { if (dtx->DisplaySound) { if ( pixmapflag == 1 ){ do_pixmap_art( dtx ); /* MJK 12.02.98 */ /* draw_sounding(dtx, dtx->CurTime); */ } if ((dtx->CursorX != dtx->Sound.currentX || dtx->CursorY != dtx->Sound.currentY) || (dtx->CurTime != dtx->Sound.currentTime) || /* MJK 12.02.98 */ (pixmapflag)){ if (dtx->CurTime != dtx->Sound.currentTime){ reload_sounding_data( dtx ); } draw_sounding(dtx, dtx->CurTime); dtx->Sound.currentX = dtx->CursorX; dtx->Sound.currentY = dtx->CursorY; dtx->Sound.currentTime = dtx->CurTime; } } } /* * Redraw everything in the 3-D window but don't display it yet. Call * swap_3d_window() to do that. * Input: ctx - the vis5d context * animflag - 1=animating, 0=notanimating * Return: 0 = ok, -1 = error. */ void render_everything( Display_Context dtx, int animflag ) { if (get_frame(dtx, dtx->CurTime)) { return; } /*** Draw 3-D Objects ***/ set_3d( dtx->GfxProjection, dtx->FrntClip, dtx->Zoom, (float*) dtx->CTM); if(dtx->StereoOn){ /* * The set_3d call should have set the model matrix and the * projection matrix correctly. The stereo_set_3d_perspective * call just changes the projection matrix slightly. */ /* left eye */ stereo_set_3d_perspective(VIS5D_STEREO_LEFT,dtx->FrntClip); stereo_set_buff(VIS5D_STEREO_LEFT); clear_color (dtx->BgColor); clear_3d_window(); if (dtx->DisplayBox){ int i; for (i=0; i < (dtx->PrettyFlag ? AA_PASSES : 1); i++) { start_aa_pass(i); draw_box(dtx, dtx->CurTime); /* draw_tick_marks( dtx ); */ end_aa_pass(i); } } clipping_on(); render_3d_only( dtx, animflag ); clipping_off(); if (dtx->DisplayClips){ render_vclips( dtx, animflag ); render_hclips( dtx, animflag ); } /* right eye */ stereo_set_3d_perspective(VIS5D_STEREO_RIGHT,dtx->FrntClip); stereo_set_buff(VIS5D_STEREO_RIGHT); clear_color (dtx->BgColor); clear_3d_window(); if (dtx->DisplayBox){ int i; for (i=0; i < (dtx->PrettyFlag ? AA_PASSES : 1); i++) { start_aa_pass(i); draw_box(dtx, dtx->CurTime); /* draw_tick_marks( dtx ); */ end_aa_pass(i); } } clipping_on(); render_3d_only( dtx, animflag ); clipping_off(); if (dtx->DisplayClips){ render_vclips( dtx, animflag ); render_hclips( dtx, animflag ); } /* reset to default draw buffer */ stereo_set_buff(VIS5D_STEREO_BOTH); }else{ /* * The clear_3d_window call was moved out of vis5d_draw_frame and moved * down into this function so stereo and mono rendering loops can both * work with the same higher level api function. */ clear_3d_window(); clear_color (dtx->BgColor); if (dtx->DisplayBox){ int i, listflag=0; for (i=0; i < (dtx->PrettyFlag ? AA_PASSES : 1); i++) { start_aa_pass(i); draw_box(dtx, dtx->CurTime); /* draw_tick_marks( dtx ); */ end_aa_pass(i); } } clipping_on(); render_3d_only( dtx, animflag ); clipping_off(); if (dtx->DisplayClips){ render_vclips( dtx, animflag ); render_hclips( dtx, animflag ); } } /*** Draw 2-D objects ***/ set_2d(); render_2d_only( dtx ); /*** Draw Sounding ***/ render_sounding_only( dtx , 0); if (dtx->AnimRecord) { save_frame( dtx, dtx->CurTime ); } finish_rendering(); }