static void TrimCovar (Mat &Covar, int nTrimCovar, unsigned ProfSpec) { ASSERT(IS_2D(ProfSpec)); ASSERT(nTrimCovar > 0); int width = nGetProfWidth(Covar.ncols(), ProfSpec); // so parameter nTrimCovar=1 corresponds only to diag elems const int nTrimCovar1 = nTrimCovar - 1; ASSERT(nTrimCovar1 <= (width-1)/ 2); Mat NewCovar(Covar.nrows(), Covar.ncols()); NewCovar.fill(0); // upper triangle blocks (each block is width x width) for (int iyBlock = 0; iyBlock < width; iyBlock++) for (int ixBlock = iyBlock+1; ixBlock < width; ixBlock++) if (ABS(ixBlock - iyBlock) <= nTrimCovar1) { const int iyMin = iyBlock * width; const int iyMax = iyMin + width; for (int iy = iyMin; iy < iyMax; iy++) { const int ixMin = MAX(0, iy % width - nTrimCovar1) + ixBlock * width; const int ixMax = MIN(width-1, iy % width + nTrimCovar1) + ixBlock * width; for (int ix = ixMin; ix <= ixMax; ix++) NewCovar(iy, ix) = Covar(iy, ix); } } // diagonal blocks (done separately for efficiency -- reduces the number // of compares in inner loops) for (int iBlock = 0; iBlock < width; iBlock++) { const int iyMin = iBlock * width; const int iyMax = iyMin + width; for (int iy = iyMin; iy < iyMax; iy++) { const int ixMin = MAX(0, iy % width - nTrimCovar1) + iBlock * width; const int ixMax = MIN(width-1, iy % width + nTrimCovar1) + iBlock * width; for (int ix = ixMin; ix <= ixMax; ix++) NewCovar(iy, ix) = Covar(iy, ix); } } Covar = NewCovar; // make symmetrical again (so we can check it later for pos definiteness) const int nRows = Covar.nrows(); for (int i = 0; i < nRows; i++) for (int j = 0; j < i; j++) Covar(i,j) = Covar(j,i); }
int _dxfPlineDraw (tdmPortHandleP portHandle, xfieldT *xf, int buttonUp) { Vector *normals ; Point *points = 0 ; struct p2d {float x, y ;} *pnts2d = 0 ; RGBColor *fcolors, *color_map ; char *cache_id ; enum approxE approx ; tdmStripArraySB *stripsSB = 0 ; int type, rank, shape, is_2d ; DEFPORT(portHandle) ; ENTRY(("_dxfPlineDraw(0x%x, 0x%x, %d)", portHandle, xf, buttonUp)); /* * Transparent surfaces are stripped for those ports which implement * transparency with the screen door technique, but we need to sort them * as individual polygons to apply the more accurate alpha composition * method supported by Starbase. * * Connection-dependent colors are not supported by Starbase strips. */ approx = buttonUp ? xf->attributes.buttonUp.approx : xf->attributes.buttonDown.approx ; if ( #ifdef ALLOW_LINES_APPROX_BY_DOTS (approx == approx_dots) || #endif (xf->colorsDep == dep_connections)) { int status ; PRINT(("drawing as individual polygons")); status = _dxfLineDraw (portHandle, xf, buttonUp) ; EXIT(("")); return status ; } /* * Extract rendering data from the xfield. */ if (DXGetArrayClass(xf->fcolors_array) == CLASS_CONSTANTARRAY) fcolors = (Pointer) DXGetArrayEntry(xf->fcolors, 0, NULL) ; else fcolors = (Pointer) DXGetArrayData(xf->fcolors_array) ; color_map = (RGBColor *) DXGetArrayData(xf->cmap_array) ; if (DXGetArrayClass(xf->normals_array) == CLASS_CONSTANTARRAY) normals = (Pointer) DXGetArrayEntry(xf->normals, 0, NULL) ; else normals = (Pointer) DXGetArrayData(xf->normals_array) ; #if 0 if (xf->colorsDep != dep_field) { /* * Dense fields of varying colors are visually confusing * without hidden surface, even with wireframe approximation. */ hidden_surface (FILDES, TRUE, FALSE) ; } else /* RE : <LUMBA281> */ { hidden_surface(FILDES, TRUE, FALSE); } #endif hidden_surface(FILDES, TRUE, FALSE); if (xf->colorsDep == dep_field) { /* render field in constant color */ cache_id = "CpfPline" ; SET_COLOR(fill_color, 0) ; SET_COLOR(line_color, 0) ; } else { cache_id = "CpfPline" ; } /* * Render strips. */ PRINT(("%s", cache_id)); if (stripsSB = tdmGetTmeshCacheSB (cache_id, xf)) { /* * Use pre-constructed Starbase strips obtained from executive cache. */ register tdmTmeshCacheSB *stripArray, *end ; PRINT(("got strips from cache")); PrintBounds() ; stripArray = stripsSB->stripArray ; end = &stripArray[stripsSB->num_strips] ; for ( ; stripArray < end ; stripArray++) { polyline_with_data3d (FILDES, stripArray->clist, stripArray->numverts, stripArray->numcoords, stripArray->vertex_flags, NULL) ; } } else { /* * Construct an array of Starbase strips and cache it. */ register int vsize ; int *connections, (*strips)[2] ; int cOffs, nOffs, vertex_flags, facet_flags, numStrips ; tdmTmeshCacheSB *stripArray ; PRINT(("building new strips")); /* determine vertex and facet types and sizes */ vertex_flags = 0 ; facet_flags = UNIT_NORMALS ; vsize = 3 ; if (fcolors && xf->colorsDep != dep_field) { /* vertex has at least 6 floats, with color at float 3 */ vsize = 6 ; cOffs = 3 ; vertex_flags |= VERTEX_COLOR ; } /* get positions */ if (is_2d = IS_2D (xf->positions_array, type, rank, shape)) pnts2d = (struct p2d *) DXGetArrayData(xf->positions_array) ; else points = (Point *) DXGetArrayData(xf->positions_array) ; /* get strip topology */ connections = (int *)DXGetArrayData(xf->connections_array) ; strips = (int (*)[2])DXGetArrayData(xf->meshes) ; numStrips = xf->nmeshes ; DebugMessage() ; /* allocate space for Starbase strip data */ stripsSB = (tdmStripArraySB *) tdmAllocate(sizeof(tdmStripArraySB)) ; if (!stripsSB) { PRINT(("out of memory allocating strip structure")); DXErrorGoto (ERROR_INTERNAL, "#13000") ; } stripsSB->stripArray = 0 ; stripsSB->num_strips = 0 ; /* allocate array of Starbase strips */ stripArray = stripsSB->stripArray = (tdmTmeshCacheSB *) tdmAllocate(numStrips*sizeof(tdmTmeshCacheSB)); if (!stripArray) { PRINT(("out of memory allocating array of strips")); DXErrorGoto (ERROR_INTERNAL, "#13000") ; } for ( ; stripsSB->num_strips < numStrips ; stripsSB->num_strips++) { /* each iteration constructs and draws one Starbase strip */ register float *clist = 0, *gnormals = 0 ; register int i, dV, *pntIdx, numPnts ; stripArray->clist = 0 ; stripArray->gnormals = 0 ; /* get the number of points in this strip */ numPnts = strips[stripsSB->num_strips][1] ; /* allocate coordinate list */ stripArray->clist = clist = (float *) tdmAllocate(numPnts*vsize*sizeof(float)) ; if (!clist) { PRINT(("out of memory allocating coordinate list")); DXErrorGoto(ERROR_INTERNAL, "#13000") ; } /* get the sub-array of connections making up this strip */ pntIdx = &connections[strips[stripsSB->num_strips][0]] ; /* copy vertex coordinates into clist */ if (is_2d) for (i=0, dV=0 ; i<numPnts ; i++, dV+=vsize) { *(struct p2d *)(clist+dV) = pnts2d[pntIdx[i]] ; ((Point *)(clist+dV))->z = 0 ; } else for (i=0, dV=0 ; i<numPnts ; i++, dV+=vsize) *(Point *)(clist+dV) = points[pntIdx[i]] ; /* copy vertex colors */ if (vertex_flags & VERTEX_COLOR) if (color_map) for (i=0, dV=cOffs ; i<numPnts ; i++, dV+=vsize) *(RGBColor *)(clist+dV) = color_map[((char *)fcolors)[pntIdx[i]]] ; else for (i=0, dV=cOffs ; i<numPnts ; i++, dV+=vsize) *(RGBColor *)(clist+dV) = fcolors[pntIdx[i]] ; /* save other strip info */ stripArray->numverts = numPnts ; stripArray->numcoords = vsize-3 ; stripArray->vertex_flags = vertex_flags ; stripArray->facet_flags = facet_flags ; polyline_with_data3d (FILDES, clist, numPnts, vsize-3, vertex_flags, NULL) ; /* increment strip */ stripArray++ ; } /* cache strip array */ tdmPutTmeshCacheSB (cache_id, xf, stripsSB) ; } /* restore hidden surface OFF */ hidden_surface(FILDES, FALSE, FALSE) ; EXIT(("OK")); return OK ; error: tdmFreeTmeshCacheSB((Pointer)stripsSB) ; hidden_surface(FILDES, FALSE, FALSE) ; EXIT(("ERROR")); return ERROR ; }
int _dxfPlineDraw (tdmPortHandleP portHandle, xfieldT *xf, int buttonUp) { Point *points = 0 ; struct p2d {float x, y ;} *pnts2d = 0 ; Vector *normals ; RGBColor *fcolors, *color_map ; Type type ; int rank, shape, is_2d ; float *opacities, *opacity_map ; char *cache_id ; tdmStripDataXGL *stripsXGL = 0 ; DEFPORT(portHandle) ; DPRINT("\n(_dxfPlineDraw") ; if(xf->colorsDep == dep_connections) return _dxfLineDraw(portHandle, xf, buttonUp); /* * Extract required data from the xfield. */ if (is_2d = IS_2D(xf->positions_array, type, rank, shape)) pnts2d = (struct p2d *) DXGetArrayData(xf->positions_array) ; else points = (Point *) DXGetArrayData(xf->positions_array) ; color_map = (RGBColor *) DXGetArrayData(xf->cmap_array) ; opacity_map = (float *) DXGetArrayData(xf->omap_array) ; if (DXGetArrayClass(xf->fcolors_array) == CLASS_CONSTANTARRAY) fcolors = (Pointer) DXGetArrayEntry(xf->fcolors, 0, NULL) ; else fcolors = (Pointer) DXGetArrayData(xf->fcolors_array) ; if (DXGetArrayClass(xf->opacities_array) == CLASS_CONSTANTARRAY) opacities = (Pointer) DXGetArrayEntry(xf->opacities, 0, NULL) ; else opacities = (Pointer) DXGetArrayData(xf->opacities_array) ; DebugMessage() ; /* set default attributes for surface and wireframe approximation */ xgl_object_set (XGLCTX, XGL_CTX_LINE_COLOR_SELECTOR, XGL_LINE_COLOR_VERTEX, XGL_3D_CTX_LINE_COLOR_INTERP, TRUE, 0) ; /* override above attributes according to color dependencies and lighting */ if (xf->colorsDep == dep_field) { /* * Field has constant color. Get color from context. */ CLAMP(&fcolors[0],&fcolors[0]) ; cache_id = "CpfPline" ; /* get line color from context */ xgl_object_set (XGLCTX, XGL_CTX_LINE_COLOR_SELECTOR, XGL_LINE_COLOR_CONTEXT, XGL_CTX_LINE_COLOR, &fcolors[0], NULL) ; } else { /* * Field has varying colors. Get colors from point data. */ cache_id = "CppPline" ; } DPRINT1("\n%s", cache_id) ; #if 0 /* may want this when we add transparent lines */ /* * Set up a simple 50% screen door approximation for opacities < 0.75. * We can't do opacity dep position or connection with this technique, * but constant opacity per field is adequate for many visualizations. * * USE_SCREEN_DOOR should only be true if we're using the GT through * the XGL 3.0 interface on Solaris; no other access to this effect is * provided by Sun. The GT with XGL 3.0 also provides alpha * transparency of some sort. It's not implemented here. */ xgl_object_set (XGLCTX, XGL_CTX_SURF_FRONT_FILL_STYLE, XGL_SURF_FILL_SOLID, NULL) ; if (opacities && USE_SCREEN_DOOR) if ((opacity_map? opacity_map[*(char *)opacities]: opacities[0]) < 0.75) xgl_object_set (XGLCTX, XGL_CTX_SURF_FRONT_FILL_STYLE, XGL_SURF_FILL_STIPPLE, XGL_CTX_SURF_FRONT_FPAT, SCREEN_DOOR_50, NULL) ; #endif if (stripsXGL = _dxf_GetTmeshCacheXGL (cache_id, xf)) { /* * Use pre-constructed xgl strips obtained from executive cache. */ register Xgl_pt_list *pt_list, *end ; DPRINT("\ngot strips from cache"); pt_list = stripsXGL->pt_lists ; end = &pt_list[stripsXGL->num_strips] ; for ( ; pt_list < end ; pt_list++) xgl_multipolyline (XGLCTX, NULL, 1, pt_list) ; } else { /* * Construct an array of xgl strips and cache it. */ register int vsize, fsize ; int v_cOffs, v_nOffs, vertex_flags, numStrips ; int *connections, (*strips)[2] ; Xgl_pt_list *xgl_pt_list ; DPRINT("\nbuilding new strips"); /* determine vertex types and sizes */ vsize = 3 ; fsize = 0 ; vertex_flags = XGL_D_3 | XGL_FLT | XGL_NFLG | XGL_NHOM | XGL_DIRECT ; if (fcolors && xf->colorsDep != dep_field) { /* vertex has 3 more floats to accomodate color */ v_cOffs = vsize ; vsize += 3 ; vertex_flags |= XGL__CLR ; } /* get strip topology */ connections = (int *)DXGetArrayData(xf->connections_array) ; strips = (int (*)[2])DXGetArrayData(xf->meshes) ; numStrips = xf->nmeshes ; /* allocate space for strip data */ stripsXGL = (tdmStripDataXGL *) tdmAllocate(sizeof(tdmStripDataXGL)); if (!stripsXGL) DXErrorGoto (ERROR_INTERNAL, "#13000") ; stripsXGL->pt_lists = 0 ; stripsXGL->facet_lists = 0 ; stripsXGL->num_strips = 0 ; /* allocate array of xgl point lists */ xgl_pt_list = stripsXGL->pt_lists = (Xgl_pt_list *) tdmAllocate(numStrips*sizeof(Xgl_pt_list)); if (!xgl_pt_list) DXErrorGoto (ERROR_INTERNAL, "#13000") ; for ( ; stripsXGL->num_strips < numStrips ; stripsXGL->num_strips++) { /* each iteration constructs and draws one xgl strip */ register float *clist, *flist ; register int i, dV, *pntIdx, numPnts ; /* get the number of points in this strip */ numPnts = strips[stripsXGL->num_strips][1] ; /* allocate coordinate list */ xgl_pt_list->pts.color_normal_f3d = (Xgl_pt_color_normal_f3d *) (clist = (float *) tdmAllocate(numPnts*vsize*sizeof(float))) ; if (!clist) DXErrorGoto (ERROR_INTERNAL, "#13000") ; /* get the sub-array of connections making up this strip */ pntIdx = &connections[strips[stripsXGL->num_strips][0]] ; /* copy vertex coordinates into clist */ if (is_2d) for (i=0, dV=0 ; i<numPnts ; i++, dV+=vsize) { *(struct p2d *)(clist+dV) = pnts2d[pntIdx[i]] ; ((Point *)(clist+dV))->z = 0 ; } else for (i=0, dV=0 ; i<numPnts ; i++, dV+=vsize) *(Point *)(clist+dV) = points[pntIdx[i]] ; /* copy vertex colors */ if (vertex_flags & XGL__CLR) if (color_map) for (i=0, dV=v_cOffs ; i<numPnts ; i++, dV+=vsize) CLAMP((clist+dV), &color_map[((char *)fcolors)[pntIdx[i]]]); else for (i=0, dV=v_cOffs ; i<numPnts ; i++, dV+=vsize) CLAMP((clist+dV),&fcolors[pntIdx[i]] ) ; /* set up other point list info */ xgl_pt_list->bbox = NULL ; xgl_pt_list->num_pts = numPnts ; xgl_pt_list->pt_type = vertex_flags ; /* send strip to xgl, increment pointlist pointers */ xgl_multipolyline (XGLCTX, NULL, 1, xgl_pt_list++) ; } /* cache all strip data */ _dxf_PutTmeshCacheXGL (cache_id, xf, stripsXGL) ; } DPRINT(")") ; return OK ; error: _dxf_FreeTmeshCacheXGL((Pointer)stripsXGL) ; DPRINT("\nerror)") ; return ERROR ; }