/***********************************************************************/ /* 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 #include "interpClass.h" typedef long CRC; Interpolator _dxfNewGroupInterpolator(Group, enum interp_init, float, Matrix *); Interpolator _dxfSelectFieldInterpolator(Field, enum interp_init, float, Matrix *); static Error _dxfValidInterpolatorMap(Object); static struct PrimTypes { char *name; int dimensionality; int ptsPerPrimitive; } _dxdprimTypes[] = { { "lines", 1, 2 }, { "triangles", 2, 3 }, { "quads", 2, 4 }, { "cubes", 3, 8 }, { "tetrahedra", 3, 4 }, { NULL, 0, 0 } }; Interpolator DXNewInterpolator(Object o, enum interp_init initType, float fuzz) { Interpolator interp = NULL; Object copy = NULL; if (fuzz < 0.0) fuzz = FUZZ; if (! _dxfValidInterpolatorMap(o)) goto error; copy = DXCopy(o, COPY_HEADER); if (! copy) goto error; if (initType == INTERP_INIT_PARALLEL) DXCreateTaskGroup(); interp = _dxfNewInterpolatorSwitch(copy, initType, fuzz, NULL); if (! interp) { if (initType == INTERP_INIT_PARALLEL) DXAbortTaskGroup(); goto error; } if (initType == INTERP_INIT_PARALLEL) if (! DXExecuteTaskGroup() || DXGetError() != ERROR_NONE) goto error; interp->fuzz = fuzz; interp->rootObject = DXReference(copy); return interp; error: DXDelete((Object)interp); DXDelete((Object)copy); return NULL; } Interpolator _dxfNewInterpolatorSwitch(Object o, enum interp_init initType, float fuzz, Matrix *stack) { Interpolator interp = NULL; Class class; Object child; Matrix mat, prod; class = DXGetObjectClass(o); /* if (class == CLASS_GROUP) class = DXGetGroupClass((Group)o); */ /* * Determine class of input and call appropriate Interpolator * sub-class method */ switch (class) { case CLASS_XFORM: if (stack) { if (! DXGetXformInfo((Xform)o, &child, &mat)) goto error; prod = DXConcatenate(mat, *stack); } else if (! DXGetXformInfo((Xform)o, &child, &prod)) goto error; interp = _dxfNewInterpolatorSwitch(child, initType, fuzz, &prod); if (! interp) goto error; break; case CLASS_GROUP: interp = (Interpolator)_dxfNewGroupInterpolator((Group)o, initType, fuzz, stack); if (! interp) goto error; break; case CLASS_FIELD: interp = (Interpolator)_dxfSelectFieldInterpolator((Field)o, initType, fuzz, stack); if (! interp) goto error; break; default: DXSetError(ERROR_BAD_CLASS, "#11381", "map"); interp = NULL; } return interp; error: DXDelete((Object)interp); return NULL; } Interpolator _dxf_NewInterpolator(struct interpolator_class *class, Object o) { Interpolator i; i = (Interpolator)_dxf_NewObject((struct object_class *)class); if (! i) return NULL; i->dataObject = o; i->rootObject = NULL; memset(&i->matrix, 0, sizeof(Matrix)); return i; } int _dxfInterpolator_Delete(Interpolator interp) { if (interp->rootObject) DXDelete(interp->rootObject); return OK; } Interpolator DXInterpolate(Interpolator interp, int *n, float *p, Pointer v) { int nInterpolated, nAtStart; /* * Try to interpolate a list of points. First, try interpolation * without fuzz; if points remain, we'll have to try interpolation * with fuzz. */ if (! _dxfInterpolate(interp, n, &p, &v, NULL, FUZZ_OFF)) return NULL; /* * If points remain, loop. When the fuzz flag is turned on, the * first point will be interpolated with fuzz. If this succeeds, * subsequent interpolations will proceed without fuzz until a point * cannot be interpolated. At this point, control passes back up here * and we start again with fuzz. This loop terminates when no point is * interpolated with or without fuzz or when all points have been * interpolated. */ if (interp->fuzz > 0.0 && *n) do { nAtStart = *n; if (! _dxfInterpolate(interp, n, &p, &v, NULL, FUZZ_ON)) return NULL; nInterpolated = nAtStart - *n; } while (nInterpolated && *n); return interp; } Object _dxfInterpolator_GetType(Interpolator interp, Type *type, Category *category, int *rank, int *shape) { if (interp->rootObject == NULL) return NULL; else return DXGetType(interp->rootObject, type, category, rank, shape); } Interpolator _dxf_CopyInterpolator(Interpolator new, Interpolator src) { int i; if (src->rootObject) new->rootObject = DXReference(src->rootObject); else new->rootObject = NULL; new->dataObject = src->dataObject; new->fuzz = src->fuzz; new->nDim = src->nDim; for (i = 0; i < src->nDim; i++) { new->max[i] = src->max[i]; new->min[i] = src->min[i]; } new->type = src->type; new->category = src->category; new->rank = src->rank; new->matrix = src->matrix; for (i = 0; i < src->rank; i++) new->shape[i] = src->shape[i]; return new; } static Error _dxfValidInterpolatorMap(Object map) { char *name; Class class; name = NULL; class = DXGetObjectClass(map); if (class == CLASS_GROUP) class = DXGetGroupClass((Group)map); if (class == CLASS_COMPOSITEFIELD || class == CLASS_MULTIGRID) { Object child; int i; i = 0; while (NULL != (child = DXGetEnumeratedMember((Group)map, i++, NULL))) if (! _dxfValidInterpolatorMap(child)) return ERROR; return OK; } else if (class == CLASS_XFORM) { Object c; if (! DXGetXformInfo((Xform)map, &c, NULL)) return ERROR; return _dxfValidInterpolatorMap(c); } else if (class == CLASS_FIELD) { struct PrimTypes *prim; Array array; int rank, shape[32]; int nPrims; Object at; /* * Allow empty fields and fields with no connections */ if (DXEmptyField((Field)map)) return OK; array = (Array)DXGetComponentValue((Field)map, "connections"); if (! array) return OK; DXGetArrayInfo(array, &nPrims, NULL, NULL, NULL, NULL); if (nPrims < 0) return OK; at = DXGetComponentAttribute((Field)map, "connections", "element type"); if (! at || DXGetObjectClass(at) != CLASS_STRING) { DXSetError(ERROR_MISSING_DATA, "#10255", "connections", "element type"); return ERROR; } name = DXGetString((String)at); for (prim = _dxdprimTypes; prim->name != NULL; prim ++) if (! strcmp(prim->name, name)) break; if (prim->name == NULL) { DXSetError(ERROR_INVALID_DATA, "#11380", "name"); return ERROR; } array = (Array)DXGetComponentValue((Field)map, "positions"); if (! array) { DXSetError(ERROR_MISSING_DATA, "#10240", "map", "positions"); return ERROR; } DXGetArrayInfo(array, NULL, NULL, NULL, NULL, shape); if (shape[0] != prim->dimensionality) { DXSetError(ERROR_INVALID_DATA, "#11003", prim->name, prim->dimensionality); return ERROR; } array = (Array)DXGetComponentValue((Field)map, "connections"); DXGetArrayInfo(array, NULL, NULL, NULL, &rank, shape); if (rank != 1 || shape[0] != prim->ptsPerPrimitive) { DXSetError(ERROR_INVALID_DATA, "#11004", prim->name, prim->ptsPerPrimitive); return ERROR; } return OK; } else { DXSetError(ERROR_INVALID_DATA, "#11381"); return ERROR; } } Interpolator DXLocalizeInterpolator(Interpolator o) { return _dxfLocalizeInterpolator(o); }