void gageShapeBoundingBox(double min[3], double max[3], const gageShape *shape) { /* static const char me[]="gageShapeBoundingBox"; */ double minIdx[3], maxIdx[3], cornerIdx[8][3], tmp[3]; unsigned int ii; if (!( min && max && shape )) { return; } if (nrrdCenterNode == shape->center) { ELL_3V_SET(minIdx, 0, 0, 0); ELL_3V_SET(maxIdx, shape->size[0]-1, shape->size[1]-1, shape->size[2]-1); } else { ELL_3V_SET(minIdx, -0.5, -0.5, -0.5); ELL_3V_SET(maxIdx, shape->size[0]-0.5, shape->size[1]-0.5, shape->size[2]-0.5); } ELL_3V_SET(cornerIdx[0], minIdx[0], minIdx[1], minIdx[2]); ELL_3V_SET(cornerIdx[1], maxIdx[0], minIdx[1], minIdx[2]); ELL_3V_SET(cornerIdx[2], minIdx[0], maxIdx[1], minIdx[2]); ELL_3V_SET(cornerIdx[3], maxIdx[0], maxIdx[1], minIdx[2]); ELL_3V_SET(cornerIdx[4], minIdx[0], minIdx[1], maxIdx[2]); ELL_3V_SET(cornerIdx[5], maxIdx[0], minIdx[1], maxIdx[2]); ELL_3V_SET(cornerIdx[6], minIdx[0], maxIdx[1], maxIdx[2]); ELL_3V_SET(cornerIdx[7], maxIdx[0], maxIdx[1], maxIdx[2]); gageShapeItoW(shape, tmp, cornerIdx[0]); ELL_3V_COPY(min, tmp); ELL_3V_COPY(max, tmp); for (ii=1; ii<8; ii++) { gageShapeItoW(shape, tmp, cornerIdx[ii]); ELL_3V_MIN(min, min, tmp); ELL_3V_MAX(max, max, tmp); } return; }
/* ******** echoTriMeshSet() ** ** This has to be called any time that the locations of the points are ** changing, even if the connectivity is not changed, because of how ** the bounding box and mean vert position is calculated here. ** ** NB: the TriMesh will directly use the given pos[] and vert[] arrays, ** so don't go freeing them after they've been passed here. */ void echoTriMeshSet(echoObject *trim, int numV, echoPos_t *pos, int numF, int *vert) { int i; if (trim && echoTypeTriMesh == trim->type) { TRIMESH(trim)->numV = numV; TRIMESH(trim)->numF = numF; TRIMESH(trim)->pos = pos; TRIMESH(trim)->vert = vert; ELL_3V_SET(TRIMESH(trim)->min, ECHO_POS_MAX, ECHO_POS_MAX, ECHO_POS_MAX); ELL_3V_SET(TRIMESH(trim)->max, ECHO_POS_MIN, ECHO_POS_MIN, ECHO_POS_MIN); ELL_3V_SET(TRIMESH(trim)->meanvert, 0.0, 0.0, 0.0); for (i=0; i<numV; i++) { ELL_3V_MIN(TRIMESH(trim)->min, TRIMESH(trim)->min, pos + 3*i); ELL_3V_MAX(TRIMESH(trim)->max, TRIMESH(trim)->max, pos + 3*i); ELL_3V_INCR(TRIMESH(trim)->meanvert, pos + 3*i); } ELL_3V_SCALE(TRIMESH(trim)->meanvert, 1.0/numV, TRIMESH(trim)->meanvert); } return; }
/* ******** echoListSplit() ** ** returns a echoObjectSplit to point to the same things as pointed ** to by the given echoObjectList */ echoObject * echoListSplit(echoScene *scene, echoObject *list, int axis) { echoPos_t lo[3], hi[3], loest0[3], hiest0[3], loest1[3], hiest1[3]; double *mids; echoObject *o, *split, *list0, *list1; int i, splitIdx, len; if (!( echoTypeList == list->type || echoTypeAABBox == list->type )) { return list; } len = LIST(list)->objArr->len; if (len <= ECHO_LEN_SMALL_ENOUGH) { /* there is nothing or only one object */ return list; } split = echoObjectNew(scene, echoTypeSplit); list0 = echoObjectNew(scene, echoTypeList); list1 = echoObjectNew(scene, echoTypeList); SPLIT(split)->axis = axis; SPLIT(split)->obj0 = list0; SPLIT(split)->obj1 = list1; mids = (double *)malloc(2 * len * sizeof(double)); for (i=0; i<len; i++) { o = LIST(list)->obj[i]; echoBoundsGet(lo, hi, o); mids[0 + 2*i] = (lo[axis] + hi[axis])/2; *((unsigned int *)(mids + 1 + 2*i)) = i; } /* overkill, I know, I know */ qsort(mids, len, 2*sizeof(double), (int (*)(const void *, const void *))_echoPosCompare); /* for (i=0; i<len; i++) { printf("%d -> %g\n", i, mids[0 + 2*i]); } */ splitIdx = len/2; /* printf("splitIdx = %d\n", splitIdx); */ ELL_3V_SET(loest0, ECHO_POS_MAX, ECHO_POS_MAX, ECHO_POS_MAX); ELL_3V_SET(loest1, ECHO_POS_MAX, ECHO_POS_MAX, ECHO_POS_MAX); ELL_3V_SET(hiest0, ECHO_POS_MIN, ECHO_POS_MIN, ECHO_POS_MIN); ELL_3V_SET(hiest1, ECHO_POS_MIN, ECHO_POS_MIN, ECHO_POS_MIN); airArrayLenSet(LIST(list0)->objArr, splitIdx); for (i=0; i<splitIdx; i++) { o = LIST(list)->obj[*((unsigned int *)(mids + 1 + 2*i))]; LIST(list0)->obj[i] = o; echoBoundsGet(lo, hi, o); /* printf("000 lo = (%g,%g,%g), hi = (%g,%g,%g)\n", lo[0], lo[1], lo[2], hi[0], hi[1], hi[2]); */ ELL_3V_MIN(loest0, loest0, lo); ELL_3V_MAX(hiest0, hiest0, hi); } airArrayLenSet(LIST(list1)->objArr, len-splitIdx); for (i=splitIdx; i<len; i++) { o = LIST(list)->obj[*((unsigned int *)(mids + 1 + 2*i))]; LIST(list1)->obj[i-splitIdx] = o; echoBoundsGet(lo, hi, o); /* printf("111 lo = (%g,%g,%g), hi = (%g,%g,%g)\n", lo[0], lo[1], lo[2], hi[0], hi[1], hi[2]); */ ELL_3V_MIN(loest1, loest1, lo); ELL_3V_MAX(hiest1, hiest1, hi); } /* printf("0: loest = (%g,%g,%g); hiest = (%g,%g,%g)\n", loest0[0], loest0[1], loest0[2], hiest0[0], hiest0[1], hiest0[2]); printf("1: loest = (%g,%g,%g); hiest = (%g,%g,%g)\n", loest1[0], loest1[1], loest1[2], hiest1[0], hiest1[1], hiest1[2]); */ ELL_3V_COPY(SPLIT(split)->min0, loest0); ELL_3V_COPY(SPLIT(split)->max0, hiest0); ELL_3V_COPY(SPLIT(split)->min1, loest1); ELL_3V_COPY(SPLIT(split)->max1, hiest1); /* we can't delete the list object here, we just gut it so that there's nothing substantial left of it */ airArrayLenSet(LIST(list)->objArr, 0); mids = (double *)airFree(mids); return split; }