/***********************************************************************/ /* 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 /* * Header: /usr/people/gresh/code/svs/src/dxmods/RCS/_grow.c,v 5.0 92/11/12 09:12:57 svs Exp Locker: gresh * * */ #include #include #include #include static int IsRegular(Object); static Object GrowObject(Object, int, Pointer, Array); extern Object _dxfRegGrow(Object, int, Pointer, Array); extern Object _dxfIrregGrow(Object, int, Array); extern Object _dxfRegInvalidateDupBoundary(Object); extern Object _dxfIrregInvalidateDupBoundary(Object); extern Object _dxfRegShrink(Object); extern Object _dxfIrregShrink(Object); Array _dxfReRef(Array, int); #define IS_REGULAR 0 #define IS_NOT_REGULAR 1 #define IS_REGULAR_ERROR 2 Object DXGrowV(Object object, int rings, Pointer fill, char **componentNames) { int i; Array components = NULL; if (rings < 1) return object; if (componentNames && componentNames[0] != NULL) { for (i = 0; componentNames[i]; i++); components = DXMakeStringListV(i, componentNames); if (! components) return NULL; } else componentNames = NULL; if (! GrowObject(object, rings, fill, components)) goto error; if (components) DXFree((Object)components); return object; error: if (components) DXFree((Object)components); return NULL; } Object DXGrow(Object object, int rings, Pointer fill, ...) { char *components[100]; int i; va_list arg; va_start(arg,fill); for (i = 0; i < 100; i++) if (NULL == (components[i] = va_arg(arg, char *))) break; va_end(arg); return DXGrowV(object, rings, fill, components); } static Object GrowObject(Object object, int rings, Pointer fill, Array components) { switch(DXGetObjectClass(object)) { case CLASS_FIELD: { break; } case CLASS_GROUP: { if (DXGetGroupClass((Group)object) == CLASS_COMPOSITEFIELD) { int regularity = IsRegular(object); if (regularity == IS_REGULAR) { if (!_dxfRegGrow(object, rings, fill, components)) goto error; } else if (regularity == IS_NOT_REGULAR) { if (! _dxfIrregGrow(object, rings, components)) goto error; } } else { Object c; Group g = (Group)object; int i; for (i=0; NULL != (c = DXGetEnumeratedMember(g, i, NULL)); i++) if (! GrowObject(c, rings, fill, components)) return NULL; } break; } case CLASS_XFORM: { Object x; if (! DXGetXformInfo((Xform)object, &x, NULL)) goto error; if (! GrowObject(x, rings, fill, components)) goto error; } case CLASS_CLIPPED: { Object x; if (! DXGetClippedInfo((Clipped)object, &x, NULL)) goto error; if (! GrowObject(x, rings, fill, components)) goto error; } default: return NULL; } return object; error: return NULL; } Object DXShrink(Object object) { switch(DXGetObjectClass(object)) { case CLASS_FIELD: { break; } case CLASS_GROUP: { if (DXGetGroupClass((Group)object) == CLASS_COMPOSITEFIELD) { int regularity = IsRegular(object); if (regularity == IS_REGULAR) { if (!_dxfRegShrink(object)) goto error; } else if (regularity == IS_NOT_REGULAR) { if (! _dxfIrregShrink(object)) goto error; } } else { Object c; Group g = (Group)object; int i; for (i=0; NULL != (c = DXGetEnumeratedMember(g, i, NULL)); i++) if (! DXShrink(c)) return NULL; } break; } case CLASS_XFORM: { Object x; if (! DXGetXformInfo((Xform)object, &x, NULL)) goto error; if (! DXShrink(x)) goto error; } case CLASS_CLIPPED: { Object x; if (! DXGetClippedInfo((Clipped)object, &x, NULL)) goto error; if (! DXShrink(x)) goto error; } default: return NULL; } return object; error: return NULL; } Object DXInvalidateDupBoundary(Object object) { switch(DXGetObjectClass(object)) { case CLASS_FIELD: { Object a = DXGetComponentValue((Field)object, "invalid positions"); if (a) if (! DXSetComponentValue((Field)object, "saved invalid positions", a)) goto error; break; } case CLASS_GROUP: { if (DXGetGroupClass((Group)object) == CLASS_COMPOSITEFIELD) { int regularity = IsRegular(object); if (regularity == IS_REGULAR) { if (!_dxfRegInvalidateDupBoundary(object)) goto error; } else if (regularity == IS_NOT_REGULAR) { if (! _dxfIrregInvalidateDupBoundary(object)) goto error; } } else { Object c; Group g = (Group)object; int i; for (i=0; NULL != (c = DXGetEnumeratedMember(g, i, NULL)); i++) if (! DXInvalidateDupBoundary(c)) return NULL; } break; } case CLASS_XFORM: { Object x; if (! DXGetXformInfo((Xform)object, &x, NULL)) goto error; if (! DXInvalidateDupBoundary(x)) goto error; break; } case CLASS_CLIPPED: { Object x; if (! DXGetClippedInfo((Clipped)object, &x, NULL)) goto error; if (! DXInvalidateDupBoundary(x)) goto error; break; } default: return object; } return object; error: return NULL; } Object DXRestoreDupBoundary(Object object) { switch(DXGetObjectClass(object)) { case CLASS_FIELD: { Array a = (Array)DXGetComponentValue((Field)object, "saved invalid positions"); if (a) { if (DXGetComponentValue((Field)object, "invalid positions")) DXDeleteComponent((Field)object, "invalid positions"); if (! DXSetComponentValue((Field)object, "invalid positions", (Object)a)) goto error; DXDeleteComponent((Field)object, "saved invalid positions"); } else DXDeleteComponent((Field)object, "invalid positions"); break; } case CLASS_GROUP: { Object c; Group g = (Group)object; int i; for (i=0; NULL != (c = DXGetEnumeratedMember(g, i, NULL)); i++) if (! DXRestoreDupBoundary(c)) return NULL; break; } case CLASS_XFORM: { Object x; if (! DXGetXformInfo((Xform)object, &x, NULL)) goto error; if (! DXRestoreDupBoundary(x)) goto error; break; } case CLASS_CLIPPED: { Object x; if (! DXGetClippedInfo((Clipped)object, &x, NULL)) goto error; if (! DXRestoreDupBoundary(x)) goto error; break; } default: return object; } return object; error: return NULL; } static int IsRegular(Object in) { int i; Array array; Object child; int result; switch(DXGetObjectClass(in)) { case CLASS_GROUP: i = 0; while (NULL != (child = DXGetEnumeratedMember((Group)in, i++, NULL))) { result = IsRegular(child); if (result == IS_NOT_REGULAR) return result; } return result; case CLASS_FIELD: if (DXEmptyField((Field)in)) return IS_REGULAR_ERROR; array = (Array)DXGetComponentValue((Field)in, "connections"); if (! array) return IS_REGULAR_ERROR; if (DXQueryGridConnections(array, NULL, NULL)) return IS_REGULAR; else return IS_NOT_REGULAR; default: DXSetError(ERROR_INVALID_DATA, "IsRegular: data not group or field"); return IS_REGULAR_ERROR; } } static char ** makeGlobalStrings(char **locPtrs) { int i, j, k; char **l, **g, **gblPtrs; if (! locPtrs) return NULL; if (! *locPtrs) return NULL; for (i = 0, l = locPtrs; *l; l++, i++); gblPtrs = (char **)DXAllocate((i+1) * sizeof(char *)); for (j = 0, l = locPtrs, g = gblPtrs; j <= i; j++, l++, g++) { if (! *l) *g = NULL; else { k = strlen(*l) + 1; *g = DXAllocate(k * sizeof(char)); if (! *g) { while (--j >= 0) DXFree((Pointer)gblPtrs[j]); DXFree((Pointer)gblPtrs); return NULL; } strcpy(*g, *l); } } return gblPtrs; } static void freeGlobalStrings(char **gblPtrs) { char **g; if (gblPtrs) { for (g = gblPtrs; *g; g++) DXFree((Pointer)*g); DXFree((Pointer)gblPtrs); } } Field DXQueryOriginalSizes(Field partition, int *positions, int *connections) { Array cArray, pArray; pArray = (Array)DXGetComponentValue(partition, "original positions"); cArray = (Array)DXGetComponentValue(partition, "original connections"); if (! pArray || ! cArray) return NULL; if (positions) DXGetArrayInfo(pArray, positions, NULL, NULL, NULL, NULL); if (connections) DXGetArrayInfo(cArray, connections, NULL, NULL, NULL, NULL); return partition; } Array _dxfReRef(Array array, int n) { Type type; Category cat; int rank, shape[32]; int nItems, nReferences; int *ptr, i; DXGetArrayInfo(array, &nItems, &type, &cat, &rank, shape); if (type != TYPE_INT || cat != CATEGORY_REAL) { DXSetError(ERROR_INVALID_DATA, "referencing array must be INT/REAL"); return NULL; } nReferences = nItems; for (i = 0; i < rank; i++) nReferences *= shape[i]; ptr = (int *)DXGetArrayData(array); for (i = 0; i < nReferences; i++, ptr++) if (*ptr >= n) *ptr = -1; return array; } #define TYPE int #define LT(a,b) ((*(a))<(*(b))) #define GT(a,b) ((*(a))>(*(b))) #define QUICKSORT refsort #include "qsort.c" #define SetOrigName(buf, name) sprintf((buf), "original %s", (name)) Error _dxf_RemoveDupReferences(Field field) { Array iA, oA = NULL; Object attr; int i, n, nIn, nOut, r, s[64], nref, dup; char *name, origName[256]; int *sPtr, *dPtr, *p0, *p1; Type t; Category c; n = 0; while (NULL != (iA=(Array)DXGetEnumeratedComponentValue(field, n++, &name))) { SetOrigName(origName, name); if (! DXGetComponentValue(field, origName)) continue; if (DXGetComponentAttribute(field, name, "dep")) continue; if (NULL == (attr = DXGetComponentAttribute(field, name, "ref"))) continue; if (! strcmp(name, "connections")) continue; /* * Remember: only single references are allowed */ DXGetArrayInfo(iA, &nIn, &t, &c, &r, s); if (nIn == 0) continue; if (t != TYPE_INT || c != CATEGORY_REAL) { DXSetError(ERROR_INVALID_DATA, "invalid referential component: %s", name); goto error; } nref = DXGetItemSize(iA) / sizeof(int); if (nref != 1) continue; sPtr = (int *)DXGetArrayData(iA); refsort(sPtr, nIn); p0 = sPtr; p1 = sPtr+1; nOut = 1; for (i = 1; i < nIn; i++, p1++) if (*p0 != *p1) { p0 = p1; nOut++; } if (nIn != nOut) { oA = DXNewArrayV(t, c, r, s); if (! oA) goto error; if (! DXAddArrayData(oA, 0, nOut, NULL)) goto error; dPtr = (int *)DXGetArrayData(oA); *dPtr = *sPtr++; for (i = 1; i < nIn; i++, sPtr++) if (*dPtr != *sPtr) { dPtr++; *dPtr = *sPtr; } if (! DXSetComponentValue(field, name, (Object)oA)) goto error; oA = NULL; } } return OK; error: DXDelete((Object)oA); return ERROR; }