static Error _newQMesh(int nStrips, int nStrippedPts, QMesh *mesh, dxObject *o) { Private priv = NULL; QMesh tmp = NULL; *mesh = NULL; *o = NULL; tmp = (QMesh)DXAllocateZero(sizeof(QMeshS)); if (! tmp) return ERROR; tmp->meshArray = DXNewArray(TYPE_INT, CATEGORY_REAL, 1, 2); if (! tmp->meshArray) goto error; DXReference((dxObject)tmp->meshArray); if ( !DXAllocateArray (tmp->meshArray, nStrips)) goto error; tmp->connectionArray = DXNewArray(TYPE_INT, CATEGORY_REAL, 0); if (! tmp->connectionArray) goto error; DXReference((dxObject)tmp->connectionArray); if ( !DXAllocateArray (tmp->connectionArray, nStrippedPts)) goto error; tmp->meshes = (int *)DXGetArrayData(tmp->meshArray); tmp->connections = (int *)DXGetArrayData(tmp->connectionArray); tmp->nmeshes = nStrips; tmp->nconnections = nStrippedPts; priv = (Private)DXNewPrivate((Pointer)tmp, _deleteQMesh); if (! priv) goto error; *mesh = tmp; *o = (dxObject)priv; return OK; error: if (tmp) { if (tmp->connectionArray) DXDelete((dxObject)tmp->connectionArray); if (tmp->meshArray) DXDelete((dxObject)tmp->meshArray); DXFree((Pointer)tmp); } return ERROR; }
Error _dxf_polylinesToPlines (xfieldT *xf) { int i; int start, end, knt; int *mesh; ENTRY(("_dxf_linesToPlines(0x%x)", xf)); /* allocate permanent xfield pline data of appropriate size */ /* Allocations are a guess based on 100 lines/polyline */ if (!(xf->meshes = DXNewArray(TYPE_INT, CATEGORY_REAL, 1, 2)) || !(DXAllocateArray (xf->meshes, xf->npolylines))) { PRINT(("could not allocate xfield mesh data")); DXErrorGoto(ERROR_NO_MEMORY, "#13000") ; } mesh = (int *)DXGetArrayData(xf->meshes); for (i = 0; i < xf->npolylines; i++) { start = xf->polylines[i]; end = (i+1 == xf->npolylines) ? xf->nedges : xf->polylines[i+1]; knt = end - start; if(xf->invCntns && !DXIsElementValid(xf->invCntns,i)) continue; *mesh++ = start; *mesh++ = knt; } xf->connections_array = (Array)DXReference((dxObject)xf->edges); xf->nconnections = xf->nedges; xf->nmeshes = xf->npolylines; /* record connection info */ xf->posPerConn = 1 ; xf->connectionType = ct_pline; EXIT(("OK")); return OK ; error: if(xf->meshes) DXDelete((dxObject)xf->meshes); EXIT(("ERROR")); return 0 ; }
/* * in: 0 = input * (1) = component name * * out: 0 = avg * 1 = std * 2 = var * 3 = min * 4 = max */ int m_Statistics(Object *in, Object *out) { float min, max, avg, stddev, var; double dvar; if (!in[0]) { DXSetError(ERROR_BAD_PARAMETER, "#10000", "input"); return ERROR; } if (!DXStatistics(in[0], "data", &min, &max, &avg, &stddev)) return ERROR; out[0] = (Object)DXNewArray(TYPE_FLOAT, CATEGORY_REAL, 0); if (!out[0] || !DXAddArrayData((Array)out[0], 0, 1, (Pointer)&avg)) goto error; out[1] = (Object)DXNewArray(TYPE_FLOAT, CATEGORY_REAL, 0); if (!out[1] || !DXAddArrayData((Array)out[1], 0, 1, (Pointer)&stddev)) goto error; dvar = (double)stddev * stddev; if (dvar > DXD_MAX_FLOAT) { out[2] = (Object)DXNewArray(TYPE_DOUBLE, CATEGORY_REAL, 0); if (!out[2] || !DXAddArrayData((Array)out[2], 0, 1, (Pointer)&dvar)) goto error; } else { var = (float)dvar; out[2] = (Object)DXNewArray(TYPE_FLOAT, CATEGORY_REAL, 0); if (!out[2] || !DXAddArrayData((Array)out[2], 0, 1, (Pointer)&var)) goto error; } out[3] = (Object)DXNewArray(TYPE_FLOAT, CATEGORY_REAL, 0); if (!out[3] || !DXAddArrayData((Array)out[3], 0, 1, (Pointer)&min)) goto error; out[4] = (Object)DXNewArray(TYPE_FLOAT, CATEGORY_REAL, 0); if (!out[4] || !DXAddArrayData((Array)out[4], 0, 1, (Pointer)&max)) goto error; return OK; error: DXDelete(out[0]); out[0] = NULL; DXDelete(out[1]); out[1] = NULL; DXDelete(out[2]); out[2] = NULL; DXDelete(out[3]); out[3] = NULL; DXDelete(out[4]); out[4] = NULL; return ERROR; }
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; }
/* item[n] = start + n * delta */ static Array MakeLinearList(Array start, Array end, int *n, Array delta) { int i, j; Array a_start = NULL, a_end = NULL, a_delta = NULL; int delstart = 0, delend = 0, deldelta = 0; Array alist[3]; Array output = NULL; int count = 1; int bytes; Type t; Category c; int rank; int shape[MAXSHAPE]; int nitems; int i_start, i_end, i_delta; float f_start, f_end, f_delta, f_count; Pointer dp; int *ip; Object in[MAXCOMPINPUTS]; /* hardcoded in compute */ Object out; String compstr = NULL; char cbuf[64]; Error rc; /* do this or die in compute */ for (i=0; i<MAXCOMPINPUTS; i++) in[i] = NULL; /* find common format of start, end, delta and check for 4 parms */ i = 0; if (start) alist[i++] = start; if (end) alist[i++] = end; if (delta) alist[i++] = delta; if (n) { count = *n; if (i == 3) { DXWarning("too many inputs specified; ignoring delta"); i--; delta = NULL; } } else if (i == 2) count = 2; if (i < 2) { DXSetError(ERROR_BAD_PARAMETER, "not enough inputs specified to generate a list"); return NULL; } if (!DXQueryArrayCommonV(&t, &c, &rank, shape, i, alist)) { DXAddMessage("start, end and/or delta"); return NULL; } /* shortcut the process here if the data is scalar integer or * scalar float. otherwise, if the data is vector or ubyte * or whatever, fall through and use Compute so we can increment * by irregular values. */ if (t != TYPE_INT && t != TYPE_FLOAT) goto complicated; if (c != CATEGORY_REAL || rank != 0) goto complicated; /* compute missing value(s): * start = end - ((count - 1) * delta) * end = start + ((count - 1) * delta) * count = ((end - start) / delta) + 1 * delta = (end - start) / (count - 1) */ /* convert to the common format */ if (start) a_start = DXArrayConvertV(start, t, c, rank, shape); if (end) a_end = DXArrayConvertV(end, t, c, rank, shape); if (delta) a_delta = DXArrayConvertV(delta, t, c, rank, shape); /* for integer, scalar lists */ if (t == TYPE_INT) { if (!start) { i_end = *(int *)DXGetArrayData(a_end); i_delta = *(int *)DXGetArrayData(a_delta); i_start = i_end - ((count - 1) * i_delta); } if (!end) { i_start = *(int *)DXGetArrayData(a_start); i_delta = *(int *)DXGetArrayData(a_delta); i_end = i_start + ((count - 1) * i_delta); } if (!delta) { /* if count == 1, generate a zero of the right type. otherwise * divide to figure out the right delta to make count-1 steps * between start and end. it's count-1 because if you want * N numbers between start and end, you have N-1 increments. */ i_start = *(int *)DXGetArrayData(a_start); i_end = *(int *)DXGetArrayData(a_end); if (count == 1) i_delta = 0; else i_delta = (i_end - i_start) / (count - 1); /* try to catch the case where delta ends up being 0 (like * because the inputs are int and the count is larger than * the difference between start and end). allow it to be zero * only if start == end; i suppose if you ask for 10 things * where start == end you should be able to get them. */ if (i_delta == 0 && i_start != i_end) { DXSetError(ERROR_BAD_PARAMETER, "count too large to generate list between start and end"); goto error; } } /* if all three arrays are there, count must be missing */ if (i == 3) { i_start = *(int *)DXGetArrayData(a_start); i_end = *(int *)DXGetArrayData(a_end); i_delta = *(int *)DXGetArrayData(a_delta); if (i_delta == 0) count = 1; else { if ((i_end >= i_start && i_delta > 0) || (i_end < i_start && i_delta < 0)) count = (int)(((double)i_end-i_start) / (double)i_delta) +1; else { if (i_delta < 0) DXSetError(ERROR_BAD_PARAMETER, "delta must be positive if start is less than end"); else DXSetError(ERROR_BAD_PARAMETER, "delta must be negative if end is less than start"); goto error; } } } output = (Array)DXNewRegularArray(TYPE_INT, 1, count, (Pointer)&i_start, (Pointer)&i_delta); } /* for float, scalar lists */ if (t == TYPE_FLOAT) { if (!start) { f_end = *(float *)DXGetArrayData(a_end); f_delta = *(float *)DXGetArrayData(a_delta); f_start = f_end - ((count - 1.0) * f_delta); } if (!end) { f_start = *(float *)DXGetArrayData(a_start); f_delta = *(float *)DXGetArrayData(a_delta); f_end = f_start + ((count - 1.0) * f_delta); } if (!delta) { /* if count == 1, generate a zero of the right type. otherwise * divide to figure out the right delta to make count-1 steps * between start and end. it's count-1 because if you want * N numbers between start and end, you have N-1 increments. */ f_start = *(float *)DXGetArrayData(a_start); f_end = *(float *)DXGetArrayData(a_end); if (count == 1) f_delta = 0.0; else f_delta = (f_end - f_start) / (count - 1.0); /* try to catch the case where delta ends up being 0 (like * because the inputs are int and the count is larger than * the difference between start and end). allow it to be zero * only if start == end; i suppose if you ask for 10 things * where start == end you should be able to get them. */ if (f_delta == 0.0 && f_start != f_end) { DXSetError(ERROR_BAD_PARAMETER, "count too large to generate list between start and end"); goto error; } } /* if all three arrays are there, count must be missing */ if (i == 3) { f_start = *(float *)DXGetArrayData(a_start); f_end = *(float *)DXGetArrayData(a_end); f_delta = *(float *)DXGetArrayData(a_delta); if (f_delta == 0.0) count = 1; else { if ((f_end >= f_start && f_delta > 0) || (f_end < f_start && f_delta < 0)) { /* the intermediate float variable below is to minimize * float round-off error. if delta is 0.1 and you * ask for a list between 0 and 1, it does the math in * double, the delta used is actually 0.10000001, and * you get counts = 10.9999999 instead of 11. when * converted directly to int it becomes just 10 and your * list ends at 0.9 instead of 1. * math in base 2 has some problems. */ f_count = ((f_end - f_start) / f_delta) +1; count = (int)f_count; } else { if (f_delta < 0) DXSetError(ERROR_BAD_PARAMETER, "delta must be positive if start is less than end"); else DXSetError(ERROR_BAD_PARAMETER, "delta must be negative if end is less than start"); goto error; } } } output = (Array)DXNewRegularArray(TYPE_FLOAT, 1, count, (Pointer)&f_start, (Pointer)&f_delta); } DXDelete((Object)a_start); DXDelete((Object)a_end); DXDelete((Object)a_delta); /* return Array */ return output; /* input is a vector, or a data type different from int or float. * use compute so this code doesn't have to be replicated for each * different shape and type. */ complicated: nitems = 1; for (j=0; j<rank; j++) nitems *= shape[j]; /* compute missing value(s): * start = end - ((count - 1) * delta) * end = start + ((count - 1) * delta) * count = ((end - start) / delta) + 1 * delta = (end - start) / (count - 1) */ if (!start) { compstr = DXNewString("$0 - (($1 - 1) * $2)"); if (!compstr) goto error; in[0] = (Object)compstr; in[1] = (Object)end; in[3] = (Object)delta; in[2] = (Object)DXNewArray(TYPE_INT, CATEGORY_REAL, 0); if (!in[2]) goto error; if (!DXAddArrayData((Array)in[2], 0, 1, (Pointer)&count)) goto error; /* i need to explain this - it's basically so if compute was * going to try to cache this, it could add a reference and * then later when i call delete the object won't get deleted * out from underneath compute. (i know compute doesn't cache * things, but a different module might.) */ DXReference((Object)compstr); DXReference(in[2]); rc = m_Compute(in, &out); DXDelete((Object)compstr); compstr = NULL; DXDelete(in[2]); in[2] = NULL; if (rc == ERROR) goto error; start = (Array)out; delstart++; } if (!end) { compstr = DXNewString("$0 + (($1 - 1) * $2)"); if (!compstr) goto error; in[0] = (Object)compstr; in[1] = (Object)start; in[3] = (Object)delta; in[2] = (Object)DXNewArray(TYPE_INT, CATEGORY_REAL, 0); if (!in[2]) goto error; if (!DXAddArrayData((Array)in[2], 0, 1, (Pointer)&count)) goto error; DXReference((Object)compstr); DXReference(in[2]); rc = m_Compute(in, &out); DXDelete((Object)compstr); compstr = NULL; DXDelete(in[2]); in[2] = NULL; if (rc == ERROR) goto error; end = (Array)out; delend++; } if (!delta) { /* if count == 1, generate a zero of the right type. otherwise * divide to figure out the right delta to make count-1 steps * between start and end. it's count-1 because if you want * N numbers between start and end, you have N-1 increments. */ if (count == 1) compstr = DXNewString("$1 - $1"); else compstr = DXNewString("($2 - $0) / ($1 - 1)"); if (!compstr) goto error; in[0] = (Object)compstr; in[1] = (Object)start; in[3] = (Object)end; in[2] = (Object)DXNewArray(TYPE_INT, CATEGORY_REAL, 0); if (!in[2]) goto error; if (!DXAddArrayData((Array)in[2], 0, 1, (Pointer)&count)) goto error; DXReference((Object)compstr); DXReference(in[2]); rc = m_Compute(in, &out); DXDelete((Object)compstr); compstr = NULL; DXDelete(in[2]); in[2] = NULL; if (rc == ERROR) goto error; delta = (Array)out; deldelta++; /* try to catch the case where delta ends up being 0 (like * because the inputs are int and the count is larger than * the difference between start and end). allow it to be zero * only if start == end; i suppose if you ask for 10 things * where start == end you should be able to get them. */ if (IsZero(delta) && !IsEqual(start, end)) { DXSetError(ERROR_BAD_PARAMETER, "count too large to generate list between start and end"); goto error; } } /* if all three arrays are there, count must be missing */ if (i == 3) { char tbuf[512]; int firsttime = 1; int lastcount = 0; /* this loop allows us to to handle vectors or matricies as * well as scalars. it requires that the deltas compute to * a consistent count. like start=[0 2 4], end=[4 8 16], * would work if delta=[1 2 4] but not if delta was [1 2 2]. */ for (j=0; j < nitems; j++) { /* i think this code only works for vectors - i'm not sure * what it will do with rank=2 data. */ /* this point of this next compute expression: * if the delta is 0, don't divide by zero - the count is 1. * if the end is smaller than the start, the delta has to be * negative. if it's not, return -1. you can't generate a * negative count from the equations, so this is a safe signal. */ sprintf(tbuf, "float($2.%d) == 0.0 ? " " 1 : " " ( (($1.%d >= $0.%d) && ($2.%d > 0) || " " ($1.%d < $0.%d) && ($2.%d < 0)) ? " " int(float($1.%d - $0.%d) / float($2.%d)) + 1 : " " -1 ) ", j, j, j, j, j, j, j, j, j, j); compstr = DXNewString(tbuf); if (!compstr) goto error; in[0] = (Object)compstr; in[1] = (Object)start; in[2] = (Object)end; in[3] = (Object)delta; DXReference((Object)compstr); rc = m_Compute(in, &out); DXDelete((Object)compstr); compstr = NULL; if (rc == ERROR) goto error; if (!DXExtractInteger(out, &count)) { DXSetError(ERROR_BAD_PARAMETER, "can't compute number of items"); goto error; } DXDelete((Object)out); if (count == 0) continue; if (count < 0) { if (IsNegative(delta)) DXSetError(ERROR_BAD_PARAMETER, "delta must be positive if start is less than end"); else DXSetError(ERROR_BAD_PARAMETER, "delta must be negative if end is less than start"); goto error; } if (firsttime) { lastcount = count; firsttime = 0; } else { if (count != lastcount) { DXSetError(ERROR_BAD_PARAMETER, "inconsistent number of items required by inputs"); goto error; } } } } /* now have 4 consistant values - once again make sure they are * converted into an identical format. */ a_start = DXArrayConvertV(start, t, c, rank, shape); a_end = DXArrayConvertV(end, t, c, rank, shape); a_delta = DXArrayConvertV(delta, t, c, rank, shape); /* make empty array with n items */ output = DXNewArrayV(t, c, rank, shape); if (!output) goto error; if (!DXAddArrayData(output, 0, count, NULL)) goto error; dp = DXGetArrayData(output); if (!dp) goto error; /* foreach n */ /* call compute to add delta */ /* memcpy to right offset in array */ /* end */ bytes = DXGetItemSize(output); sprintf(cbuf, "%s($0 + ($1 * $2))", TypeName(t)); compstr = DXNewString(cbuf); if (!compstr) goto error; in[0] = (Object)compstr; in[1] = (Object)a_start; in[3] = (Object)a_delta; in[2] = (Object)DXNewArray(TYPE_INT, CATEGORY_REAL, 0); if (!in[2]) goto error; if (!DXAddArrayData((Array)in[2], 0, 1, NULL)) goto error; ip = (int *)DXGetArrayData((Array)in[2]); DXReference((Object)compstr); DXReference(in[2]); for (i=0; i<count; i++) { *ip = i; rc = m_Compute(in, &out); if (rc == ERROR) goto error; memcpy(INCVOID(dp, bytes*i), DXGetArrayData((Array)out), bytes); DXDelete((Object)out); } DXDelete((Object)compstr); DXDelete(in[2]); DXDelete((Object)a_start); DXDelete((Object)a_end); DXDelete((Object)a_delta); if (delstart) DXDelete((Object)start); if (delend) DXDelete((Object)end); if (deldelta) DXDelete((Object)delta); /* return Array */ return output; error: DXDelete((Object)output); DXDelete((Object)compstr); DXDelete((Object)a_start); DXDelete((Object)a_end); DXDelete((Object)a_delta); if (delstart) DXDelete((Object)start); if (delend) DXDelete((Object)end); if (deldelta) DXDelete((Object)delta); return NULL; }
Error _dxf_linesToPlines (xfieldT *xf) { int i; Line *line = NULL,lineScratch; int newEdgeI; Edge edges = NULL; int *polyline = NULL; Array array = NULL; int ptI,lastPtI; int plineOffset,plineIndex; Edge edgePool = NULL; int nextFreeEdge = 0; ENTRY(("_dxf_linesToPlines(0x%x)", xf)); /* allocate permanent xfield pline data of appropriate size */ /* Allocations are a guess based on 100 lines/polyline */ if (!(xf->meshes = DXNewArray (TYPE_INT, CATEGORY_REAL, 1, 2)) || !(DXAllocateArray (xf->meshes, xf->nconnections/100)) || !(array = DXNewArray (TYPE_INT, CATEGORY_REAL, 0)) || !(DXAllocateArray (array, xf->nconnections+xf->nconnections/100)) || !(edgePool = (Edge)DXAllocate(sizeof(EdgeT)*xf->nconnections * 2))) { PRINT(("could not allocate xfield mesh data")); DXErrorGoto(ERROR_NO_MEMORY, "#13000") ; } xf->nmeshes = 0 ; /* get line connection info; lines will be replaced by strips */ xf->origConnections_array = xf->connections_array ; xf->origNConnections = xf->nconnections; if(!(edges = (Edge)DXAllocateZero(xf->npositions * sizeof(EdgeT)))) DXErrorGoto(ERROR_NO_MEMORY, "#13000") ; if (!(polyline = (int *)DXAllocate((xf->nconnections+1) * sizeof(Edge)))) DXErrorGoto(ERROR_NO_MEMORY, "#13000") ; for(i=0;i<xf->nconnections;i++) { if(xf->invCntns && !DXIsElementValid(xf->invCntns,i)) continue; if(!(line = DXGetArrayEntry(xf->connections,i,&lineScratch))) goto error; INSERT_EDGE(i,line->p); INSERT_EDGE(i,line->q); } lastPtI = 0; plineOffset = 0; plineIndex = 0; while (1) { int newPline[2] ; for(ptI=lastPtI;ptI<xf->npositions;ptI++) if((newEdgeI = FIND_EDGE(ptI)) >= 0) break; if(ptI == xf->npositions) break; lastPtI = ptI; while(newEdgeI >= 0) { if(!(line = DXGetArrayEntry(xf->connections,newEdgeI,&lineScratch))) goto error; polyline[plineIndex++] = ptI; DELETE_EDGE(newEdgeI,ptI); ptI = OTHER_PTI(line,ptI); DELETE_EDGE(newEdgeI,ptI); newEdgeI = FIND_EDGE(ptI); } polyline[plineIndex++] = ptI; newPline[0] = plineOffset; newPline[1] = plineIndex; #if defined(DEBUG) if(plineIndex >= 20) histogram[10]++; else histogram[plineIndex/2]++; #endif /* add the pline data to the xfield */ DXAddArrayData (xf->meshes, xf->nmeshes, 1, newPline) ; DXAddArrayData (array, plineOffset, plineIndex, polyline) ; xf->nmeshes++ ; plineOffset += plineIndex; plineIndex = 0; } /* Trim extra storage allocation from arrays */ DXTrim(xf->meshes); DXTrim(array); xf->connections_array = array; xf->nconnections = plineOffset + plineIndex; array = NULL; /* free old array handle and create a new one */ if (!(DXFreeArrayHandle(xf->connections)) || !(xf->connections = DXCreateArrayHandle(xf->connections_array))) { PRINT(("could not create new connections array handle")); DXErrorGoto(ERROR_NO_MEMORY, "#13000") ; } #if 0 DXReference((dxObject)xf->connections_array); DXReference((dxObject)xf->meshes); /* create a new array handleo */ if(!(xf->connections = DXCreateArrayHandle(xf->connections_array))) { PRINT(("could not create new connections array handle")); DXErrorGoto(ERROR_NO_MEMORY, "#13000") ; } #endif /* record connection info */ xf->posPerConn = 1 ; xf->connectionType = ct_pline; #if defined(DEBUG) for(i=0;i<11;i++) PRINT((" %3d",2*i)); PRINT((" >")); for(i=0;i<11;i++) { PRINT((" %3d",histogram[i])); histogram[i] = 0; } #endif DXFree(edgePool); DXFree(edges); DXFree(polyline); EXIT(("OK")); return OK ; error: if(edgePool) DXFree(edgePool); if(edges) DXFree(edges); if(polyline) DXFree(polyline); if(array) DXDelete((dxObject)array); if(xf->meshes) DXDelete((dxObject)xf->meshes); EXIT(("ERROR")); return 0 ; }
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 ); }
static void CaptionKeyStruck(void *data, DXKeyPressEvent *event) { CaptionData sdata = (CaptionData)data; ModuleInput min[2]; ModuleOutput mout[1]; Object caption, strattr, posattr; Object postion; float *xyz; int i, oldl, n, *ptr; char *oldstr; char *newstr; Object obType = NULL; int x = event->x; int y = event->y; char c = event->key; if (sdata->label == NULL) return; caption = DXGetMember((Group)sdata->obj, sdata->label); if (caption) { /* * If there was already a member by that name, make sure its * an appropriate object and get its state attributes. */ obType = DXGetAttribute(caption, "object type"); if (!obType || strcmp(DXGetString((String)obType), "caption")) return; strattr = DXGetAttribute(caption, "string"); posattr = DXGetAttribute(caption, "position"); } else { /* * Otherwise, we'll initialize the state. We'll need an object * type attribute to put on the result (We re-use the one on the * input if there already was a caption) */ obType = (Object)DXNewString("caption"); /* * Initial state is an empty string at the current mouse * position. */ strattr = (Object)DXNewString(""); posattr = (Object)DXNewArray(TYPE_FLOAT, CATEGORY_REAL, 1, 3); DXAddArrayData((Array)posattr, 0, 1, NULL); xyz = (float *)DXGetArrayData((Array)posattr); xyz[0] = ((float)x)/sdata->w; xyz[1] = ((float)(sdata->h - y))/sdata->w; xyz[2] = 0.0; } DXExtractString(strattr, &oldstr); /* * Update the string. */ oldl = strlen(oldstr); if (c == 0x8 /* BACKSPACE */) { if (oldl > 0) { newstr = (char *)DXAllocate(oldl + 1); for (i = 0; i < oldl-1; i++) newstr[i] = oldstr[i]; newstr[oldl-1] = '\0'; } } else { newstr = (char *)DXAllocate(oldl + 2); for (i = 0; i < oldl; i++) newstr[i] = oldstr[i]; newstr[oldl] = c; newstr[oldl+1] = '\0'; } strattr = (Object)DXNewString(newstr); DXReference(strattr); DXReference(posattr); /* * Use CallModule to call the Caption module. This creates the * new caption object. */ DXModSetObjectInput(min+0, "string", strattr); DXModSetObjectInput(min+1, "position", posattr); DXModSetObjectOutput(mout+0, "caption", &caption); DXCallModule("Caption", 2, min, 1, mout); /* * Replace attributes onto caption */ DXSetAttribute(caption, "string", strattr); DXSetAttribute(caption, "position", posattr); DXSetAttribute(caption, "object type", obType); /* * Replace it into scene object group */ DXSetMember((Group)sdata->obj, sdata->label, caption); DXDelete(strattr); DXDelete(posattr); return; }
static void CaptionMouseButton(void *data, DXMouseEvent *event) { Object caption; Object obType; CaptionData sdata = (CaptionData)data; int b = WHICH_BUTTON(event); int x, y; x = event->x; y = event->y; if (sdata->label == NULL) return; /* * Get the member by name. If no caption by this name exists, * there's nothing to move, so we return. */ caption = DXGetMember((Group)sdata->obj, sdata->label); if (! caption) return; /* * Make sure its an appropriate object */ obType = DXGetAttribute(caption, "object type"); if (!obType || strcmp(DXGetString((String)obType), "caption")) return; /* * Only should see left buttons, but check anyway. */ if (b == 0) { ModuleInput min[2]; ModuleOutput mout[1]; Object strattr, posattr; float *xyz; /* * If its a caption object, it better have these attributes. * A little error checking might be called for. */ strattr = DXGetAttribute(caption, "string"); posattr = (Object)DXNewArray(TYPE_FLOAT, CATEGORY_REAL, 1, 3); DXAddArrayData((Array)posattr, 0, 1, NULL); xyz = (float *)DXGetArrayData((Array)posattr); /* * Move to the current position (0-1 space requires the division * by the screen width in pixels. */ xyz[0] = ((float)x)/sdata->w; xyz[1] = ((float)(sdata->h - y))/sdata->w; xyz[2] = 0.0; DXReference(strattr); DXReference(posattr); /* * Use CallModule to call the Caption module. This creates the * new caption object. */ DXModSetObjectInput(min+0, "string", strattr); DXModSetObjectInput(min+1, "position", posattr); DXModSetObjectOutput(mout+0, "caption", &caption); DXCallModule("Caption", 2, min, 1, mout); /* * Replace attributes onto caption */ DXSetAttribute(caption, "string", strattr); DXSetAttribute(caption, "position", posattr); DXSetAttribute(caption, "object type", obType); /* * Replace it into scene object group */ DXSetMember((Group)sdata->obj, sdata->label, caption); DXDelete(strattr); DXDelete(posattr); } return; }
main() { int rcode; ModuleInput minput[MAX_PARAMS]; ModuleOutput moutput[MAX_PARAMS]; float cap_position[] = { 0.5, 0.02}; Array cap_pos_array = NULL; Object caption_out = NULL; Object import_cloud_out = NULL; float iso_value = 0.11; Object isosurface_out = NULL; float color_opacity = 0.3; Object color_out = NULL; Object import_wind_out = NULL; Array grid_pt_array = NULL; float grid_point[] = { 35000, 600, 25000}; Array grid_shape_array = NULL; float grid_shape[] = { 3000, 0, 0, 0, 0, 3000}; int grid_density = 5; Object grid_out = NULL; Object streamline_out = NULL; Object map_out = NULL; Object autocolor_out = NULL; float ribbon_width = 400; Object ribbon_out = NULL; Object options_out = NULL; float spec_value = 0.1; float diffuse_value = 0.9; Object collect_out = NULL; Object autocamera_out = NULL; DXInitModules(); /* This program will exit when the enter key is hit */ DXRegisterInputHandler(exit_handler, STDIN_FILENO, 0) ; /* Caption - setup in/outputs and call module */ DXModSetStringInput(&minput[0], "string", "data courtesy of NCSA, University of Illinois at Urbana-Champaign"); cap_pos_array = DXNewArray(TYPE_FLOAT, CATEGORY_REAL, 1, 2); if (cap_pos_array == NULL) goto error; if (DXAddArrayData(cap_pos_array, 0, 1, cap_position) == NULL) goto error; DXModSetObjectInput(&minput[1], "position", (Object)cap_pos_array); DXModSetObjectOutput(&moutput[0], "caption", &caption_out); rcode = DXCallModule("Caption", 2, minput, 1, moutput); if (rcode == ERROR) goto error; /* Import - setup in/outputs and call module */ DXModSetStringInput(&minput[0], "name", "cloudwater"); DXModSetObjectOutput(&moutput[0], "data", &import_cloud_out); rcode = DXCallModule("Import", 1, minput, 1, moutput); if (rcode == ERROR) goto error; /* Isosurface - setup in/outputs and call module */ /* no need to reference import_cloud_out before using it here */ /* because we will not use it again. After this module is */ /* called import_cloud_out will be deleted. */ DXModSetObjectInput(&minput[0], "data", import_cloud_out); DXModSetFloatInput(&minput[1], "value", iso_value); DXModSetObjectOutput(&moutput[0], "surface", &isosurface_out); rcode = DXCallModule("Isosurface", 2, minput, 1, moutput); if (rcode == ERROR) goto error; /* Color - setup in/outputs and call module */ DXModSetObjectInput(&minput[0], "input", isosurface_out); DXModSetStringInput(&minput[1], "color", "light blue"); DXModSetFloatInput(&minput[2], "opacity", color_opacity); DXModSetObjectOutput(&moutput[0], "colored", &color_out); rcode = DXCallModule("Color", 3, minput, 1, moutput); if (rcode == ERROR) goto error; /* Import - setup in/outputs and call module */ DXModSetStringInput(&minput[0], "name", "wind"); DXModSetObjectOutput(&moutput[0], "data", &import_wind_out); rcode = DXCallModule("Import", 1, minput, 1, moutput); if (rcode == ERROR) goto error; /* Grid - setup in/outputs and call module */ grid_pt_array = DXNewArray(TYPE_FLOAT, CATEGORY_REAL, 1, 3); if (grid_pt_array == NULL) goto error; if (DXAddArrayData(grid_pt_array, 0, 1, grid_point) == NULL) goto error; DXModSetObjectInput(&minput[0], "point", (Object)grid_pt_array); DXModSetStringInput(&minput[1], "structure", "ellipse"); grid_shape_array = DXNewArray(TYPE_FLOAT, CATEGORY_REAL, 1, 3); if (grid_shape_array == NULL) goto error; if (DXAddArrayData(grid_shape_array, 0, 2, grid_shape) == NULL) goto error; DXModSetObjectInput(&minput[2], "shape", (Object)grid_shape_array); DXModSetIntegerInput(&minput[3], "density", grid_density); DXModSetObjectOutput(&moutput[0], "grid" , &grid_out); rcode = DXCallModule("Grid", 4, minput, 1, moutput); if (rcode == ERROR) goto error; /* Streamline - setup in/outputs and call module */ DXModSetObjectInput(&minput[0], "data", import_wind_out); DXModSetObjectInput(&minput[1], "start", grid_out); DXModSetIntegerInput(&minput[2], "flag", 1); DXModSetObjectOutput(&moutput[0], "line", &streamline_out); rcode = DXCallModule("Streamline", 3, minput, 1, moutput); if (rcode == ERROR) goto error; /* AutoColor - setup in/outputs and call module */ DXModSetObjectInput(&minput[0], "data", streamline_out); DXModSetObjectInput(&minput[1], "min", streamline_out); DXModSetObjectOutput(&moutput[0], "mapped", &autocolor_out); rcode = DXCallModule("AutoColor", 2, minput, 1, moutput); if (rcode == ERROR) goto error; /* Ribbon - setup in/outputs and call module */ DXModSetObjectInput(&minput[0], "line", autocolor_out); DXModSetFloatInput(&minput[1], "width", ribbon_width); DXModSetObjectOutput(&moutput[0], "ribbon", &ribbon_out); rcode = DXCallModule("Ribbon", 2, minput, 1, moutput); if (rcode == ERROR) goto error; /* Options - setup in/outputs and call module */ DXModSetObjectInput(&minput[0], "input", ribbon_out); DXModSetStringInput(&minput[1], "attribute", "specular"); DXModSetFloatInput(&minput[2], "value", spec_value); DXModSetStringInput(&minput[3], "attribute1", "diffuse"); DXModSetFloatInput(&minput[4], "value1", diffuse_value); DXModSetObjectOutput(&moutput[0], "output", &options_out); rcode = DXCallModule("Options", 5, minput, 1, moutput); if (rcode == ERROR) goto error; /* Collect - setup in/outputs and call module */ DXModSetObjectInput(&minput[0], "object", caption_out); DXModSetObjectInput(&minput[1], "object1", color_out); DXModSetObjectInput(&minput[2], "object2", options_out); DXModSetObjectOutput(&moutput[0], "group", &collect_out); rcode = DXCallModule("Collect", 3, minput, 1, moutput); if (rcode == ERROR) goto error; /* AutoCamera - setup in/outputs and call module */ /* We need to reference collect_out because we will use */ /* it again in the call to Display */ DXReference(collect_out); DXModSetObjectInput(&minput[0], "object", collect_out); DXModSetObjectOutput(&moutput[0], "camera", &autocamera_out); rcode = DXCallModule("AutoCamera", 1, minput, 1, moutput); if (rcode == ERROR) goto error; /* Display - setup in/outputs and call module */ DXModSetObjectInput(&minput[0], "object", collect_out); DXModSetObjectInput(&minput[1], "camera", autocamera_out); rcode = DXCallModule("Display", 2, minput, 0, moutput); if (rcode == ERROR) goto error; fprintf(stderr, "Hit the enter key to exit: "); while(1) { DXCheckRIH(1); } error: exit (-1); }
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; }
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; }
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; }
/* return outputs from module asynchronously */ Error DXSetOutputs(Object *olist, int dxfd) { static int firsttime = 1; Array oarr; Error ret = ERROR; ErrorCode ecode; Group iobj = NULL; Group oobj = NULL; Array code = NULL; String mess = NULL; int i; int count = 0; int one = 1; int zero = 0; if (firsttime && ! callsetup (dxfd)) { host_status = HOST_CLOSED; return ERROR; } ecode = DXGetError(); /* * 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 (DXGetErrorMessage ()); 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 (ecode == ERROR_NONE) { /* 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 < number_of_outputs; 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 < number_of_outputs; i++) { if (olist[i] == NULL) continue; if (! DXSetEnumeratedMember (oobj, count++, olist[i])) goto finish_up; } } /* if the exec isn't already sitting there waiting for results, * alert it that something is going to come back down the pipe, * wait for it to be called and eat the new inputs, and send * the new outputs. */ if (!in_module) { DXInternalReadyToRun(); iobj = (Group) _dxfImportBin_FP (dxfd); if (iobj == NULL) goto finish_up; DXDelete ((Object)iobj); } 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) oobj); in_module = 0; return ret; }
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; }