/***********************************************************************/ /* Open Visualization Data Explorer */ /* (C) Copyright IBM Corp. 1989,1999 */ /* ALL RIGHTS RESERVED */ /* This code licensed under the */ /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */ /***********************************************************************/ #include #ifndef hwPolyhedrawDraw_c_h #define hwPolyhedrawDraw_c_h /*---------------------------------------------------------------------------*\ $Source: /home/gda/dxcvs/dx/src/exec/hwrender/starbase/hwPolyhedraDrawSB.c.h,v $ Author: Mark Hood \*---------------------------------------------------------------------------*/ #include "hwXfield.h" /*#define USE_POLYHEDRA*/ /*#define COMPOSITE*/ typedef struct { int numFacets ; int numVertices ; int index[VerticesPerFacet] ; } FacetSet ; #ifdef COMPOSITE /* * Make a sort routine called polysort() with access to some global data. */ static Point Z, *sPts ; static int *sConnect, *sortArray ; static float II[4][4], I[4][4] = {{1,0,0,0}, {0,1,0,0}, {0,0,1,0}, {0,0,0,1}} ; #define TYPE int #define LT(a,b) (DXDot(Z,sPts[sConnect[*(a)]]) < DXDot(Z,sPts[sConnect[*(b)]])) #define GT(a,b) (DXDot(Z,sPts[sConnect[*(a)]]) > DXDot(Z,sPts[sConnect[*(b)]])) #define QUICKSORT polysort #include "qsort.c" #endif #ifdef DEBUG #define DebugMessage() \ { \ int i ; \ float outx, outy, outz ; \ float minx, maxx, miny, maxy, minz, maxz ; \ \ fprintf (stderr, "\nnumber of points: %d", xf->npositions) ; \ fprintf (stderr, "\n%d invalid positions", \ xf->invPositions? DXGetInvalidCount(xf->invPositions): 0) ; \ fprintf (stderr, "\nnumber of connections: %d", xf->nconnections) ; \ fprintf (stderr, "\n%d invalid connections", \ xf->invCntns? DXGetInvalidCount(xf->invCntns): 0) ; \ fprintf (stderr, "\ncolors: 0x%x, color_map: 0x%x, dep on pos: %d", \ (int)fcolors, (int)color_map, xf->colorsDep == dep_positions) ; \ \ minx = miny = minz = +MAXFLOAT ; \ maxx = maxy = maxz = -MAXFLOAT ; \ for (i=0 ; inpositions ; i++) \ { \ if (points[i].x < minx) minx = points[i].x ; \ if (points[i].y < miny) miny = points[i].y ; \ if (points[i].z < minz) minz = points[i].z ; \ \ if (points[i].x > maxx) maxx = points[i].x ; \ if (points[i].y > maxy) maxy = points[i].y ; \ if (points[i].z > maxz) maxz = points[i].z ; \ } \ \ transform_point(FILDES, MC_TO_VDC, minx, miny, minz, &outx, &outy, &outz) ; \ fprintf(stderr, "\nmin MC->VDC %9f %9f %9f -> %9f %9f %9f", \ minx, miny, minz, outx, outy, outz) ; \ \ transform_point(FILDES, MC_TO_VDC, maxx, maxy, maxz, &outx, &outy, &outz) ; \ fprintf(stderr, "\nmax MC->VDC %9f %9f %9f -> %9f %9f %9f", \ maxx, maxy, maxz, outx, outy, outz) ; \ } #else #define DebugMessage() {} #endif /* DEBUG */ int tdmPolyhedraDraw (tdmPortHandleP portHandle, xfieldT *xf, int buttonUp) { register float *clist = 0 ; register int i, j, vsize, dV, pstride, dP, npoints ; int nshapes, *connections, mod, cOffs, numPolys, vertex_flags ; tdmPolyhedraCacheSB *cache = 0 ; FacetSet ilist[FacetsPerPolyhedron] ; Point *points ; RGBColor *fcolors, *color_map ; char *cache_id ; enum approxE approx ; DEFPORT(portHandle) ; ENTRY(("tdmPolyhedraDraw(0x%x, 0x%x, %d)", portHandle, xf, buttonUp)); /* * Extract required data from the xfield. */ points = (Point *) DXGetArrayData (xf->positions_array) ; color_map = (RGBColor *) DXGetArrayData(xf->cmap_array) ; if (DXGetArrayClass(xf->fcolors_array) == CLASS_CONSTANTARRAY) fcolors = (Pointer) DXGetArrayEntry(xf->fcolors, 0, NULL) ; else fcolors = (Pointer) DXGetArrayData(xf->fcolors_array) ; connections = (int *) DXGetArrayData (xf->connections_array) ; nshapes = xf->nconnections ; npoints = xf->npositions ; if (buttonUp) { mod = xf->attributes.buttonUp.density ; approx = xf->attributes.buttonUp.approx ; } else { mod = xf->attributes.buttonDown.density ; approx = xf->attributes.buttonDown.approx ; } DebugMessage() ; cOffs = 0 ; vsize = 3 ; /* number of floats per vertex */ vertex_flags = 0 ; /* assume no extra vertex data */ numPolys = nshapes/mod ; /* number of polyhedra to draw */ pstride = PolyhedraSize*mod ; /* indices to next polyhedron */ /* use z-buffer, cull backface */ hidden_surface (FILDES, TRUE, TRUE) ; /* volume primitives are rendered without lighting computations */ shade_mode (FILDES, CMAP_FULL, FALSE) ; /* transparency is off */ alpha_transparency (FILDES, 0, 0, 0.0, 0.0) ; switch (approx) { case approx_dots: interior_style (FILDES, INT_POINT, FALSE) ; break ; case approx_lines: interior_style (FILDES, INT_OUTLINE, FALSE) ; break ; default: case approx_none: interior_style (FILDES, INT_SOLID, FALSE) ; break ; } if (xf->colorsDep == dep_field) { cache_id = CpfPolyhedra ; SET_COLOR (fill_color, 0) ; } else if (xf->colorsDep == dep_connections) cache_id = CpcPolyhedra ; else cache_id = CpvPolyhedra ; PRINT(("cache_id = %s", cache_id)); PRINT(("%d polyhedra to be rendered", numPolys)); /* check vertex color */ if (fcolors && xf->colorsDep == dep_positions) { /* vertex has at least 6 floats, with color at float 3 */ vsize = 6 ; cOffs = 3 ; vertex_flags |= VERTEX_COLOR ; } #ifdef USE_POLYHEDRA /* construct coordinate list */ if (! vertex_flags) /* points array can be used for the coordinate list */ clist = (float *) points ; else if (cache = tdmGetPolyhedraCacheSB (cache_id, 0, xf)) /* use cached coordinate list */ clist = cache->clist ; else { /* allocate coordinate list, copy vertex data */ clist = (float *) tdmAllocate(npoints*vsize*sizeof(float)) ; if (!clist) DXErrorGoto(ERROR_INTERNAL, "#13000") ; /* copy vertex coordinates into clist */ for (i=0, dV=0 ; iinvCntns && !DXIsElementValid (xf->invCntns, dP/PolyhedraSize)) /* skip invalid polyhedra */ continue ; #else /* *render polyhedra in order given */ for (i=0, dP=0 ; iinvCntns && !DXIsElementValid (xf->invCntns, i)) /* skip invalid polyhedra */ continue ; if (fcolors && xf->colorsDep == dep_connections) SET_COLOR (fill_color, dP/PolyhedraSize) ; #if (PolyhedraSize == 4) /* construct tetrahedral indices list */ ilist[0].numFacets = 1 ; ilist[0].numVertices = 3 ; ilist[0].index[0] = connections[dP+0] ; ilist[0].index[1] = connections[dP+1] ; ilist[0].index[2] = connections[dP+2] ; ilist[1].numFacets = 1 ; ilist[1].numVertices = 3 ; ilist[1].index[0] = connections[dP+0] ; ilist[1].index[1] = connections[dP+3] ; ilist[1].index[2] = connections[dP+1] ; ilist[2].numFacets = 1 ; ilist[2].numVertices = 3 ; ilist[2].index[0] = connections[dP+1] ; ilist[2].index[1] = connections[dP+3] ; ilist[2].index[2] = connections[dP+2] ; ilist[3].numFacets = 1 ; ilist[3].numVertices = 3 ; ilist[3].index[0] = connections[dP+2] ; ilist[3].index[1] = connections[dP+3] ; ilist[3].index[2] = connections[dP+0] ; #endif #if (PolyhedraSize == 8) /* construct cubic indices list */ ilist[0].numFacets = 1 ; ilist[0].numVertices = 4 ; ilist[0].index[0] = connections[dP+0] ; ilist[0].index[1] = connections[dP+1] ; ilist[0].index[2] = connections[dP+3] ; ilist[0].index[3] = connections[dP+2] ; ilist[1].numFacets = 1 ; ilist[1].numVertices = 4 ; ilist[1].index[0] = connections[dP+0] ; ilist[1].index[1] = connections[dP+2] ; ilist[1].index[2] = connections[dP+6] ; ilist[1].index[3] = connections[dP+4] ; ilist[2].numFacets = 1 ; ilist[2].numVertices = 4 ; ilist[2].index[0] = connections[dP+2] ; ilist[2].index[1] = connections[dP+3] ; ilist[2].index[2] = connections[dP+7] ; ilist[2].index[3] = connections[dP+6] ; ilist[3].numFacets = 1 ; ilist[3].numVertices = 4 ; ilist[3].index[0] = connections[dP+4] ; ilist[3].index[1] = connections[dP+6] ; ilist[3].index[2] = connections[dP+7] ; ilist[3].index[3] = connections[dP+5] ; ilist[4].numFacets = 1 ; ilist[4].numVertices = 4 ; ilist[4].index[0] = connections[dP+0] ; ilist[4].index[1] = connections[dP+4] ; ilist[4].index[2] = connections[dP+5] ; ilist[4].index[3] = connections[dP+1] ; ilist[5].numFacets = 1 ; ilist[5].numVertices = 4 ; ilist[5].index[0] = connections[dP+1] ; ilist[5].index[1] = connections[dP+5] ; ilist[5].index[2] = connections[dP+7] ; ilist[5].index[3] = connections[dP+3] ; #endif #ifdef USE_POLYHEDRA /* send polyhedron to Starbase */ polyhedron_with_data (FILDES, clist, npoints, vsize-3, vertex_flags, (int *)ilist, NULL, FacetsPerPolyhedron, NULL) ; #else /* use polygon_with_data3d() */ for (j=0 ; j