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

Comparing ray/src/common/triangulate.c (file contents):
Revision 2.1 by greg, Thu Jan 23 23:51:41 2014 UTC vs.
Revision 2.5 by greg, Thu Dec 22 18:50:48 2016 UTC

# Line 5 | Line 5 | static const char RCSid[] = "$Id$";
5   *  triangulate.c
6   *  
7   *  Adapted by Greg Ward on 1/23/14.
8 < *  Copyright 2014 Anyhere Software. All rights reserved.
8 > *  Fixes for polygons with seams/holes and co-linear vertices added
9 > *  by Nathaniel Jones on 12/21/16.
10 > *  Copyright 2016 Anyhere Software. All rights reserved.
11   *
12   */
13  
# Line 38 | Line 40 | static int
40   polySnip(const Vert2_list *contour, int u, int v, int w, int n, int *V)
41   {
42    int p;
43 <  double Ax, Ay, Bx, By, Cx, Cy, Px, Py;
43 >  double Ax, Ay, Bx, By, Cx, Cy, Px, Py, cross;
44  
45    Ax = contour->v[V[u]].mX;
46    Ay = contour->v[V[u]].mY;
# Line 49 | Line 51 | polySnip(const Vert2_list *contour, int u, int v, int
51    Cx = contour->v[V[w]].mX;
52    Cy = contour->v[V[w]].mY;
53  
54 <  if ( EPSILON > (((Bx-Ax)*(Cy-Ay)) - ((By-Ay)*(Cx-Ax))) ) return false;
54 >  cross = ((Bx - Ax)*(Cy - Ay)) - ((By - Ay)*(Cx - Ax));
55 >  if (EPSILON > cross) return EPSILON > -cross ? -1 : false; /* Negative if colinear points */
56  
57    for (p=0;p<n;p++)
58    {
59 <    if( (p == u) || (p == v) || (p == w) ) continue;
59 >    if( (p == u) | (p == v) | (p == w) ) continue;
60      Px = contour->v[V[p]].mX;
61      Py = contour->v[V[p]].mY;
62 +    if ((Px == Ax && Py == Ay) || (Px == Bx && Py == By) ||
63 +                (Px == Cx && Py == Cy)) continue; /* Handle donuts */
64      if (insideTriangle(Ax,Ay,Bx,By,Cx,Cy,Px,Py)) return false;
65    }
66  
# Line 123 | Line 128 | polyTriangulate(const Vert2_list *contour, tri_out_t *
128   {
129    /* allocate and initialize list of Vertices in polygon */
130  
131 <  int nv, m, u, v, w, count;
131 >  int nv, m, u, v, w, count, result;
132    int *V;
133  
134    if ( contour->nv < 3 ) return false;
# Line 133 | Line 138 | polyTriangulate(const Vert2_list *contour, tri_out_t *
138  
139    /* we want a counter-clockwise polygon in V */
140  
141 <  if ( 0.0 < Area(contour) )
141 >  if ( 0.0 < polyArea(contour) )
142      for (v=0; v<contour->nv; v++) V[v] = v;
143    else
144      for(v=0; v<contour->nv; v++) V[v] = (contour->nv-1)-v;
# Line 146 | Line 151 | polyTriangulate(const Vert2_list *contour, tri_out_t *
151    for(m=0, v=nv-1; nv>2; )
152    {
153      /* if we loop, it is probably a non-simple polygon */
154 <    if (0 >= (count--))
154 >    if (0 >= count--)
155      {
156 <      /* Triangulate: ERROR - probable bad polygon! */
156 >      /* Triangulate: ERROR - probable bad polygon */
157        return false;
158      }
159  
# Line 157 | Line 162 | polyTriangulate(const Vert2_list *contour, tri_out_t *
162      v = u+1; if (nv <= v) v = 0;     /* new v    */
163      w = v+1; if (nv <= w) w = 0;     /* next     */
164  
165 <    if ( polySnip(contour,u,v,w,nv,V) )
165 >    result = polySnip(contour, u, v, w, nv, V);
166 >    if (result > 0) /* successfully found a triangle */
167      {
168 <      int a,b,c,s,t;
168 >      int a,b,c;
169  
170        /* true names of the vertices */
171        a = V[u]; b = V[v]; c = V[w];
172  
173        /* output Triangle */
174 <      (*cb)(contour, a, b, c);
174 >      if (!(*cb)(contour, a, b, c)) return false;
175  
176        m++;
177 +    }
178 +    if (result) /* successfully found a triangle or three consecutive colinear points */
179 +    {
180 +      int s,t;
181  
182        /* remove v from remaining polygon */
183        for(s=v,t=v+1;t<nv;s++,t++) V[s] = V[t]; nv--;
184  
185 <      /* resest error detection counter */
185 >      /* reset error detection counter */
186        count = 2*nv;
187      }
188    }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines