/***********************************************************************/ /* 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" */ /***********************************************************************/ /*********************************************************************/ /* I.B.M. CONFIENTIAL */ /*********************************************************************/ #include /* * $Source: /home/gda/dxcvs/dx/src/exec/hwrender/xgl/hwPolylineDraw.c,v $ * */ #include #include #include #include "hwDeclarations.h" #include "hwPortXGL.h" #include "hwXfield.h" #include "hwMemory.h" #include "hwCacheUtilXGL.h" struct p2d {float x, y ;} ; #define DEF_ARGS \ tdmPortHandleP portHandle, xfieldT *xf, \ int mod, enum approxE approx, \ int npoints, Point *points, \ int nPl, int *polylines, int nE, int *edges, \ RGBColor *fcolors, RGBColor *color_map, \ int is_2d #define ARGS \ portHandle, xf, \ mod, approx, \ xf->npositions, points, \ xf->npolylines, xf->polylines, xf->nedges, xf->edges, \ fcolors, color_map, is_2d #ifdef MJHDEBUG #define DebugMessage() \ { \ int i ; \ Xgl_pt Min, Max ; \ Xgl_pt_f3d min, max ; \ \ fprintf (stderr, "\n2D: %s", is_2d ? "yes" : "no") ; \ fprintf (stderr, "\nnumber of points: %d", xf->npositions) ; \ fprintf (stderr, "\nnumber of connections: %d", nshapes) ; \ 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->fcolorsDep == dep_positions) ; \ \ min.x = min.y = min.z = +MAXFLOAT ; \ Min.pt_type = XGL_PT_F3D ; \ Min.pt.f3d = &min ; \ \ max.x = max.y = max.z = -MAXFLOAT ; \ Max.pt_type = XGL_PT_F3D ; \ Max.pt.f3d = &max ; \ \ if (is_2d) \ { \ struct p2d *pnts2d = (struct p2d *)points ; \ min.z = max.z = 0 ; \ for (i=0 ; inpositions ; i++) \ { \ if (pnts2d[i].x < min.x) min.x = pnts2d[i].x ; \ if (pnts2d[i].y < min.y) min.y = pnts2d[i].y ; \ \ if (pnts2d[i].x > max.x) max.x = pnts2d[i].x ; \ if (pnts2d[i].y > max.y) max.y = pnts2d[i].y ; \ } \ } \ else \ for (i=0 ; inpositions ; i++) \ { \ if (points[i].x < min.x) min.x = points[i].x ; \ if (points[i].y < min.y) min.y = points[i].y ; \ if (points[i].z < min.z) min.z = points[i].z ; \ \ if (points[i].x > max.x) max.x = points[i].x ; \ if (points[i].y > max.y) max.y = points[i].y ; \ if (points[i].z > max.z) max.z = points[i].z ; \ } \ \ xgl_transform_multiply (TMP_TRANSFORM, \ MODEL_VIEW_TRANSFORM, PROJECTION_TRANSFORM) ; \ \ fprintf (stderr, "\nmin MC->VDC %9f %9f %9f -> ", min.x, min.y, min.z) ; \ xgl_transform_point (TMP_TRANSFORM, &Min) ; \ fprintf (stderr, "%9f %9f %9f", min.x, min.y, min.z) ; \ \ fprintf (stderr, "\nmax MC->VDC %9f %9f %9f -> ", max.x, max.y, max.z) ; \ xgl_transform_point (TMP_TRANSFORM, &Max) ; \ fprintf (stderr, "%9f %9f %9f", max.x, max.y, max.z) ; \ } #else /* MJHDEBUG */ #define DebugMessage() {} #endif /* MJHDEBUG */ int tdmCdfPolylineDraw (DEF_ARGS) { char *mem ; int from_cache, i; int nextpt, nextpl; Xgl_pt_list *pt_list ; Xgl_color cpf_color ; Xgl_pt_f3d *pt_f3d ; struct p2d *pnts2d = (struct p2d *)points ; char *color_index = (char *)fcolors ; int nplines, nindices; DEFPORT(portHandle) ; DPRINT("\n(CdfPolylineDraw") ; if (mem = _dxf_GetLineCacheXGL ("CdfPolylineDraw", mod, xf)) { DPRINT("\ngot lines from cache") ; from_cache = 1 ; nplines = *(int *) mem ; pt_list = (Xgl_pt_list *) (mem + sizeof(int)) ; } else { DPRINT("\ngenerating XGL lines") ; from_cache = 0 ; if (xf->invCntns) { for (nplines = nindices = 0, i=0 ; iinvCntns, i)) { int estart = polylines[i]; int eend = (i >= nPl-1) ? nE : polylines[i+1]; nplines ++; nindices += (eend - estart); } } } else { nplines = nPl; nindices = nE; } mem = (char *) tdmAllocate (sizeof(int) + sizeof(Xgl_pt_list)*nplines + sizeof(Xgl_pt_f3d)*nindices) ; if (!mem) goto error; pt_list = (Xgl_pt_list *)(mem+sizeof(int)); pt_f3d = (Xgl_pt_f3d *)(mem+sizeof(int)+sizeof(Xgl_pt_list)*nplines); for (nextpl=0, nextpt=0, i=0 ; i < nPl ; i++ ) { if (! xf->invCntns || DXIsElementValid (xf->invCntns, i)) { int estart = polylines[i]; int eend = (i >= nPl-1) ? nE : polylines[i+1]; int e; pt_list[nextpl].pt_type = XGL_PT_F3D; pt_list[nextpl].pts.f3d = pt_f3d + nextpt; pt_list[nextpl].bbox = NULL; pt_list[nextpl].num_pts = eend - estart; nextpl ++; for (e = estart; e < eend; e++) { int index = edges[e]; if (is_2d) { *(struct p2d *)(pt_f3d+nextpt) = pnts2d[index]; pt_f3d[nextpt].z = 0 ; } else { pt_f3d[nextpt] = *(Xgl_pt_f3d *) &points[index]; } nextpt ++; } } } nplines = *((int *)mem) = nextpl; } if (color_map) CLAMP(&cpf_color,&color_map[color_index[0]]); else CLAMP(&cpf_color,&fcolors[0]) ; xgl_object_set (XGLCTX, XGL_CTX_LINE_COLOR_SELECTOR, XGL_LINE_COLOR_CONTEXT, XGL_CTX_LINE_COLOR, &cpf_color, 0) ; DPRINT("\ncall xgl_multipolyline") ; xgl_multipolyline (XGLCTX, NULL, nplines, pt_list) ; if (!from_cache) _dxf_PutLineCacheXGL ("CdfPolylineDraw", mod, xf, mem) ; DPRINT(")") ; return 1 ; error: DPRINT("\nerror)") ; return 0 ; } int tdmCdcPolylineDraw (DEF_ARGS) { char *mem ; int nplines, nindices, from_cache, i; int nextpt, nextpl; Xgl_pt_list *pt_list ; Xgl_pt_color_f3d *pt_color_f3d ; struct p2d *pnts2d = (struct p2d *)points ; DEFPORT(portHandle) ; DPRINT("\n(CdcPolylineDraw") ; if (mem = _dxf_GetLineCacheXGL ("CdcPolylineDraw", mod, xf)) { DPRINT("\ngot lines from cache") ; from_cache = 1 ; nplines = *(int *) mem ; pt_list = (Xgl_pt_list *) (mem + sizeof(int)) ; } else { DPRINT("\ngenerating XGL lines") ; from_cache = 0 ; if (xf->invCntns) { for (nplines = nindices = 0, i=0 ; iinvCntns, i)) { int estart = polylines[i]; int eend = (i >= nPl-1) ? nE : polylines[i+1]; nplines ++; nindices += (eend - estart); } } } else { nplines = nPl; nindices = nE; } mem = (char *) tdmAllocate (sizeof(int) + sizeof(Xgl_pt_list)*nplines + sizeof(Xgl_pt_color_f3d)*nindices) ; if (!mem) goto error; pt_list = (Xgl_pt_list *) (mem + sizeof(int)); pt_color_f3d = (Xgl_pt_color_f3d *) (mem + sizeof(int) + sizeof(Xgl_pt_list)*nplines) ; for (nextpl=0, nextpt=0, i=0 ; i < nPl ; i++ ) { if (! xf->invCntns || DXIsElementValid (xf->invCntns, i)) { int estart = polylines[i]; int eend = (i >= nPl-1) ? nE : polylines[i+1]; int e; pt_list[nextpl].pt_type = XGL_PT_COLOR_F3D; pt_list[nextpl].pts.color_f3d = pt_color_f3d + nextpt; pt_list[nextpl].bbox = NULL; pt_list[nextpl].num_pts = eend - estart; nextpl ++; for (e = estart; e < eend; e++) { int index = edges[e]; if (is_2d) { *(struct p2d *)(pt_color_f3d+nextpt) = pnts2d[index]; pt_color_f3d[nextpt].z = 0 ; } else { pt_color_f3d[nextpt] = *(Xgl_pt_color_f3d *) &points[index]; } if (color_map) { char *color_index = (char *)fcolors ; CLAMP(&pt_color_f3d[nextpt].color, &color_map[color_index[i]]) ; } else { CLAMP(&pt_color_f3d[nextpt].color, &fcolors[i]) ; } nextpt ++; } } } nplines = *((int *)mem) = nextpl; } if (approx == approx_dots) { /* * Dot approximations are more efficiently rendered by * _dxfUnconnectedPointDraw(), but connection-dependent colors * are not be handled by that routine. */ Xgl_pt_list dot_pt_list ; dot_pt_list.pt_type = XGL_PT_COLOR_F3D ; dot_pt_list.pts.color_f3d = pt_color_f3d; dot_pt_list.bbox = NULL ; dot_pt_list.num_pts = nextpt; xgl_object_set (XGLCTX, #ifdef solaris XGL_CTX_MARKER, xgl_marker_dot, #else XGL_CTX_MARKER_DESCRIPTION, xgl_marker_dot, #endif XGL_CTX_MARKER_COLOR_SELECTOR, XGL_MARKER_COLOR_POINT, NULL) ; DPRINT("\ncalling xgl_multimarker") ; xgl_multimarker (XGLCTX, &dot_pt_list) ; } else { xgl_object_set (XGLCTX, XGL_CTX_LINE_COLOR_SELECTOR, XGL_LINE_COLOR_VERTEX, XGL_3D_CTX_LINE_COLOR_INTERP, FALSE, 0) ; DPRINT("\ncalling xgl_multipolyline") ; xgl_multipolyline (XGLCTX, NULL, nplines, pt_list) ; } if (!from_cache) _dxf_PutLineCacheXGL ("CdcPolylineDraw", mod, xf, mem) ; DPRINT(")") ; return 1 ; error: DPRINT("\nerror)") ; return 0 ; } int tdmCdpPolylineDraw (DEF_ARGS) { char *mem ; int from_cache, i; int nextpt, nextpl; Xgl_pt_list *pt_list ; Xgl_pt_color_f3d *pt_color_f3d ; struct p2d *pnts2d = (struct p2d *)points ; int nplines, nindices; DEFPORT(portHandle) ; DPRINT("\n(CdpPolylineDraw") ; if (mem = _dxf_GetLineCacheXGL ("CdpPolylineDraw", mod, xf)) { DPRINT("\ngot lines from cache") ; from_cache = 1 ; nplines = *(int *) mem ; pt_list = (Xgl_pt_list *) (mem + sizeof(int)) ; } else { DPRINT("\ngenerating XGL lines") ; from_cache = 0 ; if (xf->invCntns) { for (nplines = nindices = 0, i=0 ; iinvCntns, i)) { int estart = polylines[i]; int eend = (i >= nPl-1) ? nE : polylines[i+1]; nplines ++; nindices += (eend - estart); } } } else { nplines = nPl; nindices = nE; } mem = (char *) tdmAllocate (sizeof(int) + sizeof(Xgl_pt_list)*nplines + sizeof(Xgl_pt_color_f3d)*nindices) ; if (!mem) goto error; *((int *)mem) = nplines; pt_list = (Xgl_pt_list *) (mem + sizeof(int)) ; pt_color_f3d = (Xgl_pt_color_f3d *) (mem + sizeof(int) + sizeof(Xgl_pt_list)*nplines) ; for (nextpl=0, nextpt=0, i=0 ; i < nPl ; i++ ) { if (! xf->invCntns || DXIsElementValid (xf->invCntns, i)) { int estart = polylines[i]; int eend = (i >= nPl-1) ? nE : polylines[i+1]; int e; pt_list[nextpl].pt_type = XGL_PT_COLOR_F3D; pt_list[nextpl].pts.color_f3d = pt_color_f3d + nextpt; pt_list[nextpl].bbox = NULL; pt_list[nextpl].num_pts = eend - estart; nextpl ++; for (e = estart; e < eend; e++) { int index = edges[e]; if (is_2d) { *(struct p2d *)(pt_color_f3d+nextpt) = pnts2d[index]; pt_color_f3d[nextpt].z = 0 ; } else { pt_color_f3d[nextpt] = *(Xgl_pt_color_f3d *) &points[index]; } if (color_map) { char *color_index = (char *)fcolors ; CLAMP(&pt_color_f3d[nextpt].color, &color_map[color_index[e]]) ; } else { CLAMP(&pt_color_f3d[nextpt].color, &fcolors[e]) ; } nextpt ++; } } } nplines = *((int *)mem) = nextpl; } xgl_object_set (XGLCTX, XGL_CTX_LINE_COLOR_SELECTOR, XGL_LINE_COLOR_VERTEX, XGL_3D_CTX_LINE_COLOR_INTERP, TRUE, 0) ; DPRINT("\ncalling xgl_multipolyline") ; xgl_multipolyline (XGLCTX, NULL, nplines, pt_list) ; if (!from_cache) _dxf_PutLineCacheXGL ("CdpPolylineDraw", mod, xf, mem) ; DPRINT(")") ; return 1 ; error: DPRINT("\nerror)") ; return 0 ; } int _dxfPolylineDraw (tdmPortHandleP portHandle, xfieldT *xf, int buttonUp) { Point *points ; RGBColor *fcolors, *color_map ; int *connections, mod, ret ; int nshapes; Type type ; int rank, shape, is_2d ; enum approxE approx ; DEFPORT(portHandle) ; DPRINT("\n(_dxfPolylineDraw") ; /* * Extract required data from the xfield. */ is_2d = IS_2D(xf->positions_array, type, rank, shape) ; points = (Point *) DXGetArrayData (xf->positions_array) ; color_map = (RGBColor *) DXGetArrayData(xf->cmap_array) ; if(xf->origConnections_array) { /* if the field has been made into a polyline, use origConnections */ connections = (int *) DXGetArrayData (xf->origConnections_array) ; nshapes = xf->origNConnections; } else { connections = (int *) DXGetArrayData (xf->connections_array) ; nshapes = xf->nconnections; } if (DXGetArrayClass(xf->fcolors_array) == CLASS_CONSTANTARRAY) fcolors = (Pointer) DXGetArrayEntry(xf->fcolors, 0, NULL) ; else fcolors = (Pointer) DXGetArrayData(xf->fcolors_array) ; if (buttonUp) { mod = xf->attributes.buttonUp.density ; approx = xf->attributes.buttonUp.approx ; } else { mod = xf->attributes.buttonDown.density ; approx = xf->attributes.buttonDown.approx ; } DebugMessage() ; if (xf->colorsDep == dep_field) ret = tdmCdfPolylineDraw(ARGS) ; else if (xf->colorsDep == dep_positions) ret = tdmCdpPolylineDraw(ARGS) ; else ret = tdmCdcPolylineDraw(ARGS) ; DPRINT(")") ; return ret ; }