/***********************************************************************/ /* 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 "dx/dx.h" #include "fieldinterpClass.h" typedef int (*PFI)(); typedef FieldInterpolator (*PFFI)(); int _dxfRecognizeTetras(Field); PFFI _dxfNewTetrasInterpolator(Field, enum interp_init, double, Matrix *); int _dxfRecognizeLinesII1D(Field); PFFI _dxfNewLinesII1DInterpolator(Field, enum interp_init, double, Matrix *); int _dxfRecognizeLinesRR1D(Field); PFFI _dxfNewLinesRR1DInterpolator(Field, enum interp_init, double, Matrix *); int _dxfRecognizeTrisRI2D(Field); PFFI _dxfNewTrisRI2DInterpolator(Field, enum interp_init, double, Matrix *); int _dxfRecognizeQuadsRR2D(Field); PFFI _dxfNewQuadsRR2DInterpolator(Field, enum interp_init, double, Matrix *); int _dxfRecognizeQuadsII2D(Field); PFFI _dxfNewQuadsII2DInterpolator(Field, enum interp_init, double, Matrix *); int _dxfRecognizeCubesII(Field); PFFI _dxfNewCubesIIInterpolator(Field, enum interp_init, double, Matrix *); int _dxfRecognizeLinesRI1D(Field); PFFI _dxfNewLinesRI1DInterpolator(Field, enum interp_init, double, Matrix *); int _dxfRecognizeCubesRR(Field); PFFI _dxfNewCubesRRInterpolator(Field, enum interp_init, double, Matrix *); int _dxfRecognizeFLE2D(Field); PFFI _dxfNewFle2DInterpolator(Field, enum interp_init, double, Matrix *); static struct subClass { PFI recognizeMth; PFFI newMth; } _dxdsubClasses[] = { { _dxfRecognizeTetras, (PFFI)_dxfNewTetrasInterpolator }, { _dxfRecognizeLinesRR1D, (PFFI)_dxfNewLinesRR1DInterpolator }, { _dxfRecognizeLinesRI1D, (PFFI)_dxfNewLinesRI1DInterpolator }, { _dxfRecognizeLinesII1D, (PFFI)_dxfNewLinesII1DInterpolator }, { _dxfRecognizeTrisRI2D, (PFFI)_dxfNewTrisRI2DInterpolator }, { _dxfRecognizeQuadsRR2D, (PFFI)_dxfNewQuadsRR2DInterpolator }, { _dxfRecognizeQuadsII2D, (PFFI)_dxfNewQuadsII2DInterpolator }, { _dxfRecognizeCubesRR, (PFFI)_dxfNewCubesRRInterpolator }, { _dxfRecognizeCubesII, (PFFI)_dxfNewCubesIIInterpolator }, { _dxfRecognizeFLE2D, (PFFI)_dxfNewFle2DInterpolator }, { NULL, NULL } }; FieldInterpolator _dxfSelectFieldInterpolator(Field f, enum interp_init initType, float fuzz, Matrix *m) { FieldInterpolator fi; struct subClass *sub; Array array; int nElements; /* * If the field is empty of positions and/or connections, * return an empty interpolator */ if (DXEmptyField(f)) goto emptyInterpolator; for (sub = _dxdsubClasses; sub->recognizeMth != NULL; sub++) { if (sub->recognizeMth(f)) break; if (DXGetError() != ERROR_NONE) break; } if (!sub->recognizeMth || DXGetError() != ERROR_NONE) { if (DXGetError() == ERROR_NONE) DXSetError(ERROR_INVALID_DATA, "#11850"); return NULL; } fi = (*(sub->newMth))(f, initType, (double)fuzz, m); if (!fi) return NULL; return fi; emptyInterpolator: fi = _dxf_NewFieldInterpolator(f, fuzz, m, &_dxdfieldinterpolator_class); return fi; } FieldInterpolator _dxf_NewFieldInterpolator(Field f, float fuzz, Matrix *m, struct fieldinterpolator_class *class) { FieldInterpolator fi; Array boxArray, icArray, dArray; float *boxPts, *boxPt; int i, nDim, nItems; Object attr; char *str; fi = (FieldInterpolator)_dxf_NewInterpolator ((struct interpolator_class *)class, (Object)f); if (! fi) return NULL; fi->initialized = 0; fi->localized = 0; fi->fuzz = fuzz; if (m) { fi->xform = DXInvert(*m); fi->xflag = 1; } else fi->xflag = 0; for (i = 0; i < MAX_DIM; i++) { fi->interpolator.min[i] = DXD_MAX_FLOAT; fi->interpolator.max[i] = -DXD_MAX_FLOAT; } if (DXBoundingBox((Object) f, NULL)) { boxArray = (Array)DXGetComponentValue(f, "box"); boxPts = (float *)DXGetArrayData(boxArray); DXGetArrayInfo(boxArray, &nItems, NULL, NULL, NULL, &nDim); fi->interpolator.nDim = nDim; boxPt = boxPts; while (nItems-- > 0) { for (i = 0; i < nDim; i++) { if (*boxPt > fi->interpolator.max[i]) fi->interpolator.max[i] = *boxPt; if (*boxPt < fi->interpolator.min[i]) fi->interpolator.min[i] = *boxPt; boxPt ++; } } } else if (DXGetError() != ERROR_NONE) { DXFree((Pointer)fi); return NULL; } else fi->interpolator.nDim = 0; if (NULL == (dArray = (Array)DXGetComponentValue(f, "data"))) { DXSetError(ERROR_MISSING_DATA, "#10250", "map", "data"); return NULL; } if (DXQueryConstantArray(dArray, NULL, NULL)) fi->cstData = DXGetConstantArrayData(dArray); else fi->cstData = NULL; /* * Check dependency of connections array */ if ((attr = DXGetComponentAttribute(f, "data", "dep")) == NULL) { DXSetError(ERROR_MISSING_DATA, "#10241", "map"); return NULL; } if (DXGetObjectClass(attr) != CLASS_STRING) { DXSetError(ERROR_MISSING_DATA, "#11080", "dependency attribute"); return NULL; } str = DXGetString((String)attr); if (! strcmp(str, "positions")) fi->data_dependency = DATA_POSITIONS_DEPENDENT; else if (! strcmp(str, "connections")) fi->data_dependency = DATA_CONNECTIONS_DEPENDENT; else if (! strcmp(str, "faces")) fi->data_dependency = DATA_FACES_DEPENDENT; else { DXSetError(ERROR_INVALID_DATA, "#10250", "data"); DXFree((Pointer)fi); return NULL; } if (! DXInvalidateConnections((Object)f)) { DXFree((Pointer)fi); return NULL; } if (DXGetComponentValue(f, "connections")) { fi->invCon = DXCreateInvalidComponentHandle((Object)f, NULL, "connections"); if (! fi->invCon) { DXFree((Pointer)fi); return NULL; } if (DXGetInvalidCount(fi->invCon) == 0) { DXFreeInvalidComponentHandle(fi->invCon); fi->invCon = NULL; } } return fi; } _dxfFieldInterpolator_Delete(FieldInterpolator fi) { if (fi->invCon) DXFreeInvalidComponentHandle(fi->invCon); _dxfInterpolator_Delete((Interpolator) fi); } int _dxfFieldInterpolator_Interpolate(FieldInterpolator fi, int *n, float **points, Pointer *values, Interpolator *hint, int fuzzFlag) { int i, j; int nStart; float *p, xpoints[MAX_DIM]; CHECK(fi, CLASS_INTERPOLATOR); if (hint) *hint = NULL; if (fi->xflag) { p = xpoints; for (i = 0; i < fi->interpolator.nDim; i++) { p[i] = fi->xform.b[i]; for (j = 0; j < fi->interpolator.nDim; j++) p[i] += (*points)[j]*fi->xform.A[j][i]; } } else p = *points; if (fuzzFlag == FUZZ_ON) for (i = 0; i < fi->interpolator.nDim; i++) { if (fi->interpolator.min[i]-fi->fuzz > p[i]) return OK; if (fi->interpolator.max[i]+fi->fuzz < p[i]) return OK; } else for (i = 0; i < fi->interpolator.nDim; i++) { if (fi->interpolator.min[i] > p[i]) return OK; if (fi->interpolator.max[i] < p[i]) return OK; } /* * Set hint ONLY if we interpolated some points */ nStart = *n; if (! _dxfPrimitiveInterpolate(fi, n, points, values, fuzzFlag)) return 0; if (hint && nStart != *n) *hint = (Interpolator)fi; return OK; } FieldInterpolator _dxf_CopyFieldInterpolator(FieldInterpolator new, FieldInterpolator old, enum copy copy) { if (! _dxf_CopyInterpolator((Interpolator)new, (Interpolator)old)) return NULL; new->localized = old->localized; new->initialized = old->initialized; new->fuzz = old->fuzz; new->data_dependency = old->data_dependency; new->cstData = old->cstData; if (old->invCon) new->invCon = DXCreateInvalidComponentHandle ((new->interpolator.dataObject), NULL, "connections"); else new->invCon = NULL; return new; }