home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 8
/
CDASC08.ISO
/
NEWS
/
RADIANCE
/
SRC
/
RT
/
M_CLIP.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-07
|
2KB
|
98 lines
/* Copyright (c) 1986 Regents of the University of California */
#ifndef lint
static char SCCSid[] = "@(#)m_clip.c 2.1 11/12/91 LBL";
#endif
/*
* m_clip.c - routine for clipped (cut) objects.
*
* 3/17/86
*/
#include "ray.h"
/*
* Clipping objects permit holes and sections to be taken out
* of other objects. The method is simple:
*
* The argument is the clipped materials;
* the first is used to shade upon exit.
*/
m_clip(m, r) /* clip objects from ray */
register OBJREC *m;
register RAY *r;
{
OBJECT cset[MAXSET+1], *modset;
int entering;
register int i;
if ((modset = (OBJECT *)m->os) == NULL) {
register OBJECT mod;
if (m->oargs.nsargs < 1 || m->oargs.nsargs > MAXSET)
objerror(m, USER, "bad # arguments");
modset = (OBJECT *)malloc((m->oargs.nsargs+1)*sizeof(OBJECT));
if (modset == NULL)
error(SYSTEM, "out of memory in m_clip");
modset[0] = 0;
for (i = 0; i < m->oargs.nsargs; i++) {
if (!strcmp(m->oargs.sarg[i], VOIDID))
continue;
if ((mod = modifier(m->oargs.sarg[i])) == OVOID) {
sprintf(errmsg, "unknown modifier \"%s\"",
m->oargs.sarg[i]);
objerror(m, WARNING, errmsg);
continue;
}
if (inset(modset, mod)) {
objerror(m, WARNING, "duplicate modifier");
continue;
}
insertelem(modset, mod);
}
m->os = (char *)modset;
}
if (r->clipset != NULL)
setcopy(cset, r->clipset);
else
cset[0] = 0;
entering = r->rod > 0.0; /* entering clipped region? */
for (i = modset[0]; i > 0; i--) {
if (entering) {
if (!inset(cset, modset[i])) {
if (cset[0] >= MAXSET)
error(INTERNAL, "set overflow in m_clip");
insertelem(cset, modset[i]);
}
} else {
if (inset(cset, modset[i]))
deletelem(cset, modset[i]);
}
}
/* compute ray value */
r->newcset = cset;
if (strcmp(m->oargs.sarg[0], VOIDID)) {
int inside = 0;
register RAY *rp;
/* check for penetration */
for (rp = r; rp->parent != NULL; rp = rp->parent)
if (!(rp->rtype & RAYREFL) && rp->parent->ro != NULL
&& inset(modset, rp->parent->ro->omod))
if (rp->parent->rod > 0.0)
inside++;
else
inside--;
if (inside > 0) { /* we just hit the object */
flipsurface(r);
rayshade(r, modifier(m->oargs.sarg[0]));
return;
}
}
raytrans(r); /* else transfer ray */
}