home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 8 / CDASC08.ISO / NEWS / RADIANCE / SRC / RT / M_CLIP.C < prev    next >
C/C++ Source or Header  |  1993-10-07  |  2KB  |  98 lines

  1. /* Copyright (c) 1986 Regents of the University of California */
  2.  
  3. #ifndef lint
  4. static char SCCSid[] = "@(#)m_clip.c 2.1 11/12/91 LBL";
  5. #endif
  6.  
  7. /*
  8.  *  m_clip.c - routine for clipped (cut) objects.
  9.  *
  10.  *     3/17/86
  11.  */
  12.  
  13. #include  "ray.h"
  14.  
  15. /*
  16.  *  Clipping objects permit holes and sections to be taken out
  17.  *  of other objects.  The method is simple:  
  18.  *
  19.  *  The argument is the clipped materials;
  20.  *  the first is used to shade upon exit.
  21.  */
  22.  
  23.  
  24. m_clip(m, r)            /* clip objects from ray */
  25. register OBJREC  *m;
  26. register RAY  *r;
  27. {
  28.     OBJECT  cset[MAXSET+1], *modset;
  29.     int  entering;
  30.     register int  i;
  31.  
  32.     if ((modset = (OBJECT *)m->os) == NULL) {
  33.         register OBJECT  mod;
  34.  
  35.         if (m->oargs.nsargs < 1 || m->oargs.nsargs > MAXSET)
  36.             objerror(m, USER, "bad # arguments");
  37.         modset = (OBJECT *)malloc((m->oargs.nsargs+1)*sizeof(OBJECT));
  38.         if (modset == NULL)
  39.             error(SYSTEM, "out of memory in m_clip");
  40.         modset[0] = 0;
  41.         for (i = 0; i < m->oargs.nsargs; i++) {
  42.             if (!strcmp(m->oargs.sarg[i], VOIDID))
  43.                 continue;
  44.             if ((mod = modifier(m->oargs.sarg[i])) == OVOID) {
  45.                 sprintf(errmsg, "unknown modifier \"%s\"",
  46.                         m->oargs.sarg[i]);
  47.                 objerror(m, WARNING, errmsg);
  48.                 continue;
  49.             }
  50.             if (inset(modset, mod)) {
  51.                 objerror(m, WARNING, "duplicate modifier");
  52.                 continue;
  53.             }
  54.             insertelem(modset, mod);
  55.         }
  56.         m->os = (char *)modset;
  57.     }
  58.     if (r->clipset != NULL)
  59.         setcopy(cset, r->clipset);
  60.     else
  61.         cset[0] = 0;
  62.  
  63.     entering = r->rod > 0.0;        /* entering clipped region? */
  64.  
  65.     for (i = modset[0]; i > 0; i--) {
  66.         if (entering) {
  67.             if (!inset(cset, modset[i])) {
  68.                 if (cset[0] >= MAXSET)
  69.                     error(INTERNAL, "set overflow in m_clip");
  70.                 insertelem(cset, modset[i]);
  71.             }
  72.         } else {
  73.             if (inset(cset, modset[i]))
  74.                 deletelem(cset, modset[i]);
  75.         }
  76.     }
  77.                     /* compute ray value */
  78.     r->newcset = cset;
  79.     if (strcmp(m->oargs.sarg[0], VOIDID)) {
  80.         int  inside = 0;
  81.         register RAY  *rp;
  82.                     /* check for penetration */
  83.         for (rp = r; rp->parent != NULL; rp = rp->parent)
  84.             if (!(rp->rtype & RAYREFL) && rp->parent->ro != NULL
  85.                     && inset(modset, rp->parent->ro->omod))
  86.                 if (rp->parent->rod > 0.0)
  87.                     inside++;
  88.                 else
  89.                     inside--;
  90.         if (inside > 0) {    /* we just hit the object */
  91.             flipsurface(r);
  92.             rayshade(r, modifier(m->oargs.sarg[0]));
  93.             return;
  94.         }
  95.     }
  96.     raytrans(r);            /* else transfer ray */
  97. }
  98.