static Error ConvertObject(Object in, char *strin, Object *out) { Class cl; if (!(cl = DXGetObjectClass(in))) return ERROR; switch (cl) { case CLASS_GROUP: DXSetError(ERROR_DATA_INVALID,"colormaps must be a single field"); return ERROR; case CLASS_FIELD: if (!strcmp(strin,"hsv")) { if (!(*out = (Object)_dxfMakeRGBColorMap((Field)in))) return ERROR; } else { if (!(*out = (Object)_dxfMakeHSVfromRGB((Field)in))) return ERROR; } break; default: break; } return OK; }
/* unlike Inquire, say yes if you find any */ static int queryNDconnections(Field f, int n) { char *cp; Object con; if (!(con = DXGetComponentValue(f, "connections"))) { if (n == 0) return 1; return 0; } if (DXGetObjectClass(con) != CLASS_ARRAY) return 0; if (!DXGetStringAttribute(con, "element type", &cp)) return 0; if (!strcmp(cp, "lines") && (n == 1)) return 1; if ((!strcmp(cp, "triangles") || !strcmp(cp, "quads")) && (n == 2)) return 1; if ((!strcmp(cp, "tetrahedra") || !strcmp(cp, "cubes")) && (n == 3)) return 1; if (!strncmp(cp, "cubes", 5) && (strlen(cp) > 5) && (n > 3)) return 1; return 0; }
static Error ExtractMatrix(Object o, Matrix *m) { Pointer p; int i, items, shape[2]; Type type; float *fp; if (DXGetObjectClass(o) != CLASS_ARRAY) return ERROR; if (!DXTypeCheck((Array)o, TYPE_FLOAT, CATEGORY_REAL, 2, 3, 3) && !DXTypeCheck((Array)o, TYPE_FLOAT, CATEGORY_REAL, 2, 4, 3) && !DXTypeCheck((Array)o, TYPE_INT, CATEGORY_REAL, 2, 3, 3) && !DXTypeCheck((Array)o, TYPE_INT, CATEGORY_REAL, 2, 4, 3)) return ERROR; if (!DXGetArrayInfo((Array)o, &items, &type, NULL, NULL, shape)) return ERROR; if (items != 1) return ERROR; p = DXGetArrayData((Array)o); items = shape[0] * shape[1]; if (type == TYPE_FLOAT) memcpy((char *)m, (char *)p, items * sizeof(float)); else for (i=0, fp=(float *)m; i<items; i++, fp++) *fp = (float)((int *)p)[i]; return OK; }
/* return how many items in this field are valid */ static Error validcount(Field f, char *component, int *icount) { Array a = NULL; char *dep = NULL; char *invalid = NULL; InvalidComponentHandle ih; /* assume none and be happily surprised when it finds some */ *icount = 0; /* this must be called at the field level. if you want to recurse * through a hierarchy, do the recursion above this subroutine. */ if (DXGetObjectClass((Object)f) != CLASS_FIELD) { Return_Internal_Error; } a = (Array)DXGetComponentValue(f, component); if (!a) { DXSetError(ERROR_DATA_INVALID, "field has no `%s' component", component); return ERROR; } /* follow a dependency. */ if (!DXGetStringAttribute((Object)a, "dep", &dep)) { DXSetError(ERROR_DATA_INVALID, "The `%s' component does not have a `dep' attribute", component); return ERROR; } if (!DXGetArrayInfo(a, icount, NULL, NULL, NULL, NULL)) return ERROR; #define INVLEN 10 /* strlen("invalid "); */ if (!(invalid = (char *)DXAllocate(strlen(dep) + INVLEN))) return ERROR; strcpy(invalid, "invalid "); strcat(invalid, dep); /* if no invalid component, all valid */ if (!DXGetComponentValue(f, invalid)) { DXFree((Pointer)invalid); return OK; } DXFree((Pointer)invalid); ih = DXCreateInvalidComponentHandle((Object)f, NULL, dep); if (!ih) return ERROR; *icount = DXGetValidCount(ih); DXFreeInvalidComponentHandle(ih); return OK; }
static int qimage(Object o) { int n; Array a; char *s; /* an image has got to be a field or a composite field */ if (DXGetObjectClass(o) != CLASS_FIELD) { if (DXGetObjectClass(o) != CLASS_GROUP) return 0; if (DXGetGroupClass((Group)o) != CLASS_COMPOSITEFIELD) return 0; o = DXGetEnumeratedMember((Group)o, 0, NULL); } /* check to see if it's the right shape, etc */ /* check positions */ a = (Array) DXGetComponentValue((Field)o, "positions"); if (!a || !DXQueryGridPositions(a, &n, NULL, NULL, NULL) || n!=2) return 0; /* check connections */ a = (Array) DXGetComponentValue((Field)o, "connections"); if (!a || !DXQueryGridConnections(a, &n, NULL) || n!=2) return 0; /* is there a colors component */ a = (Array) DXGetComponentValue((Field)o, "colors"); if (!a) return 0; /* check dep */ s = DXGetString((String)DXGetAttribute((Object)a, "dep")); if (s && strcmp(s, "positions")) return 0; return 1; }
static uint32 computeRecipe(Program *p, int ind) { ProgramVariable *pv; Object obj; uint32 tcrc; gvar *gv; if (ind == -1) return(computeDefaultRecipe (NULL)); pv = FETCH_LIST(p->vars, ind); gv = pv->gv; /* gv will be null for prehidden inputs for outboards, anything else?*/ if(!gv) gv = _dxf_ExCreateGvar(GV_UNRESOLVED); /* if input already has a recipe, just use it, * Otherwise, it must be some kind of known variable */ if (gv->reccrc == 0) { obj = gv->obj; if (obj == NULL) obj = pv->dflt; if (obj == NULL) tcrc = computeDefaultRecipe (obj); else { switch (DXGetObjectClass (obj)) { case CLASS_ARRAY: tcrc = computeArrayRecipe ((Array) obj); break; case CLASS_STRING: tcrc = computeStringRecipe ((String) obj); break; default: tcrc = computeDefaultRecipe (obj); break; } } pv->reccrc = gv->reccrc = tcrc; DXSetObjectTag (obj, tcrc); } return(gv->reccrc); }
Error m_Options(Object *in, Object *out) { Object a, v; char *s; int i; /* check input object */ if (!in[0]) { DXSetError(ERROR_BAD_PARAMETER, "#10000", "input"); return ERROR; } /* create output copy */ out[0] = DXCopy(in[0], COPY_HEADER); if (!out[0]) return ERROR; /* arrays don't copy by default - you have to call something special * to get a new copy. */ if (out[0] == in[0] && DXGetObjectClass(in[0]) == CLASS_ARRAY) { out[0] = (Object)_dxfReallyCopyArray((Array)in[0]); if (!out[0]) return ERROR; } /* set attributes */ for (i=0; i<PAIRS; i++) { a = in[2*i+1]; v = in[2*i+2]; if (a) { if (!DXExtractString(a, &s)) { DXSetError(ERROR_BAD_PARAMETER, "#10200", "attribute name"); goto error; } /* NB - ok for v to be NULL - this deletes the attribute */ if (!DXSetAttribute(out[0], s, v)) goto error; } } return OK; error: if (out[0] != in[0]) DXDelete(out[0]); out[0] = NULL; return ERROR; }
static void Slide2DSetRenderable(void *data, Object obj) { Slide2DData sdata = (Slide2DData)data; if (sdata->obj) DXDelete(sdata->obj); /* * Scarf up the scene object group */ if (DXGetObjectClass(obj) != CLASS_GROUP) { DXWarning("Slide2D: Object must be a group of transfomrmed objects"); sdata->obj = NULL; } else sdata->obj = DXReference(obj); }
static void CaptionSetRenderable(void *data, Object obj) { CaptionData sdata = (CaptionData)data; if (sdata->obj) DXDelete(sdata->obj); /* * Receive the current state of the object */ if (DXGetObjectClass(obj) != CLASS_GROUP) { DXWarning("Caption: Object must be a group"); sdata->obj = NULL; } else sdata->obj = DXReference(obj); }
static Error atleast1image(Object o) { Object subo, old; int i; switch (DXGetObjectClass(o)) { case CLASS_FIELD: if (qimage(o)) return OK; break; case CLASS_GROUP: /* traverse members */ for (i=0; subo = DXGetEnumeratedMember((Group)o, i, NULL); i++) if (atleast1image(subo)) return OK; break; case CLASS_SCREEN: if (!DXGetScreenInfo((Screen)o, &subo, NULL, NULL)) return ERROR; return atleast1image(subo); case CLASS_XFORM: if (!DXGetXformInfo((Xform)o, &subo, NULL)) return ERROR; return atleast1image(subo); case CLASS_CLIPPED: if (!DXGetClippedInfo((Clipped)o, &subo, NULL)) return ERROR; return atleast1image(subo); default: break; } return ERROR; }
static Error atleast1contype(Object o, int n) { Object subo, old; int i; switch (DXGetObjectClass(o)) { case CLASS_FIELD: if (queryNDconnections((Field)o, n)) return OK; break; case CLASS_GROUP: /* traverse members */ for (i=0; subo = DXGetEnumeratedMember((Group)o, i, NULL); i++) if (atleast1contype(subo, n)) return OK; break; case CLASS_SCREEN: /* these don't act like other objs; don't count them for this */ break; case CLASS_XFORM: if (!DXGetXformInfo((Xform)o, &subo, NULL)) return ERROR; return atleast1contype(subo, n); case CLASS_CLIPPED: if (!DXGetClippedInfo((Clipped)o, &subo, NULL)) return ERROR; return atleast1contype(subo, n); default: break; } return ERROR; }
static void * Slide2DInitMode(Object args, int w, int h, int *mask) { Slide2DData sdata = (Slide2DData)DXAllocateZero(sizeof(struct slide2DData)); if (! sdata) return NULL; /* * Parse the argument. It better be a string or an integer. */ if (! args) { DXWarning("Slide2D: argument required (index 0 used)"); sdata->label = NULL; sdata->index = 0; } else if (DXGetObjectClass(args) == CLASS_STRING) { sdata->args = DXReference(args); sdata->label = DXGetString((String)args); } else if (DXGetObjectClass(args) == CLASS_ARRAY) { Type t; DXGetArrayInfo((Array)args, NULL, &t, NULL, NULL, NULL); if (t == TYPE_INT) { sdata->args = DXReference(args); sdata->index = *(int *)DXGetArrayData((Array)args); sdata->label = NULL; } else if (t == TYPE_UBYTE || t == TYPE_BYTE || t == TYPE_STRING) { sdata->args = DXReference(args); sdata->label = (char *)DXGetArrayData((Array)args); sdata->index = -1; } else { DXWarning("Slide2D: argument must be string or int (index 0 used)"); sdata->label = NULL; sdata->index = 0; } } /* * Save the window width and height for scaling purposes */ sdata->w = w; sdata->h = h; /* * Initially, the button is up */ sdata->strokeStart = 1; /* * Pay attention to only the left and middle buttons */ *mask = DXEVENT_LEFT | DXEVENT_MIDDLE; return (void *)sdata; }
Error m_Light(Object *in, Object *out) { Vector v; RGBColor c; int camera = 0; char *colorstr; /* if first parm isn't a vector, try to see if it's a camera object. * if so, use the same calculation as the renderer uses for the default * light - slightly to the left of the camera position. */ if (!in[0]) { v.x = v.y = 0.0; v.z = 1.0; } else if (!DXExtractParameter(in[0], TYPE_FLOAT, 3, 1, (Pointer)&v)) { if (DXGetObjectClass(in[0]) == CLASS_CAMERA) { Point from, to; Vector eye, up, left; DXGetView((Camera)in[0], &from, &to, &up); eye = DXNormalize(DXSub(from,to)); left = DXCross(eye, up); v = DXAdd(eye, left); } else { DXSetError(ERROR_BAD_PARAMETER, "#10670", "`where'"); return ERROR; } } /* color, default is white */ if (!in[1]) { c.r = c.b = c.g = 1.0; } else if (DXExtractString(in[1],&colorstr)) { if (!DXColorNameToRGB(colorstr, &c)) /* it sets a reasonable error string */ return ERROR; } else if (!DXExtractParameter(in[1], TYPE_FLOAT, 3, 1, (Pointer)&c)) { DXSetError(ERROR_BAD_PARAMETER, "#10510", "color"); return ERROR; } /* absolute or camera relative? */ if (in[2] && !DXExtractInteger(in[2], &camera)) { DXSetError(ERROR_BAD_PARAMETER, "#10070", "camera flag"); return ERROR; } if (!camera) out[0] = (Object)DXNewDistantLight(v, c); else out[0] = (Object)DXNewCameraDistantLight(v, c); return(out[0] ? OK : ERROR); }
Error m_SXConstruct( Object *in, Object*out){ /* *+ * Name: * SXConstruct * Purpose: * constructs a regular field with regular connections * Language: * ANSI C * Syntax: * output = SXConstruct( object, lower, upper, deltas, counts ); * Classification: * Realization * Description: * The SXConstruct module constructs a field with regular positions * and connections covering a volume with specified bounds. It is * similar to the standard Construct module, but is somewhat easier to * use if a simple grid is required. * If "object" is given, its bounds define the extent of the output * field. Otherwise, the vectors given for "upper" and "lower" define * the extent of the output field. * If "deltas" is supplied, it defines the distances between adjacent * positions on each axis. It should be a vector with the same number * of dimensions as "upper" and "lower", or a single value (in which * case the supplied value is used for all axes). The upper and lower * bounds are expanded if necessary until they span an integer number * of deltas. * * If "deltas" is not supplied, then "counts" must be supplied and * should be an integer vector giving the number of positions on each * axis, or a single integer (in which case the same value is used for * all axes). * Parameters: * object = field (given) * object to define extent of new field [none] * lower = vector (Given) * explicit lower bounds of new field [none] * upper = vector (Given) * explicit upper bounds of new field [none] * deltas = scalar or vector (Given) * increment for each axis * counts = integer or vector (Given) * number of positions along each axis * output = field (Returned) * output field * Components: * The output has "positions", "connections" and "box" components, but * no "data" component. * Examples: * This example imports a scattered data set from "C02.general", * extracts a single frame, uses SXConstruct to make a grid covering the * bounds of the frame, with increments of 10.0 along each axis, and * then uses SXBIN to find the mean data value in each of the square * connections of this new grid. the resulting field is displayed. * * data = Import("/usr/lpp/dx/samples/data/CO2.general"); * frame17 = Select(data,17); * newgrid = SXConstruct(frame17,deltas=10); * binned = SXBin(frame17,newgrid); * coloured = AutoColor(binned); * camera = AutoCamera(coloured); * Display(coloured,camera); * See Also: * Construct, Grid * Returned Value: * OK, unless an error occurs in which case ERROR is returned and the * DX error code is set. * Copyright: * Copyright (C) 1995 Central Laboratory of the Research Councils. * All Rights Reserved. * Licence: * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be * useful,but WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street,Fifth Floor, Boston, MA * 02110-1301, USA * Authors: * DSB: David Berry (STARLINK) * {enter_new_authors_here} * History: * 18-OCT-1995 (DSB): * Original version * {enter_further_changes_here} * Bugs: * {note_any_bugs_here} *- */ /* Local Variables. */ int cnt[3]; /* Counts */ int *counts; /* Pointers to counts */ float del[3]; /* Deltas */ float del3d[9]; /* 3-D Deltas */ float *deltas; /* Pointers to deltas */ float *lower; /* Pointer to lower bounds */ float *upper; /* Pointer to upper bounds */ float lbnd[3]; /* lower bounds */ float ubnd[3]; /* upper bounds */ int ndim; /* No. of components for each vector */ int ndim2; /* No. of dimensions in second object */ Object o=NULL; /* Output object */ float bnd; /* Current bound value */ Point box[8]; /* Bounding box */ Category cat; /* Array category */ Array array; /* An array */ float *box_ptr; /* Pointer to box array */ int i; /* Loop count */ int j; /* Loop count */ int ncorn; /* No. of corners in the bounding box */ int rank; /* Array rank */ float tmp; /* Swapping space */ Type type; /* Array numeric type */ /* If OBJECT was supplied, check it is a field. */ if( in[0] ){ if( DXGetObjectClass(in[0]) != CLASS_FIELD ){ DXSetError( ERROR_BAD_TYPE, "input object is not a field" ); goto error; } /* Take a copy of it. */ o = DXCopy( in[0], COPY_STRUCTURE ); /* Get the bounding box component from the object */ array = (Array) DXGetComponentValue( (Field) o, "box" ); /* If no bounding box was found, create one. */ if( !array ){ if( !DXBoundingBox( o, box ) ){ DXSetError( ERROR_UNEXPECTED, "cannot obtain a bounding box." ); goto error; } array = (Array) DXGetComponentValue( (Field) o, "box" ); } /* Get a pointer to the bounding box array and the number of items in * the array, etc. */ box_ptr = (float *) DXGetArrayData( array ); DXGetArrayInfo( array, &ncorn, &type, &cat, &rank, &ndim ); if( type != TYPE_FLOAT ){ DXSetError( ERROR_BAD_TYPE, "input object positions are not TYPE_FLOAT"); goto error; } if( cat != CATEGORY_REAL ){ DXSetError( ERROR_BAD_TYPE, "input object positions are not REAL"); goto error; } if( rank > 1 ){ DXSetError( ERROR_BAD_TYPE, "input object positions have rank larger than 1"); goto error; } if( rank == 0 ) ndim = 1; if( ndim > 3 ){ DXSetError( ERROR_BAD_TYPE, "input object positions have more than 3 dimensions"); goto error; } /* Store the bounds for each dimension. */ for( j=0; j<ndim; j++){ lbnd[j] = FLT_MAX; ubnd[j] = FLT_MIN; } for( i=0; i<ncorn; i++ ){ for( j=0; j<ndim; j++ ){ bnd = *(box_ptr++); if( bnd < lbnd[j] ) lbnd[j]=bnd; if( bnd > ubnd[j] ) ubnd[j]=bnd; } } /* Delete the copy of the input object */ DXDelete( o ); o = NULL; array = NULL; /* If OBJECT was not supplied, get the bounds from LOWER and UPPER. */ } else { if( !in[1] ) { DXSetError( ERROR_MISSING_DATA, "No lower bounds supplied"); goto error; } else { lower = SXGet1r( "lower", in[1], &ndim ); if( !lower ) goto error; if( ndim > 3 ){ DXSetError( ERROR_BAD_TYPE, "lower bounds have more than 3 dimensions"); goto error; } } if( !in[2] ) { DXSetError( ERROR_MISSING_DATA, "No upper bounds supplied"); goto error; } else { upper = SXGet1r( "upper", in[2], &ndim2 ); if( !upper ) goto error; if( ndim2 != ndim ){ DXSetError( ERROR_BAD_TYPE, "number of upper and lower bounds does not match"); goto error; } } for( j=0; j<ndim; j++){ lbnd[j] = lower[j]; ubnd[j] = upper[j]; } } /* Ensure bounds are OK. */ for( j=0; j<ndim; j++ ){ if( ubnd[j] < lbnd[j] ) { tmp = ubnd[j]; ubnd[j] = lbnd[j]; lbnd[j] = tmp; } } /* If DELTAS was supplied, get its values and check dimensionality. */ if( in[3] ){ deltas = SXGet1r( "deltas", in[3], &ndim2 ); if( ndim2 == 1 ){ for( j=0; j<ndim; j++){ del[j] = *deltas; } } else { if( ndim2 != ndim ){ DXSetError( ERROR_BAD_TYPE, "incorrect number of deltas given"); goto error; } else { for( j=0; j<ndim; j++){ del[j] = deltas[j]; } } } /* Find the corresponding counts and adjust lower bounds */ for( j=0; j<ndim; j++ ){ if( del[j] > 0.0 ){ cnt[j] = 1 + (int) ( 0.9999 + (ubnd[j]-lbnd[j])/del[j] ); lbnd[j] = 0.5*( ubnd[j] + lbnd[j] - ( cnt[j] - 1 )*del[j] ); } else { DXSetError( ERROR_BAD_TYPE, "negative or zero delta given"); goto error; } } /* If COUNTS was supplied, get its values and check dimensionality. */ } else if( in[4] ){ counts = SXGet1i( "counts", in[4], &ndim2 ); if( ndim2 == 1 ){ for( j=0; j<ndim; j++){ cnt[j] = *counts; } } else { if( ndim2 != ndim ){ DXSetError( ERROR_BAD_TYPE, "incorrect number of counts given"); goto error; } else { for( j=0; j<ndim; j++){ cnt[j] = counts[j]; } } } /* Find corresponding DELTAS */ for( j=0; j<ndim; j++ ){ if( cnt[j] > 1 ) { del[j] = ( ubnd[j] - lbnd[j] )/( (float) cnt[j] - 1 ); } else { cnt[j] = 1; del[j] = 1.0; tmp = 0.5*( ubnd[j]+ lbnd[j] ); ubnd[j] = tmp; lbnd[j] = tmp; } } /* report an error if neither COUNTS nor DELTAS was supplied. */ } else { DXSetError( ERROR_MISSING_DATA, "no deltas or counts given"); goto error; } /* Construct the n-d delta vectors, form the increments on each axis. */ for( j=0; j<9; j++ ) del3d[j] = 0.0; for( j=0; j<ndim; j++ ) del3d[ j*(ndim+1) ] = del[j]; /* Create the output field. */ o = (Object) DXNewField(); if( !o ) goto error; /* Create the positions array and put it in the field. */ array = DXMakeGridPositionsV( ndim, cnt, lbnd, del3d ); if( !array ) goto error; if( !DXSetComponentValue( (Field) o, "positions", (Object) array ) ) goto error; array = NULL; /* Create the connections array and put it in the field. */ array = DXMakeGridConnectionsV( ndim, cnt ); if( !array ) goto error; if( !DXSetComponentValue( (Field) o, "connections", (Object) array ) ) goto error; array = NULL; /* Finish the field */ if( !DXEndField( (Field) o ) ) goto error; /* Return the output field. */ out[0] = o; return( OK ); error: DXDelete( o ); return( ERROR ); }
Error _dxfValidate(Field f) { Array current = NULL; Array target = NULL; char *tname, *cname; int ncurrent, ntarget, *ip; int index; unsigned char *cp; int i, j, lim, nitems; Type type, ref_type; Category cat; String s = NULL; Object o = NULL; int rank, shape[MAXRANK]; int counts[MAXRANK]; for (i=0; (current=(Array)DXGetEnumeratedComponentValue(f, i, &cname)); i++) { /* dep */ if ((s = (String)DXGetAttribute((Object)current, "dep")) != NULL) { /* make sure number of items matches number of items in dep */ if ((DXGetObjectClass((Object)s) != CLASS_STRING) || ((tname = DXGetString(s)) == NULL)) { DXSetError(ERROR_DATA_INVALID, Err_MustBeString, "dep", cname); return ERROR; } if ((target = (Array)DXGetComponentValue(f, tname)) == NULL) { DXSetError(ERROR_DATA_INVALID, Err_MissingComp, tname, "dep", cname); return ERROR; } if (DXGetObjectClass((Object)target) != CLASS_ARRAY) { DXSetError(ERROR_DATA_INVALID, Err_NotArray, tname, "dep", cname); return ERROR; } if (!DXGetArrayInfo(current, &nitems, &type, &cat, &rank, shape)) return ERROR; ncurrent = nitems; if (!DXGetArrayInfo(target, &nitems, &type, &cat, &rank, shape)) return ERROR; ntarget = nitems; if (ncurrent != ntarget) { DXSetError(ERROR_DATA_INVALID, Err_DiffCount, "dep", ncurrent, cname, ntarget, tname); return ERROR; } } /* end of if (has dep) */ /* ref */ if ((s = (String)DXGetAttribute((Object)current, "ref")) != NULL) { if ((DXGetObjectClass((Object)s) != CLASS_STRING) || ((tname = DXGetString(s)) == NULL)) { DXSetError(ERROR_DATA_INVALID, Err_MustBeString, "ref", cname); return ERROR; } if ((target = (Array)DXGetComponentValue(f, tname)) == NULL) { DXSetError(ERROR_DATA_INVALID, Err_MissingComp, tname, "ref", cname); return ERROR; } if (DXGetObjectClass((Object)target) != CLASS_ARRAY) { DXSetError(ERROR_DATA_INVALID, Err_NotArray, tname, "ref", cname); return ERROR; } if (!DXGetArrayInfo(current, &nitems, &type, &cat, &rank, shape)) return ERROR; if ( !( type == TYPE_INT || type == TYPE_UBYTE ) ) { DXSetError(ERROR_DATA_INVALID, Err_RefNotInt, cname); return ERROR; } ref_type = type; ncurrent = nitems; for (j=0; j<rank; j++) ncurrent *= shape[j]; if (ncurrent > 0) { if (!DXGetArrayInfo(target, &nitems, &type, &cat, &rank, shape)) return ERROR; ntarget = nitems; /* only do this if they are already irregular */ if (DXGetArrayClass(current) == CLASS_ARRAY) { if ((ip = (int *)DXGetArrayData(current)) == NULL) return ERROR; cp = (unsigned char *) ip; /* neighbors can have -1's as indicies */ lim = strcmp(cname, "neighbors") ? 0 : -1; for (j=0; j < ncurrent; j++) { if (ref_type == TYPE_INT) index = *(ip++); else index = *(cp++); if (index < lim || index >= ntarget) { DXSetError(ERROR_DATA_INVALID, Err_OutOfRange, j+1, ending(j+1), cname, index, lim, ntarget-1); return ERROR; } } } else if (DXQueryGridConnections(current, &rank, counts)) { for (j=0, ncurrent=1; j<rank; j++) ncurrent *= counts[j]; if (ncurrent > ntarget) { DXSetError(ERROR_DATA_INVALID, Err_DiffCount, "ref", ncurrent, cname, ntarget, tname); return ERROR; } } else { /* mesh array of mixed path and irregular arrays. */ /* have to handle the terms separately */ } } } /* end of if (has ref) */ /* der - can be string lists here */ if ((o = DXGetAttribute((Object)current, "der")) != NULL) { if (DXExtractString(o, &tname)) { /* simple string? */ if ((target = (Array)DXGetComponentValue(f, tname)) == NULL) { DXSetError(ERROR_DATA_INVALID, Err_MissingComp, tname, "der", cname); return ERROR; } if (DXGetObjectClass((Object)target) != CLASS_ARRAY) { DXSetError(ERROR_DATA_INVALID, Err_NotArray, tname, "der", cname); return ERROR; } } else if (DXExtractNthString(o, 0, &tname)) { /* string list? */ for (j=0; DXExtractNthString(o, j, &tname); j++) { if ((target = (Array)DXGetComponentValue(f, tname)) == NULL) { DXSetError(ERROR_DATA_INVALID, Err_MissingComp, tname, "der", cname); return ERROR; } if (DXGetObjectClass((Object)target) != CLASS_ARRAY) { DXSetError(ERROR_DATA_INVALID, Err_NotArray, tname, "der", cname); return ERROR; } } } else { /* neither string or string list */ DXSetError(ERROR_DATA_INVALID, Err_MustBeStringList, "der", cname); return ERROR; } } /* end of if (has der) */ /* element type */ if ((s = (String)DXGetAttribute((Object)current, "element type")) != NULL) { if ((DXGetObjectClass((Object)s) != CLASS_STRING) || ((tname = DXGetString(s)) == NULL)) { DXSetError(ERROR_DATA_INVALID, Err_MustBeString, "element type", cname); return ERROR; } if (!strcmp(cname, "connections") && DXQueryGridConnections(current, &rank, counts)) { if (!elemtypecheck(rank, tname)) return ERROR; } } /* end of if (has element type) */ } /* for each component in the field */ /* check for missing positions component if the field has more than * one component. */ if (i > 1 && !DXGetComponentValue(f, "positions")) DXWarning("importing a field with no `positions' component"); return OK; }
static Error saydata(Object o, char *opt) { Array a; int nitems; Type type; Category category; int rank; int shape[MAXRANK]; int valids; Point boxlist[8]; Point vboxlist[8]; float min, max, avg; if (DXGetObjectClass(o) == CLASS_ARRAY) { DXGetArrayInfo((Array)o, &nitems, &type, &category, &rank, shape); pinfo(1, nitems, nitems, type, category, rank, shape); } else if (DXGetObjectClass(o) == CLASS_FIELD) { a = (Array)DXGetComponentValue((Field)o, "positions"); if (!a) { DescribeMsg("The Field does not contain any positions. It will not cause an error, but will be\n"); DescribeMsg("silently ignored by most modules since positions are required.\n"); DescribeMsg("Use the `Mark' or `Replace' module to create a `positions' component.\n"); } a = (Array)DXGetComponentValue((Field)o, "data"); if (!a) { DescribeMsg("The Field contains nothing marked as data items.\n"); DescribeMsg("If the Field does contain data under another name, use the `Mark' module\n"); DescribeMsg("to select what should be used as data.\n"); } else { DXGetArrayInfo(a, &nitems, &type, &category, &rank, shape); if (!validcount((Field)o, "data", &valids)) return ERROR; pinfo(1, nitems, valids, type, category, rank, shape); } } else if (!DXGetType((Object)o, &type, &category, &rank, shape)) { /* DescribeMsg("no data type information\n"); */ DXResetError(); } else pinfo(0, 0, 0, type, category, rank, shape); /* get bbox and print it in a non-threatening format */ if (!DXBoundingBox(o, boxlist)) { /* DescribeMsg("Cannot get information about the positions of the data\n"); */ DXResetError(); } else { DescribeMsg("The positions are enclosed within the box defined by the corner points:\n"); DescribeMsg("[ %g %g %g ] and [ %g %g %g ]\n", boxlist[0].x, boxlist[0].y, boxlist[0].z, boxlist[7].x, boxlist[7].y, boxlist[7].z); } if (!DXValidPositionsBoundingBox(o, vboxlist)) { /* DescribeMsg("Cannot get information about the valid positions of the data\n"); */ DXResetError(); } else { if ((boxlist[0].x != vboxlist[0].x) || (boxlist[7].x != vboxlist[7].x) || (boxlist[0].y != vboxlist[0].y) || (boxlist[7].y != vboxlist[7].y) || (boxlist[0].z != vboxlist[0].z) || (boxlist[7].z != vboxlist[7].z)) { DescribeMsg("The VALID positions are enclosed within the box defined by the corner points:\n"); DescribeMsg("[ %g %g %g ] and [ %g %g %g ]\n", vboxlist[0].x, vboxlist[0].y, vboxlist[0].z, vboxlist[7].x, vboxlist[7].y, vboxlist[7].z); } } /* something about data stats */ if (!DXStatistics(o, "data", &min, &max, &avg, NULL)) { /* DescribeMsg("Cannot get information about the data values\n"); */ DXResetError(); } else { DescribeMsg("Data range is:\n"); DescribeMsg("minimum = %g, maximum = %g, average = %g\n", min, max, avg); if (rank > 0) { /* ??? call vectorstats here if rank >= 1 * look at the code in histogram; does rank=1, nothing * about larger. */ DescribeMsg("(These are the scalar statistics which will be used by modules\n"); DescribeMsg("which need scalar values. The length is computed for vectors and\n"); DescribeMsg("the determinant for matricies.)\n"); } } return OK; }
/* accumulate info about what's what */ static Error traverse(Object o, struct info *ip, int nosee) { Object subo; Class curclass; int i; switch (curclass = DXGetObjectClass(o)) { case CLASS_FIELD: return validfield((Field)o, ip, nosee); case CLASS_GROUP: /* traverse members */ for (i=0; (subo = DXGetEnumeratedMember((Group)o, i, NULL)); i++) { if (!traverse(subo, ip, nosee)) return ERROR; } break; case CLASS_SCREEN: if (!DXGetScreenInfo((Screen)o, &subo, NULL, NULL)) return ERROR; return traverse(subo, ip, 1); case CLASS_XFORM: if (!DXGetXformInfo((Xform)o, &subo, NULL)) return ERROR; return traverse(subo, ip, nosee); case CLASS_CLIPPED: if (!DXGetClippedInfo((Clipped)o, &subo, NULL)) return ERROR; return traverse(subo, ip, nosee); /* is this right? */ case CLASS_LIGHT: ip->ri.nlights++; break; case CLASS_INTERPOLATOR: case CLASS_MAX: case CLASS_MIN: case CLASS_PRIVATE: case CLASS_DELETED: case CLASS_STRING: case CLASS_ARRAY: case CLASS_CAMERA: default: for (i=0; i<ip->ri.badobjs; i++) { if (ip->ri.badclass[i] == curclass) return OK; } ip->ri.badobjs++; ip->ri.badclass = (Class *)DXReAllocate((Pointer)ip->ri.badclass, sizeof(Class) * ip->ri.badobjs); ip->ri.badclass[ip->ri.badobjs - 1] = curclass; break; } return OK; }
static Error ConvertFieldObject(Object out, char *strin) { Class cl; int i, rank, shape[30], numitems; Type type; Category category; Array data, new_data; RGBColor *dp_old, *dp_new; Object subo; float red, green, blue, hue, sat, val; if (!(cl = DXGetObjectClass(out))) return ERROR; switch (cl) { case CLASS_GROUP: for (i=0; (subo = DXGetEnumeratedMember((Group)out, i, NULL)); i++) { if (!ConvertFieldObject((Object)subo, strin)) return ERROR; } break; case CLASS_FIELD: if (DXEmptyField((Field)out)) return OK; data = (Array)DXGetComponentValue((Field)out,"data"); if (!data) { DXSetError(ERROR_MISSING_DATA,"#10240", "data"); return ERROR; } DXGetArrayInfo(data,&numitems,&type,&category,&rank,shape); if ((type != TYPE_FLOAT)||(category != CATEGORY_REAL)) { DXSetError(ERROR_DATA_INVALID,"#10331", "data"); return ERROR; } if ((rank != 1)||(shape[0] != 3)) { DXSetError(ERROR_DATA_INVALID,"#10331", "data"); return ERROR; } new_data = DXNewArray(TYPE_FLOAT,CATEGORY_REAL,1,3); new_data = DXAddArrayData(new_data, 0, numitems, NULL); dp_old = (RGBColor *)DXGetArrayData(data); dp_new = (RGBColor *)DXGetArrayData(new_data); if (!strcmp(strin,"hsv")) { for (i=0; i<numitems; i++) { if (!_dxfHSVtoRGB(dp_old[i].r, dp_old[i].g, dp_old[i].b, &red, &green, &blue)) return ERROR; dp_new[i] = DXRGB(red,green,blue); } } else { for (i=0; i<numitems; i++) { if (!_dxfRGBtoHSV(dp_old[i].r, dp_old[i].g, dp_old[i].b, &hue, &sat, &val)) return ERROR; dp_new[i] = DXRGB(hue, sat, val); } } DXSetComponentValue((Field)out, "data", (Object)new_data); DXChangedComponentValues((Field)out,"data"); DXEndField((Field)out); break; default: break; } return OK; }
/* make sure the field contains colors and that > 1 are valid. * i guess we can look to see that the positions are 1D <= p <= 3D * as well. and we could look at connections here as well. */ static Error validfield(Field f, struct info *ip, int nosee) { int icount = 0; Array colors, pos, conn; char *elem = NULL; char *dep = NULL; char *invalid = NULL; InvalidComponentHandle ih; /* check for fields - recurse above this */ if (DXGetObjectClass((Object)f) != CLASS_FIELD) { Return_Internal_Error; } /* check pos first */ pos = (Array)DXGetComponentValue(f, "positions"); if (!pos) { ip->np.nopos++; return OK; } if (!DXGetArrayInfo(pos, &icount, NULL, NULL, NULL, NULL)) return ERROR; if (icount <= 0) { ip->np.nopos++; return OK; } /* pos must be vector, rank 1, 1 <= shape <= 3 */ if ((!DXTypeCheck(pos, TYPE_FLOAT, CATEGORY_REAL, 1, 1)) && (!DXTypeCheck(pos, TYPE_FLOAT, CATEGORY_REAL, 1, 2)) && (!DXTypeCheck(pos, TYPE_FLOAT, CATEGORY_REAL, 1, 3))) { ip->ri.badpos++; return OK; } /* check Nd of conn here. if "nosee" is true, don't count the * Nd of the connections because normal modules won't "see" these * as normal fields. */ if (!nosee) { conn = (Array)DXGetComponentValue(f, "connections"); if (!conn) ip->nd.c0++; else if (DXGetObjectClass((Object)conn) != CLASS_ARRAY) ip->nd.cbad++; else if (!DXGetStringAttribute((Object)conn, "element type", &elem)) ip->nd.cmissing++; else if (!strcmp(elem, "lines")) ip->nd.c1++; else if (!strcmp(elem, "triangles") || !strcmp(elem, "quads")) ip->nd.c2++; else if (!strcmp(elem, "tetrahedra") || !strcmp(elem, "cubes")) ip->nd.c3++; else if (!strncmp(elem, "cubes", 5) && (strlen(elem) > 5)) ip->nd.cplus++; else ip->nd.cbad++; } /* expect colors and follow dependency */ colors = (Array)DXGetComponentValue(f, "colors"); if (!colors) { ip->ri.nocolors++; return OK; } else { /* check for colormap component */ if (DXGetComponentValue(f, "color map") != NULL) ip->nc.cbytemap++; else if (DXTypeCheck(colors, TYPE_UBYTE, CATEGORY_REAL, 1, 3)) ip->nc.cubyte++; else if (DXTypeCheck(colors, TYPE_FLOAT, CATEGORY_REAL, 1, 3)) ip->nc.cfloat++; else ip->nc.cunknown++; } /* follow colors dependency. it will be unusual to find no dep. */ if (!DXGetStringAttribute((Object)colors, "dep", &dep)) { ip->np.nodep++; return OK; } if (!DXGetArrayInfo(colors, &icount, NULL, NULL, NULL, NULL)) return ERROR; if (icount == 0) { ip->np.novalid++; return OK; } #define INVLEN 10 /* strlen("invalid "); */ if (!(invalid = (char *)DXAllocate(strlen(dep) + INVLEN))) return ERROR; strcpy(invalid, "invalid "); strcat(invalid, dep); /* if no invalid component, all valid */ if (!DXGetComponentValue(f, invalid)) { DXFree((Pointer)invalid); ip->ri.nfields++; return OK; } DXFree((Pointer)invalid); ih = DXCreateInvalidComponentHandle((Object)f, NULL, dep); if (!ih) return ERROR; icount = DXGetValidCount(ih); DXFreeInvalidComponentHandle(ih); if (icount == 0) { ip->np.novalid++; return OK; } ip->ri.nfields++; return OK; }
static int doLeaf(Object *in, Object *out) { int result=0; Field field; Category category; Category lookup_category; int rank, shape[30]; char *cat_comp; char *data_comp; char *lookup_comp; char name_str[256]; char *opstr; int operation; int lookup_knt; int lookup_knt_provided = 0; Array cat_array = NULL; Array data_array = NULL; Array out_array = NULL; Array array = NULL; Array lookup_array = NULL; float *out_data; int data_knt, cat_knt; int out_knt=0; Type cat_type, data_type, lookup_type; float floatmax; ICH invalid; if (DXGetObjectClass(in[0]) == CLASS_FIELD) { field = (Field)in[0]; if (DXEmptyField(field)) return OK; } if (!DXExtractString((Object)in[1], &opstr)) opstr = STR_COUNT; if (!strcmp(opstr, STR_COUNT)) operation = STAT_COUNT; else if (!strcmp(opstr, STR_MEAN)) operation = STAT_MEAN; else if (!strcmp(opstr, STR_SD)) operation = STAT_SD; else if (!strcmp(opstr, STR_VAR)) operation = STAT_VAR; else if (!strcmp(opstr, STR_MIN)) operation = STAT_MIN; else if (!strcmp(opstr, STR_MAX)) operation = STAT_MAX; else if (!strcmp(opstr, STR_ACCUM)) operation = STAT_ACCUM; else operation = STAT_UNDEF; if (operation == STAT_UNDEF) { DXSetError(ERROR_BAD_PARAMETER, "statistics operation must be one of: count, mean, sd, var, min, max"); goto error; } if (!DXExtractString((Object)in[2], &cat_comp)) cat_comp = STR_DATA; if (!DXExtractString((Object)in[3], &data_comp)) data_comp = STR_DATA; if (in[0]) { if (DXGetObjectClass(in[0]) != CLASS_FIELD) { DXSetError(ERROR_BAD_CLASS, "\"input\" should be a field"); goto error; } cat_array = (Array)DXGetComponentValue((Field)in[0], cat_comp); if (! cat_array) { DXSetError(ERROR_MISSING_DATA, "\"input\" has no \"%s\" categorical component", cat_comp); goto error; } if (DXGetObjectClass((Object)cat_array) != CLASS_ARRAY) { DXSetError(ERROR_BAD_CLASS, "categorical component \"%s\" of \"input\" should be an array", cat_comp); goto error; } if (!HasInvalid((Field)in[0], cat_comp, &invalid)) { DXSetError(ERROR_INTERNAL, "Bad invalid component"); goto error; } if (invalid) { DXSetError(ERROR_DATA_INVALID, "categorical component must not contain invalid data"); goto error; } DXGetArrayInfo(cat_array, &cat_knt, &cat_type, &category, &rank, shape); if ( (cat_type != TYPE_BYTE && cat_type != TYPE_UBYTE && cat_type != TYPE_INT && cat_type != TYPE_UINT) || category != CATEGORY_REAL || !((rank == 0) || ((rank == 1)&&(shape[0] == 1)))) { DXSetError(ERROR_DATA_INVALID, "categorical component %s must be scalar non-float", cat_comp); goto error; } if (operation != STAT_COUNT) { data_array = (Array)DXGetComponentValue((Field)in[0], data_comp); if (! data_array) { DXSetError(ERROR_MISSING_DATA, "\"input\" has no \"%s\" data component", data_comp); goto error; } if (DXGetObjectClass((Object)data_array) != CLASS_ARRAY) { DXSetError(ERROR_BAD_CLASS, "data component \"%s\" of \"input\" should be an array", data_comp); goto error; } DXGetArrayInfo(data_array, &data_knt, &data_type, &category, &rank, shape); if ( (data_type != TYPE_BYTE && data_type != TYPE_UBYTE && data_type != TYPE_INT && data_type != TYPE_UINT && data_type != TYPE_FLOAT && data_type != TYPE_DOUBLE) || category != CATEGORY_REAL || !((rank == 0) || ((rank == 1)&&(shape[0] == 1)))) { DXSetError(ERROR_DATA_INVALID, "data component \"%s\" must be scalar", data_comp); goto error; } if (data_knt != cat_knt) { DXSetError(ERROR_DATA_INVALID, "category and data counts must be the same"); goto error; } } } if (in[4]) { if (DXExtractString((Object)in[4], &lookup_comp)) { lookup_array = (Array)DXGetComponentValue((Field)in[0], lookup_comp); if (!lookup_array) { DXSetError(ERROR_MISSING_DATA, "\"input\" has no \"%s\" lookup component", lookup_comp); goto error; } } else if (DXExtractInteger((Object)in[4], &lookup_knt)) { lookup_knt_provided = 1; out_knt = lookup_knt; } else if (DXGetObjectClass((Object)in[4]) == CLASS_ARRAY) { lookup_array = (Array)in[4]; sprintf(name_str, "%s lookup", cat_comp); lookup_comp = name_str; } else { DXSetError(ERROR_DATA_INVALID, "lookup component must be string, integer, or array"); goto error; } } else { sprintf(name_str, "%s lookup", cat_comp); lookup_comp = name_str; lookup_array = (Array)DXGetComponentValue((Field)in[0], lookup_comp); } if (lookup_array) { DXGetArrayInfo(lookup_array, &lookup_knt, &lookup_type, &lookup_category, &rank, shape); out_knt = lookup_knt; } else if (!lookup_knt_provided){ if (!DXStatistics((Object)in[0], cat_comp, NULL, &floatmax, NULL, NULL)) { DXSetError(ERROR_INTERNAL, "Bad statistics on categorical component"); goto error; } out_knt = (int)(floatmax+1.5); } out_array = DXNewArray(TYPE_FLOAT, CATEGORY_REAL, 0); if (! out_array) goto error; if (! DXSetAttribute((Object)out_array, "dep", (Object)DXNewString("positions"))) goto error; if (! DXAddArrayData(out_array, 0, out_knt, NULL)) goto error; if (out[0]) { if (DXGetObjectClass(out[0]) != CLASS_FIELD) { DXSetError(ERROR_INTERNAL, "non-field object found in output"); goto error; } if (DXGetComponentValue((Field)out[0], "data")) DXDeleteComponent((Field)out[0], "data"); if (! DXSetComponentValue((Field)out[0], "data", (Object)out_array)) goto error; if (lookup_array) { if (! DXSetComponentValue((Field)out[0], lookup_comp, (Object)lookup_array)) goto error; } } else { out[0] = (Object)DXNewField(); array = DXMakeGridPositions(1, out_knt, 0.0, 1.0); if (!array) goto error; DXSetComponentValue((Field)out[0], "positions", (Object)array); array = DXMakeGridConnections(1, out_knt); if (!array) goto error; DXSetComponentValue((Field)out[0], "connections", (Object)array); DXSetComponentValue((Field)out[0], "data", (Object)out_array); if (lookup_array) { if (! DXSetComponentValue((Field)out[0], lookup_comp, (Object)lookup_array)) goto error; } } out_data = DXGetArrayData(out_array); if (! out_data) goto error; result = CategoryStatistics_worker( out_data, cat_knt, out_knt, cat_array, data_array, cat_type, data_type, operation); if (! result) { if (DXGetError()==ERROR_NONE) DXSetError(ERROR_INTERNAL, "error return from user routine"); goto error; } result = (DXEndField((Field)out[0]) != NULL); error: return result; }
static Error traverse(Object *in, Object *out) { switch(DXGetObjectClass(in[0])) { case CLASS_FIELD: case CLASS_ARRAY: /* * If we have made it to the leaf level, call the leaf handler. */ if (! doLeaf(in, out)) return ERROR; return OK; case CLASS_GROUP: { int i, j; int memknt; Class groupClass = DXGetGroupClass((Group)in[0]); DXGetMemberCount((Group)in[0], &memknt); /* * Create new in and out lists for each child * of the first input. */ for (i = 0; i < memknt; i++) { Object new_in[2], new_out[1]; /* * For all inputs that are Values, pass them to * child object list. For all that are Field/Group, get * the appropriate decendent and place it into the * child input object list. */ /* input "input" is Field/Group */ if (in[0]) new_in[0] = DXGetEnumeratedMember((Group)in[0], i, NULL); else new_in[0] = NULL; /* input "size" is Value */ new_in[1] = in[1]; /* * For all outputs that are Values, pass them to * child object list. For all that are Field/Group, get * the appropriate decendent and place it into the * child output object list. Note that none should * be NULL (unlike inputs, which can default). */ /* output "output" is Field/Group */ new_out[0] = DXGetEnumeratedMember((Group)out[0], i, NULL); if (! traverse(new_in, new_out)) return ERROR; /* * Now for each output that is not a Value, replace * the updated child into the object in the parent. */ /* output "output" is Field/Group */ DXSetEnumeratedMember((Group)out[0], i, new_out[0]); } return OK; } case CLASS_XFORM: { int i, j; Object new_in[2], new_out[1]; /* * Create new in and out lists for the decendent of the * first input. For inputs and outputs that are Values * copy them into the new in and out lists. Otherwise * get the corresponding decendents. */ /* input "input" is Field/Group */ if (in[0]) DXGetXformInfo((Xform)in[0], &new_in[0], NULL); else new_in[0] = NULL; /* input "size" is Value */ new_in[1] = in[1]; /* * For all outputs that are Values, copy them to * child object list. For all that are Field/Group, get * the appropriate decendent and place it into the * child output object list. Note that none should * be NULL (unlike inputs, which can default). */ /* output "output" is Field/Group */ DXGetXformInfo((Xform)out[0], &new_out[0], NULL); if (! traverse(new_in, new_out)) return ERROR; /* * Now for each output that is not a Value replace * the updated child into the object in the parent. */ /* output "output" is Field/Group */ DXSetXformObject((Xform)out[0], new_out[0]); return OK; } case CLASS_SCREEN: { int i, j; Object new_in[2], new_out[1]; /* * Create new in and out lists for the decendent of the * first input. For inputs and outputs that are Values * copy them into the new in and out lists. Otherwise * get the corresponding decendents. */ /* input "input" is Field/Group */ if (in[0]) DXGetScreenInfo((Screen)in[0], &new_in[0], NULL, NULL); else new_in[0] = NULL; /* input "size" is Value */ new_in[1] = in[1]; /* * For all outputs that are Values, copy them to * child object list. For all that are Field/Group, get * the appropriate decendent and place it into the * child output object list. Note that none should * be NULL (unlike inputs, which can default). */ /* output "output" is Field/Group */ DXGetScreenInfo((Screen)out[0], &new_out[0], NULL, NULL); if (! traverse(new_in, new_out)) return ERROR; /* * Now for each output that is not a Value, replace * the updated child into the object in the parent. */ /* output "output" is Field/Group */ DXSetScreenObject((Screen)out[0], new_out[0]); return OK; } case CLASS_CLIPPED: { int i, j; Object new_in[2], new_out[1]; /* input "input" is Field/Group */ if (in[0]) DXGetClippedInfo((Clipped)in[0], &new_in[0], NULL); else new_in[0] = NULL; /* input "size" is Value */ new_in[1] = in[1]; /* * For all outputs that are Values, copy them to * child object list. For all that are Field/Group, get * the appropriate decendent and place it into the * child output object list. Note that none should * be NULL (unlike inputs, which can default). */ /* output "output" is Field/Group */ DXGetClippedInfo((Clipped)out[0], &new_out[0], NULL); if (! traverse(new_in, new_out)) return ERROR; /* * Now for each output that is not a Value, replace * the updated child into the object in the parent. */ /* output "output" is Field/Group */ DXSetClippedObjects((Clipped)out[0], new_out[0], NULL); return OK; } default: { DXSetError(ERROR_BAD_CLASS, "encountered in object traversal"); return ERROR; } } }
static int doLeaf(Object *in, Object *out) { int i, result=0; Array array; Field field; Pointer *in_data[2], *out_data[1]; int in_knt[2], out_knt[1]; Type type; Category category; int rank, shape; Object attr, src_dependency_attr = NULL; char *src_dependency = NULL; /* * Irregular positions info */ int p_knt, p_dim; float *p_positions; int c_knt = -1; /* User-added declarations */ float *scratch, *in_ptr, size; Point inpoint, *out_pos_ptr; ArrayHandle handle; Array connections; Line *conn_ptr; /* * positions and/or connections are required, so the first must * be a field. */ if (DXGetObjectClass(in[0]) != CLASS_FIELD) { DXSetError(ERROR_DATA_INVALID, "positions and/or connections unavailable in array object"); goto error; } else { field = (Field)in[0]; if (DXEmptyField(field)) return OK; /* * Determine the dependency of the source object's data * component. */ src_dependency_attr = DXGetComponentAttribute(field, "data", "dep"); if (! src_dependency_attr) { DXSetError(ERROR_MISSING_DATA, "\"input\" data component is missing a dependency attribute"); goto error; } if (DXGetObjectClass(src_dependency_attr) != CLASS_STRING) { DXSetError(ERROR_BAD_CLASS, "\"input\" dependency attribute"); goto error; } src_dependency = DXGetString((String)src_dependency_attr); array = (Array)DXGetComponentValue(field, "positions"); if (! array) { DXSetError(ERROR_BAD_CLASS, "\"input\" contains no positions component"); goto error; } /* change to doLeaf so that regular positions are not expanded */ if (!(handle = DXCreateArrayHandle(array))) goto error; scratch = DXAllocate(3*sizeof(float)); if (!scratch) goto error; DXGetArrayInfo(array, &p_knt, NULL, NULL, NULL, &p_dim); } /* New User code starts here */ /* Make the new positions array for the output */ array = DXNewArray(TYPE_FLOAT, CATEGORY_REAL, 1, 3); if (! array) goto error; /* Check that the positions are three dimensional: */ if (p_dim != 3) { DXSetError(ERROR_DATA_INVALID,"input positions must be 3-dimensional"); goto error; } /* Allocate space in the new positions array */ if (! DXAddArrayData(array, 0, 4*p_knt, NULL)) goto error; /* Get a pointer to the output positions */ out_pos_ptr = (Point *)DXGetArrayData(array); /* Make a connections component for the output */ connections = DXNewArray(TYPE_INT, CATEGORY_REAL, 1, 2); /* Allocate space in the new connections array */ if (! DXAddArrayData(connections, 0, 2*p_knt, NULL)) goto error; DXSetAttribute((Object)connections, "element type", (Object)DXNewString("lines")); /* Get a pointer to the new connections */ conn_ptr = (Line *)DXGetArrayData(connections); /* Now "draw" the x's */ for (i=0; i< p_knt; i++) { /* the following line accesses the position via the * array handling routines */ in_ptr = (float *)DXIterateArray(handle, i, in_ptr, scratch); inpoint = DXPt(in_ptr[0], in_ptr[1], in_ptr[2]); DXExtractFloat(in[1], &size); out_pos_ptr[4*i] = DXPt(inpoint.x - size, inpoint.y, inpoint.z); out_pos_ptr[4*i+1] = DXPt(inpoint.x + size, inpoint.y, inpoint.z); out_pos_ptr[4*i+2] = DXPt(inpoint.x, inpoint.y - size, inpoint.z); out_pos_ptr[4*i+3] = DXPt(inpoint.x, inpoint.y + size, inpoint.z); conn_ptr[2*i] = DXLn(4*i, 4*i+1); conn_ptr[2*i+1] = DXLn(4*i+2, 4*i+3); } /* Clean up; we're about to significantly modify the positions and connections */ DXChangedComponentStructure((Field)out[0],"positions"); DXChangedComponentStructure((Field)out[0],"connections"); /* Now place the new positions and connections in the output field */ DXSetComponentValue((Field)out[0], "positions", (Object)array); DXSetComponentValue((Field)out[0], "connections", (Object)connections); /* Finalize the field */ DXEndField((Field)out[0]); /* Delete scratch and handle */ DXFree((Pointer)scratch); DXFreeArrayHandle(handle); /* return */ return OK; error: /* Delete scratch and handle */ DXFree((Pointer)scratch); DXFreeArrayHandle(handle); return ERROR; }
static Error sayclass(Object o, char *intro, int descend) { int count; switch (DXGetObjectClass(o)) { case CLASS_GROUP: if (!DXGetMemberCount((Group)o, &count)) return ERROR; switch(DXGetGroupClass((Group)o)) { case CLASS_GROUP: DescribeMsg("%s %s Group which contains %d member%s.\n", intro, IS, count, (count==1 ? "" : "s")); break; case CLASS_COMPOSITEFIELD: DescribeMsg("%s %s Partitioned Field which contains %d partition%s.\n", intro, IS, count, (count==1 ? "" : "s")); break; case CLASS_MULTIGRID: DescribeMsg("%s %s Multigrid Group which contains %d member%s.\n", intro, IS, count, (count==1 ? "" : "s")); break; case CLASS_SERIES: DescribeMsg("%s %s Series Group which contains %d series member%s.\n", intro, IS, count, (count==1 ? "" : "s")); DescribeMsg("To work with one member at a time use the `Select' module\n"); break; default: DescribeMsg("%s %s Group Object but of unrecognized Group Type.\n", intro, IS); break; } if (descend) saymembers((Group)o); break; case CLASS_FIELD: DescribeMsg("%s %s Field, the basic data carrying structure in DX.\n", intro, IS); break; case CLASS_ARRAY: DescribeMsg("%s %s Array Object, containing a list of data values.\n", intro, IS_V); switch (DXGetArrayClass((Array)o)) { case CLASS_ARRAY: break; case CLASS_PRODUCTARRAY: case CLASS_MESHARRAY: case CLASS_PATHARRAY: case CLASS_CONSTANTARRAY: case CLASS_REGULARARRAY: DescribeMsg("These values are stored in a compact format to save space.\n"); break; default: DescribeMsg("The Array is of an unrecognized type.\n"); break; } /* ??? add code here ??? - print the first N values? */ break; case CLASS_STRING: DescribeMsg("%s %s String, a list of character values\n", intro, IS); DescribeMsg("It contains the value `%s'\n", DXGetString((String)o)); break; case CLASS_CAMERA: DescribeMsg("%s %s Camera, used to set the viewpoint for Rendering.\n", intro, IS); break; case CLASS_XFORM: DescribeMsg("%s %s Transformed object, meaning that a transformation will be applied to the final object before rendering.\n", intro, IS); /* sayclass of xformed obj? */ break; case CLASS_OBJECT: DescribeMsg("%s %s Generic Object, of unrecognized type.\n", intro, IS); break; case CLASS_LIGHT: DescribeMsg("%s %s Light, used to set the Lighting parameters for Rendering.\n", intro, IS); break; case CLASS_CLIPPED: DescribeMsg("%s %s Clipped Object, which means that at Rendering time part of the object will be invisible.\n", intro, IS); /* sayclass of clipped obj? */ break; case CLASS_INTERPOLATOR: DescribeMsg("%s %s Interpolator. Internal use only.\n", intro, IS); break; case CLASS_SCREEN: DescribeMsg("%s %s Screen Object, meaning this object stays aligned with the screen.\n", intro, IS); /* say something about the screen obj? */ break; case CLASS_MAX: DescribeMsg("Unrecognized Object. Object type above Class Max.\n"); break; case CLASS_MIN: DescribeMsg("Unrecognized Object. Object type below Class Min.\n"); break; case CLASS_PRIVATE: DescribeMsg("%s %s Private object, defined by a user.\n", intro, IS); break; case CLASS_DELETED: DescribeMsg("%s %s Deleted Object. Should not happen.\n", intro, IS); break; default: DescribeMsg("%s %s Unrecognized object. Bad return from GetObjectType().\n", intro, IS); break; } return OK; }
static Error DoSXEnum( Object o, char *name, char *dep ){ Array a; int n, i, *to; Object oo; /* If the supplied object is a field... */ switch( DXGetObjectClass( o ) ){ case CLASS_FIELD: /* See how many items there are in the requested component. */ a = (Array) DXGetComponentValue( (Field) o, dep ); if( !a ) { DXSetError( ERROR_DATA_INVALID, "field has no \"%s\" component", dep ); return( ERROR ); } DXGetArrayInfo( a, &n, NULL, NULL, NULL, NULL ); /* Create a new array to hold the enumeration, and get a pointer to it. */ a = (Array) DXNewArray( TYPE_INT, CATEGORY_REAL, 0 ); if( !DXAddArrayData( a, 0, n, NULL ) ) return( ERROR ); to = (int *) DXGetArrayData( a ); /* Add this new array to the field. */ DXSetComponentValue( (Field) o, name, (Object) a ); /* Store a value for the "dep" attribute of the new array. */ DXSetComponentAttribute( (Field) o, name, "dep", (Object) DXNewString( dep ) ); /* Store the enumeration values. */ for( i=0; i<n; i++ ) *(to++) = i; /* Indicate that the component values have changed, and complete the * output field. */ DXChangedComponentValues( (Field) o, name ); if( !DXEndField( (Field) o ) ) return( ERROR ); break; /* If the supplied object is a group, call this function recursively for * each member of the group. */ case CLASS_GROUP: for( i=0; oo=(Object)DXGetEnumeratedMember((Group)o,i,NULL); i++ ){ if( !DoSXEnum( oo, name, dep ) ) return( ERROR ); } break; } return( OK ); }
int m_Convert(Object *in, Object *out) { Array incolorvec, outcolorvec; int ismap, isfield, count, i, ii, numitems, addpoints; char *colorstrin, *colorstrout; char newstrin[30], newstrout[30]; Object gout; float *dpin=NULL, *dpout=NULL; gout=NULL; incolorvec = NULL; outcolorvec = NULL; if (!in[0]) { DXSetError(ERROR_MISSING_DATA,"#10000","data"); return ERROR; } out[0] = in[0]; ismap = 0; isfield = 0; /* * if it's an array (vector or list of vectors) */ if (DXGetObjectClass(in[0]) == CLASS_ARRAY) { if (!(DXQueryParameter((Object)in[0], TYPE_FLOAT, 3, &numitems))) { /* must be a list of 3-vectors or a field */ DXSetError(ERROR_BAD_PARAMETER,"#10550","data"); out[0] = NULL; return ERROR; } if (!(incolorvec = DXNewArray(TYPE_FLOAT,CATEGORY_REAL, 1, 3))){ out[0] = NULL; return ERROR; } if (!(DXAddArrayData(incolorvec,0,numitems,NULL))) goto error; if (!(dpin = (float *)DXGetArrayData(incolorvec))) goto error; if (!(DXExtractParameter((Object)in[0], TYPE_FLOAT, 3, numitems, (Pointer)dpin))) { /* must be a list of 3-vectors or a field */ DXSetError(ERROR_BAD_PARAMETER,"#10550","data"); goto error; } /* * also make the output array */ if (!(outcolorvec = DXNewArray(TYPE_FLOAT,CATEGORY_REAL, 1, 3))) goto error; if (!(DXAddArrayData(outcolorvec,0,numitems,NULL))) goto error; if (!(dpout = (float *)DXGetArrayData(outcolorvec))) goto error; } else { if (_dxfIsColorMap(in[0])) ismap = 1; else { DXResetError(); isfield = 1; } } /* now extract the to and from space names */ /* get color name */ if (!(in[1])) colorstrin = "hsv"; else if (!DXExtractString((Object)in[1], &colorstrin)) { /* invalid input string */ DXSetError(ERROR_BAD_PARAMETER,"#10200","incolorspace"); goto error; } /* convert color name to all lower case and remove spaces */ count = 0; i = 0; while ( i<29 && colorstrin[i] != '\0') { if (isalpha(colorstrin[i])){ if (isupper(colorstrin[i])) newstrin[count]= tolower(colorstrin[i]); else newstrin[count]= colorstrin[i]; count++; } i++; } newstrin[count]='\0'; if (strcmp(newstrin,"rgb")&&strcmp(newstrin,"hsv")) { DXSetError(ERROR_BAD_PARAMETER,"#10210", newstrin, "incolorspace"); goto error; } if (!in[2]) colorstrout = "rgb"; else if (!DXExtractString((Object)in[2], &colorstrout)) { /* invalid outcolorspace string */ DXSetError(ERROR_BAD_PARAMETER,"#10200","outcolorspace"); goto error; } /* convert color name to all lower case and remove spaces */ count = 0; i = 0; while ( i<29 && colorstrout[i] != '\0') { if (isalpha(colorstrout[i])){ if (isupper(colorstrout[i])) newstrout[count]= tolower(colorstrout[i]); else newstrout[count]= colorstrout[i]; count++; } i++; } newstrout[count]='\0'; if (strcmp(newstrout,"rgb")&&strcmp(newstrout,"hsv")){ /* invalid outcolorspace string */ DXSetError(ERROR_BAD_PARAMETER,"#10210", newstrout, "outcolorspace"); goto error; } if (!strcmp(newstrin,newstrout)) { DXWarning("incolorspace and outcolorspace are the same"); return OK; } if (!in[3]) { /* default behavior is to treat maps like maps (adding points) and to treat fields like fields (not adding points) */ } else { if (!DXExtractInteger(in[3], &addpoints)) { DXSetError(ERROR_BAD_PARAMETER, "#10070", "addpoints"); goto error; } if ((addpoints < 0) || (addpoints > 1)) { DXSetError(ERROR_BAD_PARAMETER, "#10070", "addpoints"); goto error; } if (isfield && addpoints) { DXSetError(ERROR_BAD_PARAMETER, "#10370", "for a field with greater than 1D positions, addpoints", "0"); goto error; } if (ismap && (!addpoints)) { /* treat the map like a field */ ismap = 0; isfield = 1; } } /* we have been given a vector value or list of values, not a map */ if ((!ismap)&&(!isfield)) { if (!strcmp(newstrin,"hsv")) { for (ii = 0; ii < numitems*3; ii = ii+3) { if (!(_dxfHSVtoRGB(dpin[ii], dpin[ii+1], dpin[ii+2], &dpout[ii], &dpout[ii+1], &dpout[ii+2]))) goto error; } } else { for (ii = 0; ii < numitems*3; ii = ii+3) { if (!(_dxfRGBtoHSV(dpin[ii], dpin[ii+1], dpin[ii+2], &dpout[ii], &dpout[ii+1], &dpout[ii+2]))) goto error; } } out[0] = (Object)outcolorvec; DXDelete((Object)incolorvec); return OK; } /* we have a map or field */ else { if (ismap) { if (!(ConvertObject(in[0], newstrin, &gout))) goto error; } else { gout = DXCopy(in[0], COPY_STRUCTURE); if (!gout) goto error; if (!(ConvertFieldObject(gout, newstrin))) goto error; } out[0] = gout; return OK; } error: out[0] = NULL; DXDelete((Object)gout); DXDelete((Object)incolorvec); DXDelete((Object)outcolorvec); return ERROR; }
Error _dxfAsyncRender (dxObject r, Camera c, char *obsolete, char *displayString) { Private cacheObject = NULL; tdmChildGlobalP globals = NULL; char* cacheId = NULL; tdmParsedFormatT *pFormat = NULL; dxObject attr; ENABLE_DEBUG(); DEBUG_MARKER("_dxfAsyncRender ENTRY"); ENTRY(("_dxfAsyncRender (0x%x, 0x%x, \"%s\", \"%s\")", r, c, obsolete, displayString)); # if defined(DEBUG) if(DXGetAttribute(r, "force env var")) { char *Buff; if(DXExtractString(DXGetAttribute(r, "force env var"), &Buff)) { PRINT(("Putting Variable %s\n", Buff)); putenv(Buff); } } # endif if (!c && !DXGetImageBounds(r,NULL,NULL,NULL,NULL)) goto error; /* get host and window name from display string, fill in the cache id */ if (!(pFormat = _tdmParseDisplayString (displayString, &cacheId))) goto error; /* validate the display string */ if (!(_validateDisplayString(pFormat, 1))) goto error ; /* Get a pointer to the global data, out of the cache or create a new one. */ if((cacheObject = (Private) DXGetCacheEntry(cacheId, 0, 0)) != NULL) { globals = (tdmChildGlobalP) DXGetPrivateData(cacheObject) ; #if defined(DX_NATIVE_WINDOWS) /* * Now lock globals so that rendering doesn't occur in another * thread until the setup is done. If we create a globals structure * here, the lock is created in CreateRenderModule, and its created * owned. */ { DEFGLOBALDATA(globals); if (DXWaitForSignal(1, &LOCK) == WAIT_TIMEOUT) goto error; } #endif } else { if(!(globals = (tdmChildGlobalP)_dxfCreateRenderModule(pFormat))) return ERROR; /* save globals in cache; call _dxfEndRenderModule when cache deleted */ if(!(cacheObject = (Private) DXNewPrivate((Pointer) globals, (Error (*)(Pointer))_dxfEndRenderModule))) { /* Can't cache tdm globals */ DXErrorGoto (ERROR_INTERNAL, "#13290"); } /* Create a reference so this doesn't get deleted while I'm using it */ DXReference ((Pointer)cacheObject); /* associate cacheId with cacheObject, set to permanent status */ if(! DXSetCacheEntry((Pointer)cacheObject, CACHE_PERMANENT, cacheId, 0, 0)) { /* Can't set cache entry for tdm globals */ DXErrorGoto (ERROR_INTERNAL, "#13300") ; } /* save the cacheId to allow cache deletion upon DestroyNotify event */ if(! (globals->cacheId = tdmAllocate(strlen(cacheId)+1))) { DXErrorGoto (ERROR_NO_MEMORY, "") ; } /* save cacheId */ strcpy(globals->cacheId,cacheId) ; } /* Now that we have a global store, use it */ { int needInit = 0; DEFGLOBALDATA(globals); if (!OBJECT || (OBJECT && OBJECT_TAG != DXGetObjectTag(r))) { if (OBJECT) DXDelete(OBJECT); OBJECT = DXReference(r); OBJECT_TAG = DXGetObjectTag(r); needInit = 1; } if (!CAMERA || (CAMERA && CAMERA_TAG != DXGetObjectTag((dxObject)c))) { if (CAMERA) DXDelete(CAMERA); CAMERA = DXReference((dxObject)c); CAMERA_TAG = DXGetObjectTag((dxObject)c); needInit = 1; } _dxfInitializeStereoSystemMode(globals, DXGetAttribute(r, "stereo system mode")); _dxfInitializeStereoCameraMode(globals, DXGetAttribute(r, "stereo camera mode")); if(CAMERA && needInit) { if(!_dxfInitRenderObject(LWIN)) { /* unable to set up for rendering */ DXErrorGoto(ERROR_NO_HARDWARE_RENDERING, "#13350"); } } /* Handle X events and redraw the image */ #if !defined(DX_NATIVE_WINDOWS) if(! _dxfProcessEvents (-1, globals, 1)) goto error; #endif } if ((attr = DXGetAttribute((dxObject)c, "camera interaction mode")) == NULL) if ((attr = DXGetAttribute(r, "object interaction mode")) == NULL) attr = DXGetAttribute(r, "interaction mode"); if (attr) { Array amode; int mode; if (DXGetObjectClass(attr) == CLASS_GROUP) { if (NULL == (amode = (Array)DXGetMember((Group)attr, "mode"))) DXErrorGoto(ERROR_DATA_INVALID, "interaction mode args group must contain a member named \"mode\""); } else if (DXGetObjectClass(attr) != CLASS_ARRAY) { DXErrorGoto(ERROR_DATA_INVALID, "interaction mode args must be a group or array"); } else amode = (Array)attr; if (DXExtractInteger((dxObject)amode, &mode)) _dxfSetInteractionMode(globals, mode, attr); else DXErrorGoto(ERROR_DATA_INVALID, "interaction mode attribute must be an integer"); } else _dxfSetInteractionMode(globals, 11, NULL); if(cacheObject) { /* delete the working reference */ DXDelete((Pointer)cacheObject) ; cacheObject = NULL; } if (cacheId) tdmFree(cacheId); if (pFormat) _dxfDeleteParsedDisplayString(pFormat); EXIT(("OK")); DEBUG_MARKER("_dxfAsyncRender EXIT"); return OK ; error: if(cacheObject) { /* delete the working reference */ DXDelete((Pointer)cacheObject) ; cacheObject = NULL; } if (cacheId) tdmFree(cacheId); if (pFormat) _dxfDeleteParsedDisplayString(pFormat); EXIT(("ERROR")); DEBUG_MARKER("_dxfAsyncRender EXIT"); return ERROR ; }
/* print something about each member, up to MEMBERCOUNT items */ static Error saymembers(Group g) { int i, count; char *name; Object subo, firstsubo; int same; Class grouptype; float position; if (!DXGetMemberCount(g, &count)) return ERROR; /* no members, nothing to do here */ if (count <= 0) return OK; /* save group type; we'll use it later on */ grouptype = DXGetGroupClass(g); switch (grouptype) { case CLASS_GROUP: if (count <= MEMBERCOUNT) { for (i=0; i<count; i++) { if (!(subo = DXGetEnumeratedMember(g, i, &name))) return ERROR; if (name) DescribeMsg(" member %d is named %s\n", i, name); } } else { for (i=0; i<MEMBERCOUNT/2; i++) { if (!(subo = DXGetEnumeratedMember(g, i, &name))) return ERROR; if (name) DescribeMsg(" member %d is named %s\n", i, name); } DescribeMsg(" ...\n"); for (i=count-MEMBERCOUNT/2; i<count; i++) { if (!(subo = DXGetEnumeratedMember(g, i, &name))) return ERROR; if (name) DescribeMsg(" member %d is named %s\n", i, name); } } break; case CLASS_COMPOSITEFIELD: break; case CLASS_MULTIGRID: /* bbox? */ break; case CLASS_SERIES: if (count <= MEMBERCOUNT) { for (i=0; i<count; i++) { if (!(subo = DXGetSeriesMember((Series)g, i, &position))) return ERROR; DescribeMsg(" member %d is at position %g\n", i, position); } } else { for (i=0; i<MEMBERCOUNT/2; i++) { if (!(subo = DXGetSeriesMember((Series)g, i, &position))) return ERROR; DescribeMsg(" member %d is at position %g\n", i, position); } DescribeMsg(" ...\n"); for (i=count-MEMBERCOUNT/2; i<count; i++) { if (!(subo = DXGetSeriesMember((Series)g, i, &position))) return ERROR; DescribeMsg(" member %d is at position %g\n", i, position); } } break; default: break; } /* if only one member, say what it is and return */ if (count <= 1) { subo = DXGetEnumeratedMember(g, 0, NULL); return sayclass(subo, "The member", 0); } /* if there is more than one member of this group, check out * whether the group members are all the same type of object. * this has to be true for a composite field and should be true * for a multigrid, and usually for a series. */ same = 1; firstsubo = DXGetEnumeratedMember(g, 0, NULL); for (i=1; i<count; i++) { if (!(subo = DXGetEnumeratedMember(g, i, NULL))) return ERROR; if (DXGetObjectClass(firstsubo) != DXGetObjectClass(subo)) { same = 0; break; } } switch (grouptype) { case CLASS_GROUP: if (same) sayclass(firstsubo, "Each group member", 0); else DescribeMsg("The group contains members of different object types\n"); break; case CLASS_COMPOSITEFIELD: if (!same || (DXGetObjectClass(firstsubo) != CLASS_FIELD)) { DescribeMsg("This is not a well-formed Partitioned Field.\n"); DescribeMsg("Members should all be Field objects and they are not.\n"); if (!same) DescribeMsg("It contains members of more than one object type.\n"); if ((DXGetObjectClass(firstsubo) != CLASS_FIELD)) DescribeMsg("It contains members which are not Field objects.\n"); } break; case CLASS_MULTIGRID: /* what about partitioned members? i think they are ok */ break; #if 0 if (!same || (DXGetObjectClass(firstsubo) != CLASS_FIELD)) { DescribeMsg("This is not a well-formed MultiGrid Group.\n"); DescribeMsg("Members should all be Field objects and they are not.\n"); if (!same) DescribeMsg("It contains members of more than one object type.\n"); if ((DXGetObjectClass(firstsubo) != CLASS_FIELD)) DescribeMsg("It contains members which are not Field objects.\n"); } break; #endif case CLASS_SERIES: if (same) sayclass(firstsubo, "Each series member", 0); else DescribeMsg("The series contains members of different object types\n"); break; default: break; } return OK; }
static Error traverse(Object *in, Object *out) { switch(DXGetObjectClass(in[0])) { case CLASS_FIELD: /* case CLASS_ARRAY: */ if (! doLeaf(in, out)) return ERROR; return OK; #if 0 case CLASS_GROUP: { int i, j; int memknt; Class groupClass = DXGetGroupClass((Group)in[0]); DXGetMemberCount((Group)in[0], &memknt); for (i = 0; i < memknt; i++) { Object new_in[4], new_out[1]; if (in[0]) new_in[0] = DXGetEnumeratedMember((Group)in[0], i, NULL); else new_in[0] = NULL; new_in[1] = in[1]; new_in[2] = in[2]; new_in[3] = in[3]; new_out[0] = DXGetEnumeratedMember((Group)out[0], i, NULL); if (! traverse(new_in, new_out)) return ERROR; DXSetEnumeratedMember((Group)out[0], i, new_out[0]); } return OK; } case CLASS_XFORM: { int i, j; Object new_in[4], new_out[1]; if (in[0]) DXGetXformInfo((Xform)in[0], &new_in[0], NULL); else new_in[0] = NULL; new_in[1] = in[1]; new_in[2] = in[2]; new_in[3] = in[3]; DXGetXformInfo((Xform)out[0], &new_out[0], NULL); if (! traverse(new_in, new_out)) return ERROR; DXSetXformObject((Xform)out[0], new_out[0]); return OK; } case CLASS_SCREEN: { int i, j; Object new_in[4], new_out[1]; if (in[0]) DXGetScreenInfo((Screen)in[0], &new_in[0], NULL, NULL); else new_in[0] = NULL; new_in[1] = in[1]; new_in[2] = in[2]; new_in[3] = in[3]; DXGetScreenInfo((Screen)out[0], &new_out[0], NULL, NULL); if (! traverse(new_in, new_out)) return ERROR; DXSetScreenObject((Screen)out[0], new_out[0]); return OK; } case CLASS_CLIPPED: { int i, j; Object new_in[4], new_out[1]; if (in[0]) DXGetClippedInfo((Clipped)in[0], &new_in[0], NULL); else new_in[0] = NULL; new_in[1] = in[1]; new_in[2] = in[2]; new_in[3] = in[3]; DXGetClippedInfo((Clipped)out[0], &new_out[0], NULL); if (! traverse(new_in, new_out)) return ERROR; DXSetClippedObjects((Clipped)out[0], new_out[0], NULL); return OK; } #endif default: { DXSetError(ERROR_BAD_CLASS, "input must be Field"); return ERROR; } } }
Error DXCallOutboard (PFE m, int dxfd) { static int firsttime = 1; Array oarr; int nin = 0; int nout = 0; Object *ilist = NULL; Object *olist = NULL; Error ret = ERROR; Error modret; ErrorCode ecode; char *emessptr = NULL; Group iobj = NULL; Group oobj = NULL; Array code = NULL; String mess = NULL; int i; int *iptr; int count = 0; int one = 1; int zero = 0; if (firsttime && ! callsetup (dxfd)) { host_status = HOST_CLOSED; return ERROR; } /* * Import the remote object, extract the number of inputs and outputs, * and rip them apart appropriately. group members are: * input parm count, * input object list (the pointers values don't mean anything in this * address space; the interesting part is whether they are NULL or not), * the output parm count, * and then each input object which isn't null. */ iobj = (Group) _dxfImportBin_FP(dxfd); if(iobj == NULL) goto finish_up; if (!DXExtractInteger (DXGetEnumeratedMember (iobj, 0, NULL), &nin)) goto finish_up; ilist = (Object *) DXAllocateZero(sizeof (Object) * nin); if (!ilist) goto finish_up; iptr = (int *)DXGetArrayData((Array)DXGetEnumeratedMember (iobj, 1, NULL)); if (!DXExtractInteger (DXGetEnumeratedMember (iobj, 2, NULL), &nout)) goto finish_up; count = 3; for (i=0; i<nin; i++) { if (iptr[i] == (int)NULL) continue; ilist[i] = DXGetEnumeratedMember(iobj, count++, NULL); } olist = (Object *) DXAllocateZero(sizeof (Object) * nout); if (!olist) goto finish_up; /* * Call the module, and save the error code if set. */ DXResetError(); _dxd_exOutboard = TRUE; modret = m (ilist, olist); _dxd_exOutboard = FALSE; /* * get these now, before we do something else which overwrites them. */ ecode = DXGetError (); emessptr = DXGetErrorMessage(); /* * now BEFORE we do anything which allocates memory or new objects * check the return objects for validity. we saw a case where the * object being returned was deleted, and then the DXNewGroup() * below got the exact same address allocated, so when we put the * group together we put a reference to the parent group into the * same group as a child. bad things followed... * * (the two calls above to geterror & geterrormsg don't allocate anything; * they return a value & ptr to a static respectively) */ for (i = 0; i < nout; i++) { if (olist[i] == NULL) continue; switch (DXGetObjectClass(olist[i])) { case CLASS_DELETED: case CLASS_MIN: case CLASS_MAX: if (ecode == ERROR_NONE) { DXSetError(ERROR_BAD_CLASS, "bad object returned as output %d from outboard module", i); ecode = DXGetError (); emessptr = DXGetErrorMessage(); } else DXAddMessage("bad object returned as output %d from outboard module", i); olist[i] = NULL; default: /* Lots of other classes */ break; } } /* * Set up for return, at least the return code and message. */ oobj = DXNewGroup (); if (oobj == NULL) goto finish_up; if (!(code = DXNewArray (TYPE_INT, CATEGORY_REAL, 0))) goto finish_up; if (! DXAddArrayData (code, 0, 1, (Pointer) &ecode)) goto finish_up; mess = DXNewString (emessptr); if (mess == NULL) goto finish_up; if (! DXSetEnumeratedMember (oobj, 0, (Object) code) || ! DXSetEnumeratedMember (oobj, 1, (Object) mess)) goto finish_up; /* * If everything is OK then go ahead and return any objects too. */ if (modret == OK) { /* send output list so the caller can tell which outputs * were set. only send the non-NULL ones. */ oarr = DXNewArray(TYPE_INT, CATEGORY_REAL, 0); if (!oarr) goto finish_up; for (i = 0; i < nout; i++) { if (! DXAddArrayData(oarr, i, 1, (olist+i) ? (Pointer)&one : (Pointer)&zero)) goto finish_up; } if (! DXSetEnumeratedMember(oobj, 2, (Object)oarr)) goto finish_up; count = 3; for (i = 0; i < nout; i++) { if (olist[i] == NULL) continue; if (! DXSetEnumeratedMember (oobj, count++, olist[i])) goto finish_up; } } if (!_dxfExportBin_FP ((Object)oobj, dxfd)) goto finish_up; /* * if you get to this point, there were no other errors. */ ret = OK; finish_up: /* * get rid of space not needed anymore. this doesn't matter for * one-shots, but for persistent modules we will run out of memory * eventually if these aren't deleted. */ DXDelete ((Object) iobj); DXDelete ((Object) oobj); DXFree ((Pointer) ilist); DXFree ((Pointer) olist); return ret; }