/***********************************************************************/ /* 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 #include #include #include #include "linesRR1DClass.h" static void _dxfCleanup(LinesRR1DInterpolator); static Error _dxfInitializeTask(Pointer); static Error _dxfInitialize(LinesRR1DInterpolator); #define DIAGNOSTIC(str) \ DXMessage("regular lines interpolator failure: %s", (str)) int _dxfRecognizeLinesRR1D(Field field) { Array array; Array topology; int nDim; int status; CHECK(field, CLASS_FIELD); ELT_TYPECHECK(field, "lines"); status = OK; array = (Array)DXGetComponentValue(field, "positions"); if (!array) return ERROR; else { if (!DXQueryGridPositions(array, &nDim, NULL, NULL, NULL)) return ERROR; if (nDim != 1) return ERROR; } array = (Array)DXGetComponentValue(field, "connections"); if (!array) return ERROR; else { if (!DXQueryGridConnections(array, &nDim, NULL)) return ERROR; if (nDim != 1) return ERROR; } return status; } LinesRR1DInterpolator _dxfNewLinesRR1DInterpolator(Field field, enum interp_init initType, double fuzz, Matrix *m) { return (LinesRR1DInterpolator)_dxf_NewLinesRR1DInterpolator(field, initType, fuzz, m, &_dxdlinesrr1dinterpolator_class); } LinesRR1DInterpolator _dxf_NewLinesRR1DInterpolator(Field field, enum interp_init initType, float fuzz, Matrix *m, struct linesrr1dinterpolator_class *class) { LinesRR1DInterpolator li; float *mm, *MM; li = (LinesRR1DInterpolator)_dxf_NewFieldInterpolator(field, fuzz, m, (struct fieldinterpolator_class *)class); if (! li) return NULL; mm = ((Interpolator)li)->min; MM = ((Interpolator)li)->max; if ((MM[0] - mm[0]) == 0.0) { DXDelete((Object)li); return NULL; } li->dataArray = NULL; li->pointsArray = NULL; li->data = NULL; if (initType == INTERP_INIT_PARALLEL) { if (! DXAddTask(_dxfInitializeTask, (Pointer)&li, sizeof(li), 1.0)) { DXDelete((Object)li); return NULL; } } else if (initType == INTERP_INIT_IMMEDIATE) { if (! _dxfInitialize(li)) { DXDelete((Object)li); return NULL; } } return li; } static Error _dxfInitialize(LinesRR1DInterpolator li) { Field field; int nDim; int i; float origin; float delta; Type dataType; Category dataCategory; field = (Field)((Interpolator)li)->dataObject; /* * De-reference data */ li->dataArray = (Array)DXGetComponentValue(field, "data"); if (!li->dataArray) { DXSetError(ERROR_MISSING_DATA, "#10240", "data"); return ERROR; } DXReference((Object)li->dataArray); DXGetArrayInfo(li->dataArray, NULL, &((Interpolator)li)->type, &((Interpolator)li)->category, &((Interpolator)li)->rank, ((Interpolator)li)->shape); li->data = DXCreateArrayHandle(li->dataArray); if (! li->data) return ERROR; /* * Get the grid. */ li->pointsArray = (Array)DXGetComponentValue(field, "positions"); if (!li->pointsArray) { DXSetError(ERROR_MISSING_DATA, "#10240", "positions"); return ERROR; } DXReference((Object)li->pointsArray); /* * get info about data values */ DXGetArrayInfo(li->dataArray, NULL, &dataType, &dataCategory, NULL, NULL); /* * Don't worry about maintaining shape of input; just determine how * many values to interpolate. */ li->nElements = DXGetItemSize(li->dataArray) / DXTypeSize(((Interpolator)li)->type); /* * The grid should be regular */ DXQueryGridPositions(li->pointsArray, &nDim, &li->count, &origin, &delta); li->invDelta = 1.0 / delta; li->origin = origin; /* * Figure fuzz as a proportion of primitive lenth */ li->fieldInterpolator.fuzz *= delta; li->fieldInterpolator.initialized = 1; return OK; } Error _dxfLinesRR1DInterpolator_Delete(LinesRR1DInterpolator li) { _dxfCleanup(li); _dxfFieldInterpolator_Delete((FieldInterpolator) li); } int _dxfLinesRR1DInterpolator_PrimitiveInterpolate(LinesRR1DInterpolator li, int *n, float **points, Pointer *values, int fuzzFlag) { float x; int ix; float dx; float xMax, xMin; int ixMax; float org; float iD; float w0, w1; int i, knt; float *p; Pointer v; float fuzz; int dep; int itemSize, typeSize; InvalidComponentHandle icH = ((FieldInterpolator)li)->invCon; ubyte *dbuf; Matrix *xform; if (! li->fieldInterpolator.initialized) { if (! _dxfInitialize(li)) { _dxfCleanup(li); return 0; } li->fieldInterpolator.initialized = 1; } dep = li->fieldInterpolator.data_dependency; typeSize = DXTypeSize(((Interpolator)li)->type); itemSize = li->nElements * typeSize; /* * De-reference indexing info from interpolator */ org = li->origin; iD = li->invDelta; /* * De-reference bounding box */ xMax = ((Interpolator)li)->max[0]; xMin = ((Interpolator)li)->min[0]; ixMax = li->count - 1; fuzz = li->fuzz; if (((FieldInterpolator)li)->xflag) xform = &(((FieldInterpolator)li)->xform); else xform = NULL; p = *points; v = *values; dbuf = (ubyte *)DXAllocate(2*itemSize); if (! dbuf) return 0; while (*n > 0) { float xpt; if (xform) xpt = (*p)*xform->A[0][0] + xform->b[0]; else xpt = *p; if (fuzzFlag == FUZZ_ON) { if (xpt < xMin-fuzz || xpt > xMax+fuzz) break; } else { if (xpt < xMin || xpt > xMax) break; } x = (xpt - org) * iD; #define INTERPOLATE(type, round) \ { \ type *v0, *v1, *r; \ \ r = (type *)v; \ \ v0 = (type *)DXGetArrayEntry(li->data, ix, (Pointer)dbuf); \ v1 = (type *)DXGetArrayEntry(li->data, \ ix+1, (Pointer)(dbuf+itemSize)); \ \ for (i = 0; i < li->nElements; i++) \ *r++ = w1*(*v1++) + w0*(*v0++) + round; \ \ v = (Pointer)r; \ } if (((FieldInterpolator)li)->cstData) { memcpy(v, ((FieldInterpolator)li)->cstData, itemSize); v = (Pointer)(((char *)v) + itemSize); } else if (dep == DATA_POSITIONS_DEPENDENT) { Type dataType; ix = x; dx = x - ix; if (ix >= ixMax) { ix = ixMax - 1; dx = 1.0; } else if (ix < 0 || dx < 0.0) { ix = 0; dx = 0.0; } w0 = 1.0 - dx; w1 = dx; if (icH && DXIsElementInvalid(icH, ix)) break; if ((dataType = ((Interpolator)li)->type) == TYPE_FLOAT) { INTERPOLATE(float, 0.0); } else if (dataType == TYPE_DOUBLE) { INTERPOLATE(double, 0.0); } else if (dataType == TYPE_INT) { INTERPOLATE(int, 0.5); } else if (dataType == TYPE_SHORT) { INTERPOLATE(short, 0.5); } else if (dataType == TYPE_USHORT) { INTERPOLATE(ushort, 0.5); } else if (dataType == TYPE_UINT) { INTERPOLATE(uint, 0.5); } else if (dataType == TYPE_BYTE) { INTERPOLATE(byte, 0.5); } else if (dataType == TYPE_UBYTE) { INTERPOLATE(ubyte, 0.5); } else { INTERPOLATE(unsigned char, 0.5); } } else { ix = x; if (ix >= ixMax) ix = ixMax - 1; else if (ix < 0) ix = 0; if (icH && DXIsElementInvalid(icH, ix)) break; memcpy(v, DXGetArrayEntry(li->data, ix, (Pointer)dbuf), itemSize); v = ((char *)v) + itemSize; } /* * only use fuzz on first point */ fuzzFlag = FUZZ_OFF; p += 1; (*n)--; } DXFree((Pointer)dbuf); *points = (float *)p; *values = v; return OK; } static void _dxfCleanup(LinesRR1DInterpolator li) { if (li->data) { DXFreeArrayHandle(li->data); li->data = NULL; } if (li->pointsArray) { DXDelete((Object)li->pointsArray); li->pointsArray = NULL; } if (li->dataArray) { DXDelete((Object)li->dataArray); li->dataArray = NULL; } } Object _dxfLinesRR1DInterpolator_Copy(LinesRR1DInterpolator old, enum copy copy) { LinesRR1DInterpolator new; new = (LinesRR1DInterpolator) _dxf_NewObject((struct object_class *)&_dxdlinesrr1dinterpolator_class); if (!(_dxf_CopyLinesRR1DInterpolator(new, old, copy))) { DXDelete((Object)new); return NULL; } else return (Object)new; } LinesRR1DInterpolator _dxf_CopyLinesRR1DInterpolator(LinesRR1DInterpolator new, LinesRR1DInterpolator old, enum copy copy) { if (! _dxf_CopyFieldInterpolator((FieldInterpolator)new, (FieldInterpolator)old, copy)) return NULL; new->origin = old->origin; new->invDelta = old->invDelta; new->nElements = old->nElements; new->count = old->count; new->fuzz = old->fuzz; if (old->fieldInterpolator.initialized) { new->pointsArray = (Array)DXReference((Object)old->pointsArray); new->dataArray = (Array)DXReference((Object)old->dataArray); new->data = DXCreateArrayHandle(new->dataArray); } if (DXGetError()) return NULL; else return new; } static Error _dxfInitializeTask(Pointer p) { return _dxfInitialize(*(LinesRR1DInterpolator *)p); } Interpolator _dxfLinesRR1DInterpolator_LocalizeInterpolator(LinesRR1DInterpolator li) { if (li->fieldInterpolator.localized) return (Interpolator)li; li->fieldInterpolator.localized = 1; return (Interpolator)li; }