ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/face.c
Revision: 2.9
Committed: Fri Mar 14 21:27:45 2003 UTC (21 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.8: +4 -4 lines
Log Message:
Added -a option to obj2mesh to incorporate materials in mesh

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 2.8 static const char RCSid[] = "$Id$";
3 greg 1.1 #endif
4     /*
5     * face.c - routines dealing with polygonal faces.
6 greg 2.6 */
7    
8 greg 2.7 #include "copyright.h"
9 greg 1.1
10     #include "standard.h"
11    
12     #include "object.h"
13    
14     #include "face.h"
15    
16     /*
17     * A face is given as a list of 3D vertices. The normal
18     * direction and therefore the surface orientation is determined
19     * by the ordering of the vertices. Looking in the direction opposite
20     * the normal (at the front of the face), the vertices will be
21     * listed in counter-clockwise order.
22     * There is no checking done to insure that the edges do not cross
23     * one another. This was considered too expensive and should be unnecessary.
24     * The last vertex is automatically connected to the first.
25     */
26    
27 greg 2.3 #ifdef SMLFLT
28 greg 2.9 #define VERTEPS 1e-3 /* allowed vertex error */
29 greg 2.3 #else
30 greg 2.9 #define VERTEPS 1e-5 /* allowed vertex error */
31 greg 2.3 #endif
32 greg 1.1
33    
34     FACE *
35     getface(o) /* get arguments for a face */
36     OBJREC *o;
37     {
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 greg 2.4 /* check for last==first */
59     if (dist2(VERTEX(f,0),VERTEX(f,f->nv-1)) <= FTINY*FTINY)
60     f->nv--;
61 greg 1.1 /* compute area and normal */
62     f->norm[0] = f->norm[1] = f->norm[2] = 0.0;
63 greg 2.5 v1[0] = VERTEX(f,1)[0] - VERTEX(f,0)[0];
64     v1[1] = VERTEX(f,1)[1] - VERTEX(f,0)[1];
65     v1[2] = VERTEX(f,1)[2] - VERTEX(f,0)[2];
66     for (i = 2; i < f->nv; i++) {
67 greg 1.1 v2[0] = VERTEX(f,i)[0] - VERTEX(f,0)[0];
68     v2[1] = VERTEX(f,i)[1] - VERTEX(f,0)[1];
69     v2[2] = VERTEX(f,i)[2] - VERTEX(f,0)[2];
70     fcross(v3, v1, v2);
71     f->norm[0] += v3[0];
72     f->norm[1] += v3[1];
73     f->norm[2] += v3[2];
74     VCOPY(v1, v2);
75     }
76     f->area = normalize(f->norm);
77     if (f->area == 0.0) {
78     objerror(o, WARNING, "zero area"); /* used to be fatal */
79 greg 1.2 f->offset = 0.0;
80 greg 1.1 f->ax = 0;
81     return(f);
82     }
83     f->area *= 0.5;
84 greg 1.2 /* compute offset */
85 greg 1.1 badvert = 0;
86 greg 1.2 f->offset = DOT(f->norm, VERTEX(f,0));
87 greg 1.1 for (i = 1; i < f->nv; i++) {
88     d1 = DOT(f->norm, VERTEX(f,i));
89 greg 2.9 badvert += fabs(1.0 - d1*i/f->offset) > VERTEPS;
90 greg 1.2 f->offset += d1;
91 greg 1.1 }
92 greg 1.5 f->offset /= (double)f->nv;
93 greg 2.9 if (f->nv > 3 && badvert)
94 greg 1.1 objerror(o, WARNING, "non-planar vertex");
95     /* find axis */
96     f->ax = fabs(f->norm[0]) > fabs(f->norm[1]) ? 0 : 1;
97     if (fabs(f->norm[2]) > fabs(f->norm[f->ax]))
98     f->ax = 2;
99    
100     return(f);
101     }
102    
103    
104 greg 2.6 void
105 greg 1.1 freeface(o) /* free memory associated with face */
106     OBJREC *o;
107     {
108 greg 1.4 if (o->os == NULL)
109     return;
110 greg 1.1 free(o->os);
111     o->os = NULL;
112     }
113    
114    
115 greg 2.6 int
116 greg 1.1 inface(p, f) /* determine if point is in face */
117     FVECT p;
118     FACE *f;
119     {
120     int ncross, n;
121     double x, y;
122 greg 2.8 int tst;
123 greg 1.1 register int xi, yi;
124 greg 1.6 register FLOAT *p0, *p1;
125 greg 1.1
126     xi = (f->ax+1)%3;
127     yi = (f->ax+2)%3;
128     x = p[xi];
129     y = p[yi];
130     n = f->nv;
131     p0 = f->va + 3*(n-1); /* connect last to first */
132     p1 = f->va;
133     ncross = 0;
134     /* positive x axis cross test */
135     while (n--) {
136 greg 2.8 if ((p0[yi] > y) ^ (p1[yi] > y)) {
137     tst = (p0[xi] > x) + (p1[xi] > x);
138     if (tst == 2)
139 greg 1.1 ncross++;
140 greg 2.8 else if (tst)
141 greg 1.1 ncross += (p1[yi] > p0[yi]) ^
142     ((p0[yi]-y)*(p1[xi]-x) >
143     (p0[xi]-x)*(p1[yi]-y));
144 greg 2.8 }
145 greg 1.1 p0 = p1;
146     p1 += 3;
147     }
148     return(ncross & 01);
149     }