ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/tmesh.c
Revision: 2.6
Committed: Thu Apr 15 23:51:04 2021 UTC (3 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R4, HEAD
Changes since 2.5: +43 -32 lines
Log Message:
feat(genbox,robjutil): Added Radiance normal smoothing support to wfobj library

File Contents

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.6 static const char RCSid[] = "$Id: tmesh.c,v 2.5 2006/03/02 17:16:56 greg Exp $";
3 greg 2.1 #endif
4     /*
5     * Compute and print barycentric coordinates for triangle meshes
6     */
7    
8     #include <stdio.h>
9     #include "fvect.h"
10     #include "tmesh.h"
11    
12    
13     int
14 greg 2.6 flat_tri( /* determine if triangle is flat */
15     FVECT v1,
16     FVECT v2,
17     FVECT v3,
18     FVECT n1,
19     FVECT n2,
20     FVECT n3
21     )
22 greg 2.1 {
23     double d1, d2, d3;
24     FVECT vt1, vt2, vn;
25     /* compute default normal */
26 greg 2.2 VSUB(vt1, v2, v1);
27     VSUB(vt2, v3, v2);
28     VCROSS(vn, vt1, vt2);
29 greg 2.1 if (normalize(vn) == 0.0)
30     return(DEGEN);
31     /* compare to supplied normals */
32     d1 = DOT(vn, n1); d2 = DOT(vn, n2); d3 = DOT(vn, n3);
33     if (d1 < 0 && d2 < 0 && d3 < 0) {
34     if (d1 > -COSTOL || d2 > -COSTOL || d3 > -COSTOL)
35     return(RVBENT);
36     return(RVFLAT);
37     }
38     if (d1 < COSTOL || d2 < COSTOL || d3 < COSTOL)
39     return(ISBENT);
40     return(ISFLAT);
41     }
42    
43    
44     int
45 greg 2.6 comp_baryc( /* compute barycentric vectors */
46     BARYCCM *bcm,
47     RREAL *v1,
48     RREAL *v2,
49     RREAL *v3
50     )
51 greg 2.1 {
52 schorsch 2.3 RREAL *vt;
53 greg 2.1 FVECT va, vab, vcb;
54     double d;
55     int ax0, ax1;
56 greg 2.6 int i;
57 greg 2.1 /* compute major axis */
58 greg 2.2 VSUB(vab, v1, v2);
59     VSUB(vcb, v3, v2);
60     VCROSS(va, vab, vcb);
61 greg 2.6 bcm->ax = (va[1]*va[1] > va[0]*va[0]);
62     if (va[2]*va[2] > va[bcm->ax]*va[bcm->ax]) bcm->ax = 2;
63     ax0 = (bcm->ax + 1)%3;
64     ax1 = (bcm->ax + 2)%3;
65 greg 2.1 for (i = 0; i < 2; i++) {
66     vab[0] = v1[ax0] - v2[ax0];
67     vcb[0] = v3[ax0] - v2[ax0];
68     vab[1] = v1[ax1] - v2[ax1];
69     vcb[1] = v3[ax1] - v2[ax1];
70     d = vcb[0]*vcb[0] + vcb[1]*vcb[1];
71     if (d <= FTINY*FTINY)
72     return(-1);
73 greg 2.6 d = (vcb[0]*vab[0] + vcb[1]*vab[1])/d;
74 greg 2.1 va[0] = vab[0] - vcb[0]*d;
75     va[1] = vab[1] - vcb[1]*d;
76     d = va[0]*va[0] + va[1]*va[1];
77     if (d <= FTINY*FTINY)
78     return(-1);
79     d = 1.0/d;
80     bcm->tm[i][0] = va[0] *= d;
81     bcm->tm[i][1] = va[1] *= d;
82 greg 2.6 bcm->tm[i][2] = -(v2[ax0]*va[0] + v2[ax1]*va[1]);
83 greg 2.1 /* rotate vertices */
84     vt = v1;
85     v1 = v2;
86     v2 = v3;
87     v3 = vt;
88     }
89     return(0);
90     }
91    
92    
93 greg 2.2 void
94 greg 2.6 eval_baryc( /* evaluate barycentric weights at p */
95     RREAL wt[3],
96     FVECT p,
97     BARYCCM *bcm
98     )
99 greg 2.2 {
100     double u, v;
101 greg 2.5 int i;
102 greg 2.2
103 greg 2.5 if ((i = bcm->ax + 1) >= 3) i -= 3;
104     u = p[i];
105     if (++i >= 3) i -= 3;
106     v = p[i];
107 greg 2.2 wt[0] = u*bcm->tm[0][0] + v*bcm->tm[0][1] + bcm->tm[0][2];
108     wt[1] = u*bcm->tm[1][0] + v*bcm->tm[1][1] + bcm->tm[1][2];
109     wt[2] = 1. - wt[1] - wt[0];
110     }
111    
112    
113     int
114 greg 2.6 get_baryc( /* compute barycentric weights at p */
115     RREAL wt[3],
116     FVECT p,
117     FVECT v1,
118     FVECT v2,
119     FVECT v3
120     )
121 greg 2.2 {
122     BARYCCM bcm;
123    
124     if (comp_baryc(&bcm, v1, v2, v3) < 0)
125     return(-1);
126     eval_baryc(wt, p, &bcm);
127     return(0);
128     }
129    
130    
131     #if 0
132     int
133     get_baryc(wt, p, v1, v2, v3) /* compute barycentric weights at p */
134 schorsch 2.3 RREAL wt[3];
135 greg 2.2 FVECT p;
136     FVECT v1, v2, v3;
137     {
138     FVECT ac, bc, pc, cros;
139     double normf;
140     /* area formula w/o 2-D optimization */
141     VSUB(ac, v1, v3);
142     VSUB(bc, v2, v3);
143     VSUB(pc, p, v3);
144     VCROSS(cros, ac, bc);
145     normf = DOT(cros,cros)
146     if (normf <= 0.0)
147     return(-1);
148     normf = 1./sqrt(normf);
149     VCROSS(cros, bc, pc);
150     wt[0] = VLEN(cros) * normf;
151     VCROSS(cros, ac, pc);
152     wt[1] = VLEN(cros) * normf;
153     wt[2] = 1. - wt[1] - wt[0];
154     return(0);
155     }
156     #endif
157    
158    
159     void
160 greg 2.6 fput_baryc( /* put barycentric coord. vectors */
161     BARYCCM *bcm,
162     RREAL com[][3],
163     int n,
164     FILE *fp
165     )
166 greg 2.1 {
167     double a, b;
168 greg 2.6 int i;
169 greg 2.1
170 greg 2.6 fprintf(fp, "%d\t%d\n", 1+3*n, bcm->ax);
171 greg 2.1 for (i = 0; i < n; i++) {
172     a = com[i][0] - com[i][2];
173     b = com[i][1] - com[i][2];
174 greg 2.6 fprintf(fp, "%14.8f %14.8f %14.8f\n",
175 greg 2.1 bcm->tm[0][0]*a + bcm->tm[1][0]*b,
176     bcm->tm[0][1]*a + bcm->tm[1][1]*b,
177     bcm->tm[0][2]*a + bcm->tm[1][2]*b + com[i][2]);
178     }
179     }