Back to index

radiance  4R0+20100331
Defines | Functions | Variables
face.c File Reference
#include "copyright.h"
#include "standard.h"
#include "object.h"
#include "face.h"

Go to the source code of this file.

Defines

#define VERTEPS   1e-5 /* allowed vertex error */

Functions

FACEgetface (OBJREC *o)
void freeface (OBJREC *o)
int inface (FVECT p, FACE *f)

Variables

static const char RCSid [] = "$Id: face.c,v 2.12 2006/03/02 16:51:54 greg Exp $"

Define Documentation

#define VERTEPS   1e-5 /* allowed vertex error */

Definition at line 30 of file face.c.


Function Documentation

void freeface ( OBJREC o)

Definition at line 109 of file face.c.

{
       if (o->os == NULL)
              return;
       free(o->os);
       o->os = NULL;
}
FACE* getface ( OBJREC o)

Definition at line 35 of file face.c.

{
       double  d1;
       int  smalloff, badvert;
       FVECT  v1, v2, v3;
       register FACE  *f;
       register int  i;

       if ((f = (FACE *)o->os) != NULL)
              return(f);                  /* already done */

       f = (FACE *)malloc(sizeof(FACE));
       if (f == NULL)
              error(SYSTEM, "out of memory in makeface");

       if (o->oargs.nfargs < 9 || o->oargs.nfargs % 3)
              objerror(o, USER, "bad # arguments");

       o->os = (char *)f;                 /* save face */

       f->va = o->oargs.farg;
       f->nv = o->oargs.nfargs / 3;
                                          /* check for last==first */
       if (dist2(VERTEX(f,0),VERTEX(f,f->nv-1)) <= FTINY*FTINY)
              f->nv--;
                                          /* compute area and normal */
       f->norm[0] = f->norm[1] = f->norm[2] = 0.0;
       v1[0] = VERTEX(f,1)[0] - VERTEX(f,0)[0];
       v1[1] = VERTEX(f,1)[1] - VERTEX(f,0)[1];
       v1[2] = VERTEX(f,1)[2] - VERTEX(f,0)[2];
       for (i = 2; i < f->nv; i++) {
              v2[0] = VERTEX(f,i)[0] - VERTEX(f,0)[0];
              v2[1] = VERTEX(f,i)[1] - VERTEX(f,0)[1];
              v2[2] = VERTEX(f,i)[2] - VERTEX(f,0)[2];
              fcross(v3, v1, v2);
              f->norm[0] += v3[0];
              f->norm[1] += v3[1];
              f->norm[2] += v3[2];
              VCOPY(v1, v2);
       }
       f->area = normalize(f->norm);
       if (f->area == 0.0) {
              objerror(o, WARNING, "zero area"); /* used to be fatal */
              f->offset = 0.0;
              f->ax = 0;
              return(f);
       }
       f->area *= 0.5;
                                          /* compute offset */
       badvert = 0;
       f->offset = DOT(f->norm, VERTEX(f,0));
       smalloff = fabs(f->offset) <= VERTEPS;
       for (i = 1; i < f->nv; i++) {
              d1 = DOT(f->norm, VERTEX(f,i));
              if (smalloff)
                     badvert += fabs(d1 - f->offset/i) > VERTEPS;
              else
                     badvert += fabs(1.0 - d1*i/f->offset) > VERTEPS;
              f->offset += d1;
       }
       f->offset /= (double)f->nv;
       if (f->nv > 3 && badvert)
              objerror(o, WARNING, "non-planar vertex");
                                          /* find axis */
       f->ax = fabs(f->norm[0]) > fabs(f->norm[1]) ? 0 : 1;
       if (fabs(f->norm[2]) > fabs(f->norm[f->ax]))
              f->ax = 2;

       return(f);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int inface ( FVECT  p,
FACE f 
)

Definition at line 120 of file face.c.

{
       int  ncross, n;
       double  x, y;
       int  tst;
       register int  xi, yi;
       register RREAL  *p0, *p1;

       if ((xi = f->ax + 1) >= 3) xi -= 3;
       if ((yi = xi + 1) >= 3) yi -= 3;
       x = p[xi];
       y = p[yi];
       n = f->nv;
       p0 = f->va + 3*(n-1);              /* connect last to first */
       p1 = f->va;
       ncross = 0;
                                   /* positive x axis cross test */
       while (n--) {
              if ((p0[yi] > y) ^ (p1[yi] > y)) {
                     tst = (p0[xi] > x) + (p1[xi] > x);
                     if (tst == 2)
                            ncross++;
                     else if (tst)
                            ncross += (p1[yi] > p0[yi]) ^
                                          ((p0[yi]-y)*(p1[xi]-x) >
                                          (p0[xi]-x)*(p1[yi]-y));
              }
              p0 = p1;
              p1 += 3;
       }
       return(ncross & 01);
}

Here is the caller graph for this function:


Variable Documentation

const char RCSid[] = "$Id: face.c,v 2.12 2006/03/02 16:51:54 greg Exp $" [static]

Definition at line 2 of file face.c.