static void add2full( /* add object to full node */ register CUBE *cu, OBJECT obj ) { OCTREE ot; OBJECT oset[MAXSET+1]; CUBE cukid; register int i, j; objset(oset, cu->cutree); cukid.cusize = cu->cusize * 0.5; if (oset[0] < objlim || cukid.cusize < (oset[0] < MAXSET ? mincusize : mincusize/256.0)) { /* add to set */ if (oset[0] >= MAXSET) { sprintf(errmsg, "set overflow in addobject (%s)", objptr(obj)->oname); error(INTERNAL, errmsg); } insertelem(oset, obj); cu->cutree = fullnode(oset); return; } /* subdivide cube */ if ((ot = octalloc()) == EMPTY) error(SYSTEM, "out of octree space"); /* assign subcubes */ for (i = 0; i < 8; i++) { cukid.cutree = EMPTY; for (j = 0; j < 3; j++) { cukid.cuorg[j] = cu->cuorg[j]; if ((1<<j) & i) cukid.cuorg[j] += cukid.cusize; } for (j = 1; j <= oset[0]; j++) addface(&cukid, oset[j]); addface(&cukid, obj); /* returned node */ octkid(ot, i) = cukid.cutree; } cu->cutree = ot; }
static OCTREE gettree() /* get a pre-ordered octree */ { register OCTREE ot; register int i; switch (getc(infp)) { case OT_EMPTY: return(EMPTY); case OT_FULL: return(getfullnode()); case OT_TREE: if ((ot = octalloc()) == EMPTY) octerror(SYSTEM, "out of tree space in gettree"); for (i = 0; i < 8; i++) octkid(ot, i) = gettree(); return(ot); case EOF: octerror(USER, "truncated octree"); default: octerror(USER, "damaged octree"); } return EMPTY; /* pro forma return */ }
static void add2full( /* add object to full node */ register CUBE *cu, OBJECT obj, int inc ) { OCTREE ot; OBJECT oset[MAXSET+1]; CUBE cukid; unsigned char inflg[(MAXSET+7)/8], volflg[(MAXSET+7)/8]; register int i, j; objset(oset, cu->cutree); cukid.cusize = cu->cusize * 0.5; if (inc==O_IN || oset[0] < objlim || cukid.cusize < (oset[0] < MAXSET ? mincusize : mincusize/256.0)) { /* add to set */ if (oset[0] >= MAXSET) { sprintf(errmsg, "set overflow in addobject (%s)", objptr(obj)->oname); error(INTERNAL, errmsg); } insertelem(oset, obj); cu->cutree = fullnode(oset); return; } /* subdivide cube */ if ((ot = octalloc()) == EMPTY) error(SYSTEM, "out of octree space"); /* mark volumes */ j = (oset[0]+7)>>3; while (j--) volflg[j] = inflg[j] = 0; for (j = 1; j <= oset[0]; j++) if (isvolume(objptr(oset[j])->otype)) { setbit(volflg,j-1); if ((*ofun[objptr(oset[j])->otype].funp) (objptr(oset[j]), cu) == O_IN) setbit(inflg,j-1); } /* assign subcubes */ for (i = 0; i < 8; i++) { cukid.cutree = EMPTY; for (j = 0; j < 3; j++) { cukid.cuorg[j] = cu->cuorg[j]; if ((1<<j) & i) cukid.cuorg[j] += cukid.cusize; } /* surfaces first */ for (j = 1; j <= oset[0]; j++) if (!tstbit(volflg,j-1)) addobject(&cukid, oset[j]); /* then this object */ addobject(&cukid, obj); /* then partial volumes */ for (j = 1; j <= oset[0]; j++) if (tstbit(volflg,j-1) && !tstbit(inflg,j-1)) addobject(&cukid, oset[j]); /* full volumes last */ for (j = 1; j <= oset[0]; j++) if (tstbit(inflg,j-1)) addobject(&cukid, oset[j]); /* returned node */ octkid(ot, i) = cukid.cutree; } cu->cutree = ot; }