ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/face.c
(Generate patch)

Comparing ray/src/common/face.c (file contents):
Revision 2.9 by greg, Fri Mar 14 21:27:45 2003 UTC vs.
Revision 2.15 by greg, Fri Feb 12 00:47:33 2021 UTC

# Line 32 | Line 32 | static const char RCSid[] = "$Id$";
32  
33  
34   FACE *
35 < getface(o)                      /* get arguments for a face */
36 < OBJREC  *o;
35 > getface(                                /* get arguments for a face */
36 >        OBJREC  *o
37 > )
38   {
39          double  d1;
40 <        int  badvert;
40 >        int  smalloff, badvert;
41          FVECT  v1, v2, v3;
42 <        register FACE  *f;
43 <        register int  i;
42 >        FACE  *f;
43 >        int  i;
44  
45          if ((f = (FACE *)o->os) != NULL)
46                  return(f);                      /* already done */
# Line 56 | Line 57 | OBJREC  *o;
57          f->va = o->oargs.farg;
58          f->nv = o->oargs.nfargs / 3;
59                                                  /* check for last==first */
60 <        if (dist2(VERTEX(f,0),VERTEX(f,f->nv-1)) <= FTINY*FTINY)
60 >        if (f->nv > 3 && dist2(VERTEX(f,0),VERTEX(f,f->nv-1)) <= FTINY*FTINY)
61                  f->nv--;
62                                                  /* compute area and normal */
63          f->norm[0] = f->norm[1] = f->norm[2] = 0.0;
# Line 84 | Line 85 | OBJREC  *o;
85                                                  /* compute offset */
86          badvert = 0;
87          f->offset = DOT(f->norm, VERTEX(f,0));
88 +        smalloff = fabs(f->offset) <= VERTEPS;
89          for (i = 1; i < f->nv; i++) {
90                  d1 = DOT(f->norm, VERTEX(f,i));
91 <                badvert += fabs(1.0 - d1*i/f->offset) > VERTEPS;
91 >                if (smalloff)
92 >                        badvert += fabs(d1 - f->offset/i) > VERTEPS;
93 >                else
94 >                        badvert += fabs(1.0 - d1*i/f->offset) > VERTEPS;
95                  f->offset += d1;
96          }
97          f->offset /= (double)f->nv;
98          if (f->nv > 3 && badvert)
99                  objerror(o, WARNING, "non-planar vertex");
100                                                  /* find axis */
101 <        f->ax = fabs(f->norm[0]) > fabs(f->norm[1]) ? 0 : 1;
101 >        f->ax = (fabs(f->norm[0]) > fabs(f->norm[1]));
102          if (fabs(f->norm[2]) > fabs(f->norm[f->ax]))
103                  f->ax = 2;
104  
# Line 102 | Line 107 | OBJREC  *o;
107  
108  
109   void
110 < freeface(o)                     /* free memory associated with face */
111 < OBJREC  *o;
110 > freeface(                       /* free memory associated with face */
111 >        OBJREC  *o
112 > )
113   {
114          if (o->os == NULL)
115                  return;
# Line 113 | Line 119 | OBJREC  *o;
119  
120  
121   int
122 < inface(p, f)                    /* determine if point is in face */
123 < FVECT  p;
124 < FACE  *f;
122 > inface(                         /* determine if point is in face */
123 >        FVECT  p,
124 >        FACE  *f
125 > )
126   {
127          int  ncross, n;
128          double  x, y;
129          int  tst;
130 <        register int  xi, yi;
131 <        register FLOAT  *p0, *p1;
130 >        int  xi, yi;
131 >        RREAL  *p0, *p1;
132  
133 <        xi = (f->ax+1)%3;
134 <        yi = (f->ax+2)%3;
133 >        if ((xi = f->ax + 1) >= 3) xi -= 3;
134 >        if ((yi = xi + 1) >= 3) yi -= 3;
135          x = p[xi];
136          y = p[yi];
137          n = f->nv;
# Line 137 | Line 144 | FACE  *f;
144                          tst = (p0[xi] > x) + (p1[xi] > x);
145                          if (tst == 2)
146                                  ncross++;
147 <                        else if (tst)
148 <                                ncross += (p1[yi] > p0[yi]) ^
149 <                                                ((p0[yi]-y)*(p1[xi]-x) >
150 <                                                (p0[xi]-x)*(p1[yi]-y));
151 <                }
147 >                        else if (tst) {
148 >                                double  prodA = (p0[yi]-y)*(p1[xi]-x);
149 >                                double  prodB = (p0[xi]-x)*(p1[yi]-y);
150 >                                if (FRELEQ(prodA, prodB))
151 >                                        return(1);      /* edge case #1 */
152 >                                ncross += (p1[yi] > p0[yi]) ^ (prodA > prodB);
153 >                        } else if (FRELEQ(p0[xi], x) && FRELEQ(p1[xi], x))
154 >                                return(1);              /* edge case #2 */
155 >                } else if (FRELEQ(p0[yi], y) && FRELEQ(p1[yi], y) &&
156 >                                (p0[xi] > x) ^ (p1[xi] > x))
157 >                        return(1);                      /* edge case #3 */
158                  p0 = p1;
159                  p1 += 3;
160          }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines