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

Comparing ray/src/ot/wfconv.c (file contents):
Revision 2.10 by greg, Fri Nov 8 16:49:04 2013 UTC vs.
Revision 2.18 by greg, Fri Apr 30 16:40:10 2021 UTC

# Line 9 | Line 9 | static const char RCSid[] = "$Id$";
9   #include "copyright.h"
10   #include "standard.h"
11   #include "cvmesh.h"
12 + #include "triangulate.h"
13   #include <ctype.h>
14  
15   typedef int     VNDX[3];        /* vertex index (point,map,normal) */
# Line 31 | Line 32 | static char    group[256];     /* current group name */
32   static int      lineno;         /* current line number */
33   static int      faceno;         /* current face number */
34  
35 < static int getstmt(char *av[MAXARG], FILE       *fp);
36 < static int cvtndx(VNDX  vi, char        *vs);
37 < static int putface(int  ac, char        **av);
35 > static int getstmt(char *av[MAXARG], FILE *fp);
36 > static int cvtndx(VNDX vi, char *vs);
37 > static int putface(int ac, char **av);
38   static OBJECT getmod(void);
39 < static int puttri(char  *v1, char       *v2, char       *v3);
39 > static int puttri(char  *v1, char *v2, char *v3);
40   static void freeverts(void);
41 < static int newv(double  x, double       y, double       z);
42 < static int newvn(double x, double       y, double       z);
43 < static int newvt(double x, double       y);
41 > static int newv(double  x, double y, double z);
42 > static int newvn(double x, double y, double z);
43 > static int newvt(double x, double y);
44   static void syntax(char *er);
45  
46  
# Line 244 | Line 245 | cvtndx(                                /* convert vertex string to index */
245          return(1);
246   }
247  
248 + /* determine dominant axis for triangle */
249 + static int
250 + dominant_axis(char *v1, char *v2, char *v3)
251 + {
252 +        VNDX    v1i, v2i, v3i;
253 +        FVECT   e1, e2, vn;
254 +        int     i, imax;
255  
256 +        if (!cvtndx(v1i, v1) || !cvtndx(v2i, v2) || !cvtndx(v3i, v3))
257 +                return(-1);
258 +        VSUB(e1, vlist[v2i[0]], vlist[v1i[0]]);
259 +        VSUB(e2, vlist[v3i[0]], vlist[v2i[0]]);
260 +        VCROSS(vn, e1, e2);
261 +        for (i = imax = 2; i--; )
262 +                if (vn[i]*vn[i] > vn[imax]*vn[imax])
263 +                        imax = i;
264 +        return(vn[imax]*vn[imax] > FTINY*FTINY*FTINY*FTINY ? imax : -1);
265 + }
266 +
267 + /* struct needed for triangulation callback */
268 + typedef struct {
269 +        char    **avl;
270 +        int     rev;
271 + } WFpoly;
272 +
273 + /* callback for triangle output from polygon */
274   static int
275 + tri_out(const Vert2_list *tp, int a, int b, int c)
276 + {
277 +        WFpoly *        wp = (WFpoly *)tp->p;
278 +
279 +        if (wp->rev)
280 +                return( puttri(wp->avl[c], wp->avl[b], wp->avl[a]) );
281 +
282 +        return( puttri(wp->avl[a], wp->avl[b], wp->avl[c]) );
283 + }
284 +
285 + static int
286   putface(                                /* put out an N-sided polygon */
287          int     ac,
288          char    **av
289   )
290   {
291 <        char            *cp;
292 <        int     i;
291 >        Vert2_list      *poly;
292 >        WFpoly          myps;
293 >        int             i, ax, ay;
294  
295 <        while (ac > 3) {                /* break into triangles */
296 <                if (!puttri(av[0], av[1], av[2]))
295 >        for (i = ac-3; i >= 0; i--)     /* identify dominant axis */
296 >                if ((ax = dominant_axis(av[i], av[i+1], av[i+2])) >= 0)
297 >                        break;
298 >        if (ax < 0)
299 >                return(1);              /* ignore degenerate face */
300 >        poly = polyAlloc(ac);
301 >        if (poly == NULL)
302 >                return(0);
303 >        myps.avl = av;
304 >        poly->p = &myps;
305 >        if (++ax >= 3) ax = 0;
306 >        ay = ax;
307 >        if (++ay >= 3) ay = 0;
308 >        for (i = 0; i < ac; i++) {      /* convert to 2-D polygon */
309 >                VNDX    vi;
310 >                if (!cvtndx(vi, av[i])) {
311 >                        error(WARNING, "bad vertex reference");
312 >                        polyFree(poly);
313                          return(0);
314 <                ac--;                   /* remove vertex & rotate */
315 <                cp = av[0];
316 <                for (i = 0; i < ac-1; i++)
263 <                        av[i] = av[i+2];
264 <                av[i] = cp;
314 >                }
315 >                poly->v[i].mX = vlist[vi[0]][ax];
316 >                poly->v[i].mY = vlist[vi[0]][ay];
317          }
318 <        return(puttri(av[0], av[1], av[2]));
318 >                                        /* flag for order reversal */
319 >        myps.rev = (polyArea(poly) < .0);
320 >                                        /* break into triangles & output */
321 >        if (!polyTriangulate(poly, &tri_out)) {
322 >                sprintf(errmsg, "self-intersecting face with %d vertices", ac);
323 >                error(WARNING, errmsg);
324 >        }
325 >        polyFree(poly);
326 >        return(1);
327   }
328  
329  
# Line 422 | Line 482 | syntax(                        /* report syntax error and exit */
482          char    *er
483   )
484   {
485 <        sprintf(errmsg, "%s: Wavefront syntax error near line %d: %s\n",
485 >        sprintf(errmsg, "%s: Wavefront syntax error near line %d: %s",
486                          inpfile, lineno, er);
487          error(USER, errmsg);
488   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines