ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/face.c
Revision: 1.6
Committed: Wed Oct 23 13:43:14 1991 UTC (32 years, 6 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.5: +1 -1 lines
Log Message:
added FLOAT definition to better control size of structures

File Contents

# User Rev Content
1 greg 1.5 /* Copyright (c) 1991 Regents of the University of California */
2 greg 1.1
3     #ifndef lint
4     static char SCCSid[] = "$SunId$ LBL";
5     #endif
6    
7     /*
8     * face.c - routines dealing with polygonal faces.
9     *
10     * 8/30/85
11     */
12    
13     #include "standard.h"
14    
15     #include "object.h"
16    
17     #include "face.h"
18    
19     /*
20     * A face is given as a list of 3D vertices. The normal
21     * direction and therefore the surface orientation is determined
22     * by the ordering of the vertices. Looking in the direction opposite
23     * the normal (at the front of the face), the vertices will be
24     * listed in counter-clockwise order.
25     * There is no checking done to insure that the edges do not cross
26     * one another. This was considered too expensive and should be unnecessary.
27     * The last vertex is automatically connected to the first.
28     */
29    
30     #define VERTEPS 1e-4 /* allowed vertex error */
31    
32    
33     FACE *
34     getface(o) /* get arguments for a face */
35     OBJREC *o;
36     {
37     double fabs();
38     double d1;
39     int badvert;
40     FVECT v1, v2, v3;
41     register FACE *f;
42     register int i;
43    
44     if ((f = (FACE *)o->os) != NULL)
45     return(f); /* already done */
46    
47     f = (FACE *)malloc(sizeof(FACE));
48     if (f == NULL)
49     error(SYSTEM, "out of memory in makeface");
50    
51     if (o->oargs.nfargs < 9 || o->oargs.nfargs % 3)
52     objerror(o, USER, "bad # arguments");
53    
54 greg 1.3 o->os = (char *)f; /* save face */
55    
56 greg 1.1 f->va = o->oargs.farg;
57     f->nv = o->oargs.nfargs / 3;
58     /* compute area and normal */
59     f->norm[0] = f->norm[1] = f->norm[2] = 0.0;
60     v1[0] = v1[1] = v1[2] = 0.0;
61     for (i = 1; i < f->nv; i++) {
62     v2[0] = VERTEX(f,i)[0] - VERTEX(f,0)[0];
63     v2[1] = VERTEX(f,i)[1] - VERTEX(f,0)[1];
64     v2[2] = VERTEX(f,i)[2] - VERTEX(f,0)[2];
65     fcross(v3, v1, v2);
66     f->norm[0] += v3[0];
67     f->norm[1] += v3[1];
68     f->norm[2] += v3[2];
69     VCOPY(v1, v2);
70     }
71     f->area = normalize(f->norm);
72     if (f->area == 0.0) {
73     objerror(o, WARNING, "zero area"); /* used to be fatal */
74 greg 1.2 f->offset = 0.0;
75 greg 1.1 f->ax = 0;
76     return(f);
77     }
78     f->area *= 0.5;
79 greg 1.2 /* compute offset */
80 greg 1.1 badvert = 0;
81 greg 1.2 f->offset = DOT(f->norm, VERTEX(f,0));
82 greg 1.1 for (i = 1; i < f->nv; i++) {
83     d1 = DOT(f->norm, VERTEX(f,i));
84 greg 1.2 badvert += fabs(d1 - f->offset/i) > VERTEPS;
85     f->offset += d1;
86 greg 1.1 }
87 greg 1.5 f->offset /= (double)f->nv;
88 greg 1.1 if (badvert)
89     objerror(o, WARNING, "non-planar vertex");
90     /* find axis */
91     f->ax = fabs(f->norm[0]) > fabs(f->norm[1]) ? 0 : 1;
92     if (fabs(f->norm[2]) > fabs(f->norm[f->ax]))
93     f->ax = 2;
94    
95     return(f);
96     }
97    
98    
99     freeface(o) /* free memory associated with face */
100     OBJREC *o;
101     {
102 greg 1.4 if (o->os == NULL)
103     return;
104 greg 1.1 free(o->os);
105     o->os = NULL;
106     }
107    
108    
109     inface(p, f) /* determine if point is in face */
110     FVECT p;
111     FACE *f;
112     {
113     int ncross, n;
114     double x, y;
115     register int xi, yi;
116 greg 1.6 register FLOAT *p0, *p1;
117 greg 1.1
118     xi = (f->ax+1)%3;
119     yi = (f->ax+2)%3;
120     x = p[xi];
121     y = p[yi];
122     n = f->nv;
123     p0 = f->va + 3*(n-1); /* connect last to first */
124     p1 = f->va;
125     ncross = 0;
126     /* positive x axis cross test */
127     while (n--) {
128     if ((p0[yi] > y) ^ (p1[yi] > y))
129     if (p0[xi] > x && p1[xi] > x)
130     ncross++;
131     else if (p0[xi] > x || p1[xi] > x)
132     ncross += (p1[yi] > p0[yi]) ^
133     ((p0[yi]-y)*(p1[xi]-x) >
134     (p0[xi]-x)*(p1[yi]-y));
135     p0 = p1;
136     p1 += 3;
137     }
138     return(ncross & 01);
139     }