Back to index

radiance  4R0+20100331
Classes | Defines | Typedefs | Functions | Variables
srcdraw.c File Reference
#include "copyright.h"
#include "ray.h"
#include "view.h"
#include "otypes.h"
#include "source.h"

Go to the source code of this file.

Classes

struct  splist

Defines

#define CLIP_ABOVE   1
#define CLIP_BELOW   2
#define CLIP_RIGHT   3
#define CLIP_LEFT   4
#define MAXVERT   10

Typedefs

typedef struct splist SPLIST

Functions

static int inregion (RREAL p[2], double cv, int crit)
static void clipregion (RREAL a[2], RREAL b[2], double cv, int crit, RREAL r[2])
static int hp_clip_poly (RREAL vl[][2], int nv, double cv, int crit, RREAL vlo[][2])
static int box_clip_poly (RREAL vl[MAXVERT][2], int nv, double xl, double xr, double yb, double ya, RREAL vlo[MAXVERT][2])
static double minw2 (RREAL vl[][2], int nv, double ar2)
static void convex_center (RREAL vl[][2], int nv, RREAL cv[2])
static double poly_area (RREAL vl[][2], int nv)
static int convex_hull (RREAL vl[][2], int nv, RREAL vlo[][2])
static void spinsert (int sn, RREAL vl[][2], int nv)
static int sourcepoly (int sn, RREAL sp[MAXVERT][2])
static void clipregion (register RREAL a[2], register RREAL b[2], double cv, int crit, RREAL r[2])
static void convex_center (register RREAL vl[][2], int nv, RREAL cv[2])
static double poly_area (register RREAL vl[][2], int nv)
void init_drawsources (int rad)
void drawsources (COLOR *pic[], float *zbf[], int x0, int xsiz, int y0, int ysiz)

Variables

static const char RCSid [] = "$Id: srcdraw.c,v 2.16 2005/04/19 01:15:07 greg Exp $"
VIEW ourview
int hres
int vres
static SPLISTsphead = NULL

Class Documentation

struct splist

Definition at line 25 of file srcdraw.c.

Collaboration diagram for splist:
Class Members
struct splist * next
short nv
int sn
RREAL vl

Define Documentation

#define CLIP_ABOVE   1

Definition at line 18 of file srcdraw.c.

#define CLIP_BELOW   2

Definition at line 19 of file srcdraw.c.

#define CLIP_LEFT   4

Definition at line 21 of file srcdraw.c.

#define CLIP_RIGHT   3

Definition at line 20 of file srcdraw.c.

#define MAXVERT   10

Definition at line 23 of file srcdraw.c.


Typedef Documentation

typedef struct splist SPLIST

Function Documentation

static int box_clip_poly ( RREAL  vl[MAXVERT][2],
int  nv,
double  xl,
double  xr,
double  yb,
double  ya,
RREAL  vlo[MAXVERT][2] 
) [static]

Definition at line 124 of file srcdraw.c.

{
       RREAL  vlt[MAXVERT][2];
       int    nvt, nvo;

       nvt = hp_clip_poly(vl, nv, yb, CLIP_BELOW, vlt);
       nvo = hp_clip_poly(vlt, nvt, ya, CLIP_ABOVE, vlo);
       nvt = hp_clip_poly(vlo, nvo, xl, CLIP_LEFT, vlt);
       nvo = hp_clip_poly(vlt, nvt, xr, CLIP_RIGHT, vlo);

       return(nvo);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void clipregion ( RREAL  a[2],
RREAL  b[2],
double  cv,
int  crit,
RREAL  r[2] 
) [static]

Here is the caller graph for this function:

static void clipregion ( register RREAL  a[2],
register RREAL  b[2],
double  cv,
int  crit,
RREAL  r[2] 
) [static]

Definition at line 72 of file srcdraw.c.

{
       switch (crit) {
       case CLIP_ABOVE:
       case CLIP_BELOW:
              r[1] = cv;
              r[0] = a[0] + (cv-a[1])/(b[1]-a[1])*(b[0]-a[0]);
              return;
       case CLIP_RIGHT:
       case CLIP_LEFT:
              r[0] = cv;
              r[1] = a[1] + (cv-a[0])/(b[0]-a[0])*(b[1]-a[1]);
              return;
       }
}
static void convex_center ( RREAL  vl[][2],
int  nv,
RREAL  cv[2] 
) [static]

Here is the caller graph for this function:

static void convex_center ( register RREAL  vl[][2],
int  nv,
RREAL  cv[2] 
) [static]

Definition at line 181 of file srcdraw.c.

{
       register int  i;
                                   /* simple average (suboptimal) */
       cv[0] = cv[1] = 0.;
       for (i = 0; i < nv; i++) {
              cv[0] += vl[i][0];
              cv[1] += vl[i][1];
       }
       cv[0] /= (double)nv;
       cv[1] /= (double)nv;
}
static int convex_hull ( RREAL  vl[][2],
int  nv,
RREAL  vlo[][2] 
) [static]

Definition at line 223 of file srcdraw.c.

{
       int    nvo, nvt;
       RREAL  vlt[MAXVERT][2];
       double voa, vta;
       register int  i, j;
                                   /* start with original polygon */
       for (i = nvo = nv; i--; ) {
              vlo[i][0] = vl[i][0]; vlo[i][1] = vl[i][1];
       }
       voa = poly_area(vlo, nvo);  /* compute its area */
       for (i = 0; i < nvo; i++) {        /* for each output vertex */
              for (j = 0; j < i; j++) {
                     vlt[j][0] = vlo[j][0]; vlt[j][1] = vlo[j][1];
              }
              nvt = nvo - 1;                     /* make poly w/o vertex */
              for (j = i; j < nvt; j++) {
                     vlt[j][0] = vlo[j+1][0]; vlt[j][1] = vlo[j+1][1];
              }
              vta = poly_area(vlt, nvt);
              if (vta >= voa) {           /* is simpler poly bigger? */
                     voa = vta;                  /* then use it */
                     for (j = nvo = nvt; j--; ) {
                            vlo[j][0] = vlt[j][0]; vlo[j][1] = vlt[j][1];
                     }
                     i--;                        /* next adjust */
              }
       }
       return(nvo);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void drawsources ( COLOR pic[],
float *  zbf[],
int  x0,
int  xsiz,
int  y0,
int  ysiz 
)

Definition at line 396 of file srcdraw.c.

{
       RREAL  spoly[MAXVERT][2], ppoly[MAXVERT][2];
       int    nsv, npv;
       int    xmin, xmax, ymin, ymax, x, y;
       RREAL  cxy[2];
       double w;
       RAY    sr;
       register SPLIST      *sp;
       register int  i;
                                   /* check each source in our list */
       for (sp = sphead; sp != NULL; sp = sp->next) {
                                   /* clip source poly to subimage */
              nsv = box_clip_poly(sp->vl, sp->nv,
                            (double)x0/hres, (double)(x0+xsiz)/hres,
                            (double)y0/vres, (double)(y0+ysiz)/vres, spoly);
              if (!nsv)
                     continue;
                                   /* find common subimage (BBox) */
              xmin = x0 + xsiz; xmax = x0;
              ymin = y0 + ysiz; ymax = y0;
              for (i = 0; i < nsv; i++) {
                     if ((double)xmin/hres > spoly[i][0])
                            xmin = spoly[i][0]*hres + FTINY;
                     if ((double)xmax/hres < spoly[i][0])
                            xmax = spoly[i][0]*hres - FTINY;
                     if ((double)ymin/vres > spoly[i][1])
                            ymin = spoly[i][1]*vres + FTINY;
                     if ((double)ymax/vres < spoly[i][1])
                            ymax = spoly[i][1]*vres - FTINY;
              }
                                   /* evaluate each pixel in BBox */
              for (y = ymin; y <= ymax; y++)
                     for (x = xmin; x <= xmax; x++) {
                                                 /* subarea for pixel */
                            npv = box_clip_poly(spoly, nsv,
                                          (double)x/hres, (x+1.)/hres,
                                          (double)y/vres, (y+1.)/vres,
                                          ppoly);
                            if (!npv)
                                   continue;     /* no overlap */
                            convex_center(ppoly, npv, cxy);
                            if ((sr.rmax = viewray(sr.rorg,sr.rdir,&ourview,
                                          cxy[0],cxy[1])) < -FTINY)
                                   continue;     /* not in view */
                            if (source[sp->sn].sflags & SSPOT &&
                                          spotout(&sr, source[sp->sn].sl.s))
                                   continue;     /* outside spot */
                            rayorigin(&sr, SHADOW, NULL, NULL);
                            sr.rsrc = sp->sn;
                            rayvalue(&sr);              /* compute value */
                            if (bright(sr.rcol) <= FTINY)
                                   continue;     /* missed/blocked */
                                                 /* modify pixel */
                            w = poly_area(ppoly, npv) * hres * vres;
                            if (zbf[y-y0] != NULL &&
                                          sr.rt < 0.99*zbf[y-y0][x-x0]) {
                                   zbf[y-y0][x-x0] = sr.rt;
                            } else if (!bigdiff(sr.rcol, pic[y-y0][x-x0],
                                          0.01)) { /* source sample */
                                   scalecolor(pic[y-y0][x-x0], w);
                                   continue;
                            }
                            scalecolor(sr.rcol, w);
                            scalecolor(pic[y-y0][x-x0], 1.-w);
                            addcolor(pic[y-y0][x-x0], sr.rcol);
                     }
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int hp_clip_poly ( RREAL  vl[][2],
int  nv,
double  cv,
int  crit,
RREAL  vlo[][2] 
) [static]

Definition at line 96 of file srcdraw.c.

{
       RREAL  *s, *p;
       register int  j, nvo;

       s = vl[nv-1];
       nvo = 0;
       for (j = 0; j < nv; j++) {
              p = vl[j];
              if (inregion(p, cv, crit)) {
                     if (!inregion(s, cv, crit))
                            clipregion(s, p, cv, crit, vlo[nvo++]);
                     vlo[nvo][0] = p[0]; vlo[nvo++][1] = p[1];
              } else if (inregion(s, cv, crit))
                     clipregion(s, p, cv, crit, vlo[nvo++]);
              s = p;
       }
       return(nvo);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void init_drawsources ( int  rad)

Definition at line 362 of file srcdraw.c.

{
       RREAL  spoly[MAXVERT][2];
       int    nsv;
       register SPLIST      *sp;
       register int  i;
                                   /* free old source list if one */
       for (sp = sphead; sp != NULL; sp = sphead) {
              sphead = sp->next;
              free((void *)sp);
       }
                                   /* loop through all sources */
       for (i = nsources; i--; ) {
                                   /* skip illum's */
              if (findmaterial(source[i].so)->otype == MAT_ILLUM)
                     continue;
                                   /* compute image polygon for source */
              if (!(nsv = sourcepoly(i, spoly)))
                     continue;
                                   /* clip to image boundaries */
              if (!(nsv = box_clip_poly(spoly, nsv, 0., 1., 0., 1., spoly)))
                     continue;
                                   /* big enough for standard sampling? */
              if (minw2(spoly, nsv, ourview.vn2/ourview.hn2) >
                            (double)rad*rad/hres/hres)
                     continue;
                                   /* OK, add to our list */
              spinsert(i, spoly, nsv);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int inregion ( RREAL  p[2],
double  cv,
int  crit 
) [static]

Definition at line 51 of file srcdraw.c.

{
       switch (crit) {
       case CLIP_ABOVE:
              return(p[1] < cv);
       case CLIP_BELOW:
              return(p[1] >= cv);
       case CLIP_RIGHT:
              return(p[0] < cv);
       case CLIP_LEFT:
              return(p[0] >= cv);
       }
       return(-1);
}

Here is the caller graph for this function:

static double minw2 ( RREAL  vl[][2],
int  nv,
double  ar2 
) [static]

Definition at line 147 of file srcdraw.c.

{
       double d2, w2, w2min, w2max;
       register RREAL       *p0, *p1, *p2;
       int    i, j;
                            /* find minimum for all widths */
       w2min = FHUGE;
       p0 = vl[nv-1];
       for (i = 0; i < nv; i++) {  /* for each edge */
              p1 = vl[i];
              d2 = (p1[0]-p0[0])*(p1[0]-p0[0]) +
                            (p1[1]-p0[1])*(p1[1]-p0[1])*ar2;
              w2max = 0.;          /* find maximum for this side */
              for (j = 1; j < nv-1; j++) {
                     p2 = vl[(i+j)%nv];
                     w2 = (p1[0]-p0[0])*(p2[1]-p0[1]) -
                                   (p1[1]-p0[1])*(p2[0]-p0[0]);
                     w2 = w2*w2*ar2/d2;   /* triangle height squared */
                     if (w2 > w2max)
                            w2max = w2;
              }
              if (w2max < w2min)   /* global min. based on local max.'s */
                     w2min = w2max;
              p0 = p1;
       }
       return(w2min);
}

Here is the caller graph for this function:

static double poly_area ( RREAL  vl[][2],
int  nv 
) [static]

Here is the caller graph for this function:

static double poly_area ( register RREAL  vl[][2],
int  nv 
) [static]

Definition at line 200 of file srcdraw.c.

{
       double a;
       RREAL  v0[2], v1[2];
       register int  i;

       a = 0.;
       v0[0] = vl[1][0] - vl[0][0];
       v0[1] = vl[1][1] - vl[0][1];
       for (i = 2; i < nv; i++) {
              v1[0] = vl[i][0] - vl[0][0];
              v1[1] = vl[i][1] - vl[0][1];
              a += v0[0]*v1[1] - v0[1]*v1[0];
              v0[0] = v1[0]; v0[1] = v1[1];
       }
       return(a * (a >= 0. ? .5 : -.5));
}
static int sourcepoly ( int  sn,
RREAL  sp[MAXVERT][2] 
) [static]

Definition at line 287 of file srcdraw.c.

{
       static short  cubeord[8][6] = {{1,3,2,6,4,5},{0,4,5,7,3,2},
                                    {0,1,3,7,6,4},{0,1,5,7,6,2},
                                    {0,2,6,7,5,1},{0,4,6,7,3,1},
                                    {0,2,3,7,5,4},{1,5,4,6,2,3}};
       register SRCREC      *s = source + sn;
       FVECT  ap, ip;
       RREAL  pt[6][2];
       int    dir;
       register int  i, j;

       if (s->sflags & (SDISTANT|SFLAT)) {
              if (s->sflags & SDISTANT) {
                     if (ourview.type == VT_PAR)
                            return(0);    /* all or nothing case */
                     if (s->srad >= 0.05)
                            return(0);    /* should never be a problem */
              }
              if (s->sflags & SFLAT) {
                     for (i = 0; i < 3; i++)
                            ap[i] = s->sloc[i] - ourview.vp[i];
                     if (DOT(ap, s->snorm) >= 0.)
                            return(0);    /* source faces away */
              }
              for (j = 0; j < 4; j++) {   /* four corners */
                     for (i = 0; i < 3; i++) {
                            ap[i] = s->sloc[i];
                            if ((j==1)|(j==2)) ap[i] += s->ss[SU][i];
                            else ap[i] -= s->ss[SU][i];
                            if ((j==2)|(j==3)) ap[i] += s->ss[SV][i];
                            else ap[i] -= s->ss[SV][i];
                            if (s->sflags & SDISTANT) {
                                   ap[i] *= 1. + ourview.vfore;
                                   ap[i] += ourview.vp[i];
                            }
                     }
                     viewloc(ip, &ourview, ap);  /* find image point */
                     if (ip[2] <= 0.)
                            return(0);           /* in front of view */
                     sp[j][0] = ip[0]; sp[j][1] = ip[1];
              }
              return(4);
       }
                                   /* identify furthest corner */
       for (i = 0; i < 3; i++)
              ap[i] = s->sloc[i] - ourview.vp[i];
       dir =  (DOT(ap,s->ss[SU])>0.) |
              (DOT(ap,s->ss[SV])>0.)<<1 |
              (DOT(ap,s->ss[SW])>0.)<<2 ;
                                   /* order vertices based on this */
       for (j = 0; j < 6; j++) {
              for (i = 0; i < 3; i++) {
                     ap[i] = s->sloc[i];
                     if (cubeord[dir][j] & 1) ap[i] += s->ss[SU][i];
                     else ap[i] -= s->ss[SU][i];
                     if (cubeord[dir][j] & 2) ap[i] += s->ss[SV][i];
                     else ap[i] -= s->ss[SV][i];
                     if (cubeord[dir][j] & 4) ap[i] += s->ss[SW][i];
                     else ap[i] -= s->ss[SW][i];
              }
              viewloc(ip, &ourview, ap);  /* find image point */
              if (ip[2] <= 0.)
                     return(0);           /* in front of view */
              pt[j][0] = ip[0]; pt[j][1] = ip[1];
       }
       return(convex_hull(pt, 6, sp));           /* make sure it's convex */
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void spinsert ( int  sn,
RREAL  vl[][2],
int  nv 
) [static]

Definition at line 260 of file srcdraw.c.

{
       register SPLIST      *spn;
       register int  i;

       if (nv < 3)
              return;
       if (nv > 3)
              spn = (SPLIST *)malloc(sizeof(SPLIST)+sizeof(RREAL)*2*(nv-3));
       else
              spn = (SPLIST *)malloc(sizeof(SPLIST));
       if (spn == NULL)
              error(SYSTEM, "out of memory in spinsert");
       spn->sn = sn;
       for (i = spn->nv = nv; i--; ) {
              spn->vl[i][0] = vl[i][0]; spn->vl[i][1] = vl[i][1];
       }
       spn->next = sphead;         /* push onto global list */
       sphead = spn;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

int hres

Definition at line 30 of file rhpict.c.

Definition at line 29 of file pcond.c.

const char RCSid[] = "$Id: srcdraw.c,v 2.16 2005/04/19 01:15:07 greg Exp $" [static]

Definition at line 2 of file srcdraw.c.

SPLIST* sphead = NULL [static]

Definition at line 34 of file srcdraw.c.

int vres

Definition at line 30 of file rhpict.c.