/***********************************************************************/ /* 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 /* * $Source: /home/gda/dxcvs/dx/src/exec/hwrender/hwPolyline.c,v $ * $L:$ */ #include #include "hwDeclarations.h" #include "hwXfield.h" #include "hwMemory.h" #include "hwDebug.h" typedef struct EdgeS { struct EdgeS *next; int edgeIndex; } EdgeT,*Edge; #define INSERT_EDGE(edgeI,ptI) { \ Edge edge; \ if(nextFreeEdge == xf->nconnections*2) goto error; \ else edge = &edgePool[nextFreeEdge++]; \ edge->edgeIndex = edgeI; \ edge->next = edges[ptI].next; \ edges[ptI].next = edge; \ } #define DELETE_EDGE(edgeI,ptI) { \ Edge tmp; \ tmp = &edges[ptI]; \ while(tmp->next && tmp->next->edgeIndex != edgeI) {tmp = tmp->next;} \ if(tmp->next) { \ Edge tmp1 = tmp->next; \ tmp->next = tmp->next->next;\ } \ } #define FIND_EDGE(ptI) (edges[ptI].next ? edges[ptI].next->edgeIndex : -1) #define OTHER_PTI(line,ptI) ((line->p == ptI) ? line->q : line->p) #if defined(DEBUG) static int histogram[21]; #endif Error _dxf_linesToPlines (xfieldT *xf) { int i; Line *line = NULL,lineScratch; int newEdgeI; Edge edges = NULL; int *polyline = NULL; Array array = NULL; int ptI,lastPtI; int plineOffset,plineIndex; Edge edgePool = NULL; int nextFreeEdge = 0; ENTRY(("_dxf_linesToPlines(0x%x)", xf)); /* allocate permanent xfield pline data of appropriate size */ /* Allocations are a guess based on 100 lines/polyline */ if (!(xf->meshes = DXNewArray (TYPE_INT, CATEGORY_REAL, 1, 2)) || !(DXAllocateArray (xf->meshes, xf->nconnections/100)) || !(array = DXNewArray (TYPE_INT, CATEGORY_REAL, 0)) || !(DXAllocateArray (array, xf->nconnections+xf->nconnections/100)) || !(edgePool = (Edge)DXAllocate(sizeof(EdgeT)*xf->nconnections * 2))) { PRINT(("could not allocate xfield mesh data")); DXErrorGoto(ERROR_NO_MEMORY, "#13000") ; } xf->nmeshes = 0 ; /* get line connection info; lines will be replaced by strips */ xf->origConnections_array = xf->connections_array ; xf->origNConnections = xf->nconnections; if(!(edges = (Edge)DXAllocateZero(xf->npositions * sizeof(EdgeT)))) DXErrorGoto(ERROR_NO_MEMORY, "#13000") ; if (!(polyline = (int *)DXAllocate((xf->nconnections+1) * sizeof(Edge)))) DXErrorGoto(ERROR_NO_MEMORY, "#13000") ; for(i=0;inconnections;i++) { if(xf->invCntns && !DXIsElementValid(xf->invCntns,i)) continue; if(!(line = DXGetArrayEntry(xf->connections,i,&lineScratch))) goto error; INSERT_EDGE(i,line->p); INSERT_EDGE(i,line->q); } lastPtI = 0; plineOffset = 0; plineIndex = 0; while (1) { int newPline[2] ; for(ptI=lastPtI;ptInpositions;ptI++) if((newEdgeI = FIND_EDGE(ptI)) >= 0) break; if(ptI == xf->npositions) break; lastPtI = ptI; while(newEdgeI >= 0) { if(!(line = DXGetArrayEntry(xf->connections,newEdgeI,&lineScratch))) goto error; polyline[plineIndex++] = ptI; DELETE_EDGE(newEdgeI,ptI); ptI = OTHER_PTI(line,ptI); DELETE_EDGE(newEdgeI,ptI); newEdgeI = FIND_EDGE(ptI); } polyline[plineIndex++] = ptI; newPline[0] = plineOffset; newPline[1] = plineIndex; #if defined(DEBUG) if(plineIndex >= 20) histogram[10]++; else histogram[plineIndex/2]++; #endif /* add the pline data to the xfield */ DXAddArrayData (xf->meshes, xf->nmeshes, 1, newPline) ; DXAddArrayData (array, plineOffset, plineIndex, polyline) ; xf->nmeshes++ ; plineOffset += plineIndex; plineIndex = 0; } /* Trim extra storage allocation from arrays */ DXTrim(xf->meshes); DXTrim(array); xf->connections_array = array; xf->nconnections = plineOffset + plineIndex; array = NULL; /* free old array handle and create a new one */ if (!(DXFreeArrayHandle(xf->connections)) || !(xf->connections = DXCreateArrayHandle(xf->connections_array))) { PRINT(("could not create new connections array handle")); DXErrorGoto(ERROR_NO_MEMORY, "#13000") ; } #if 0 DXReference((dxObject)xf->connections_array); DXReference((dxObject)xf->meshes); /* create a new array handleo */ if(!(xf->connections = DXCreateArrayHandle(xf->connections_array))) { PRINT(("could not create new connections array handle")); DXErrorGoto(ERROR_NO_MEMORY, "#13000") ; } #endif /* record connection info */ xf->posPerConn = 1 ; xf->connectionType = ct_pline; #if defined(DEBUG) for(i=0;i<11;i++) PRINT((" %3d",2*i)); PRINT((" >")); for(i=0;i<11;i++) { PRINT((" %3d",histogram[i])); histogram[i] = 0; } #endif DXFree(edgePool); DXFree(edges); DXFree(polyline); EXIT(("OK")); return OK ; error: if(edgePool) DXFree(edgePool); if(edges) DXFree(edges); if(polyline) DXFree(polyline); if(array) DXDelete((dxObject)array); if(xf->meshes) DXDelete((dxObject)xf->meshes); EXIT(("ERROR")); return 0 ; } Error _dxf_polylinesToPlines (xfieldT *xf) { int i; int start, end, knt; int *mesh; ENTRY(("_dxf_linesToPlines(0x%x)", xf)); /* allocate permanent xfield pline data of appropriate size */ /* Allocations are a guess based on 100 lines/polyline */ if (!(xf->meshes = DXNewArray(TYPE_INT, CATEGORY_REAL, 1, 2)) || !(DXAllocateArray (xf->meshes, xf->npolylines))) { PRINT(("could not allocate xfield mesh data")); DXErrorGoto(ERROR_NO_MEMORY, "#13000") ; } mesh = (int *)DXGetArrayData(xf->meshes); for (i = 0; i < xf->npolylines; i++) { start = xf->polylines[i]; end = (i+1 == xf->npolylines) ? xf->nedges : xf->polylines[i+1]; knt = end - start; if(xf->invCntns && !DXIsElementValid(xf->invCntns,i)) continue; *mesh++ = start; *mesh++ = knt; } xf->connections_array = (Array)DXReference((dxObject)xf->edges); xf->nconnections = xf->nedges; xf->nmeshes = xf->npolylines; /* record connection info */ xf->posPerConn = 1 ; xf->connectionType = ct_pline; EXIT(("OK")); return OK ; error: if(xf->meshes) DXDelete((dxObject)xf->meshes); EXIT(("ERROR")); return 0 ; }