Back to index

radiance  4R0+20100331
m_clip.c
Go to the documentation of this file.
00001 #ifndef lint
00002 static const char    RCSid[] = "$Id: m_clip.c,v 2.10 2007/07/25 04:12:36 greg Exp $";
00003 #endif
00004 /*
00005  *  m_clip.c - routine for clipped (cut) objects.
00006  */
00007 
00008 #include "copyright.h"
00009 
00010 #include  "ray.h"
00011 #include  "rtotypes.h"
00012 
00013 /*
00014  *  Clipping objects permit holes and sections to be taken out
00015  *  of other objects.  The method is simple:  
00016  *
00017  *  The argument is the clipped materials;
00018  *  the first is used to shade upon exit.
00019  */
00020 
00021 
00022 extern int
00023 m_clip(                     /* clip objects from ray */
00024        register OBJREC  *m,
00025        register RAY  *r
00026 )
00027 {
00028        OBJECT  cset[MAXSET+1], *modset;
00029        OBJECT  obj, mod;
00030        int  entering;
00031        register int  i;
00032 
00033        obj = objndx(m);
00034        if ((modset = (OBJECT *)m->os) == NULL) {
00035               if (m->oargs.nsargs < 1 || m->oargs.nsargs > MAXSET)
00036                      objerror(m, USER, "bad # arguments");
00037               modset = (OBJECT *)malloc((m->oargs.nsargs+1)*sizeof(OBJECT));
00038               if (modset == NULL)
00039                      error(SYSTEM, "out of memory in m_clip");
00040               modset[0] = 0;
00041               for (i = 0; i < m->oargs.nsargs; i++) {
00042                      if (!strcmp(m->oargs.sarg[i], VOIDID))
00043                             continue;
00044                      if ((mod = lastmod(obj, m->oargs.sarg[i])) == OVOID) {
00045                             sprintf(errmsg, "unknown modifier \"%s\"",
00046                                           m->oargs.sarg[i]);
00047                             objerror(m, WARNING, errmsg);
00048                             continue;
00049                      }
00050                      if (inset(modset, mod)) {
00051                             objerror(m, WARNING, "duplicate modifier");
00052                             continue;
00053                      }
00054                      insertelem(modset, mod);
00055               }
00056               m->os = (char *)modset;
00057        }
00058        if (r == NULL)
00059               return(0);                  /* just initializing */
00060        if (r->clipset != NULL)
00061               setcopy(cset, r->clipset);
00062        else
00063               cset[0] = 0;
00064 
00065        entering = r->rod > 0.0;           /* entering clipped region? */
00066 
00067        for (i = modset[0]; i > 0; i--) {
00068               if (entering) {
00069                      if (!inset(cset, modset[i])) {
00070                             if (cset[0] >= MAXSET)
00071                                    error(INTERNAL, "set overflow in m_clip");
00072                             insertelem(cset, modset[i]);
00073                      }
00074               } else {
00075                      if (inset(cset, modset[i]))
00076                             deletelem(cset, modset[i]);
00077               }
00078        }
00079                                    /* compute ray value */
00080        r->newcset = cset;
00081        if (strcmp(m->oargs.sarg[0], VOIDID)) {
00082               int  inside = 0;
00083               register const RAY  *rp;
00084                                    /* check for penetration */
00085               for (rp = r; rp->parent != NULL; rp = rp->parent)
00086                      if (!(rp->rtype & RAYREFL) && rp->parent->ro != NULL
00087                                    && inset(modset, rp->parent->ro->omod)) {
00088                             if (rp->parent->rod > 0.0)
00089                                    inside++;
00090                             else
00091                                    inside--;
00092                      }
00093               if (inside > 0) {    /* we just hit the object */
00094                      flipsurface(r);
00095                      return(rayshade(r, lastmod(obj, m->oargs.sarg[0])));
00096               }
00097        }
00098        raytrans(r);                /* else transfer ray */
00099        return(1);
00100 }