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.6 by schorsch, Sun Jul 27 22:12:03 2003 UTC vs.
Revision 2.17 by greg, Thu Mar 11 17:00:58 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) */
16  
17   #define CHUNKSIZ        1024    /* vertex allocation chunk size */
18  
19 < #define MAXARG          64      /* maximum # arguments in a statement */
19 > #define MAXARG          512     /* maximum # arguments in a statement */
20  
21   static FVECT    *vlist;         /* our vertex list */
22   static int      nvs;            /* number of vertices in our list */
# Line 26 | Line 27 | static int     nvts;
27  
28   static char     *inpfile;       /* input file name */
29   static int      havemats;       /* materials available? */
30 < static char     material[64];   /* current material name */
31 < static char     group[64];      /* current group name */
30 > static char     material[256];  /* current material name */
31 > 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();
36 < static int      cvtndx();
37 < static OBJECT   getmod();
38 < static int      putface();
39 < static int      puttri();
40 < static void     freeverts();
41 < static int      newv();
42 < static int      newvn();
43 < static int      newvt();
44 < static void     syntax();
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);
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);
44 > static void syntax(char *er);
45  
46  
47   void
48 < wfreadobj(objfn)                /* read in .OBJ file and convert */
49 < char    *objfn;
48 > wfreadobj(              /* read in .OBJ file and convert */
49 >        char    *objfn
50 > )
51   {
52          FILE    *fp;
53          char    *argv[MAXARG];
54          int     argc;
55          int     nstats, nunknown;
54        int     i;
56  
57          if (objfn == NULL) {
58                  inpfile = "<stdin>";
# Line 157 | Line 158 | char   *objfn;
158  
159  
160   static int
161 < getstmt(av, fp)                         /* read the next statement from fp */
162 < register char   *av[MAXARG];
163 < FILE    *fp;
161 > getstmt(                                /* read the next statement from fp */
162 >        char    *av[MAXARG],
163 >        FILE    *fp
164 > )
165   {
166          static char     sbuf[MAXARG*16];
167 <        register char   *cp;
168 <        register int    i;
167 >        char    *cp;
168 >        int     i;
169  
170          do {
171                  if (fgetline(cp=sbuf, sizeof(sbuf), fp) == NULL)
# Line 175 | Line 177 | FILE   *fp;
177                                          lineno++;
178                                  *cp++ = '\0';
179                          }
180 <                        if (!*cp || i >= MAXARG-1)
180 >                        if (!*cp)
181                                  break;
182 +                        if (i >= MAXARG-1) {
183 +                                sprintf(errmsg,
184 +                        "%s: too many arguments near line %d (limit %d)\n",
185 +                                        inpfile, lineno+1, MAXARG-1);
186 +                                break;
187 +                        }
188                          av[i++] = cp;
189                          while (*++cp && !isspace(*cp))
190                                  ;
# Line 190 | Line 198 | FILE   *fp;
198  
199  
200   static int
201 < cvtndx(vi, vs)                          /* convert vertex string to index */
202 < register VNDX   vi;
203 < register char   *vs;
201 > cvtndx(                         /* convert vertex string to index */
202 >        VNDX    vi,
203 >        char    *vs
204 > )
205   {
206                                          /* get point */
207          vi[0] = atoi(vs);
# Line 236 | Line 245 | register char  *vs;
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 + /* callback for triangle output from polygon */
268   static int
269 < putface(ac, av)                         /* put out an N-sided polygon */
242 < int     ac;
243 < register char   **av;
269 > tri_out(const Vert2_list *tp, int a, int b, int c)
270   {
271 <        char            *cp;
272 <        register int    i;
271 >        return( puttri( ((char **)tp->p)[a],
272 >                        ((char **)tp->p)[b],
273 >                        ((char **)tp->p)[c] ) );
274 > }
275  
276 <        while (ac > 3) {                /* break into triangles */
277 <                if (!puttri(av[0], av[1], av[2]))
276 > static int
277 > putface(                                /* put out an N-sided polygon */
278 >        int     ac,
279 >        char    **av
280 > )
281 > {
282 >        Vert2_list      *poly;
283 >        int             i, ax, ay;
284 >
285 >        for (i = ac-3; i >= 0; i--)     /* identify dominant axis */
286 >                if ((ax = dominant_axis(av[i], av[i+1], av[i+2])) >= 0)
287 >                        break;
288 >        if (ax < 0)
289 >                return(1);              /* ignore degenerate face */
290 >        poly = polyAlloc(ac);
291 >        if (poly == NULL)
292 >                return(0);
293 >        poly->p = (void *)av;
294 >        if (++ax >= 3) ax = 0;
295 >        ay = ax;
296 >        if (++ay >= 3) ay = 0;
297 >        for (i = 0; i < ac; i++) {      /* convert to 2-D polygon */
298 >                VNDX    vi;
299 >                if (!cvtndx(vi, av[i])) {
300 >                        error(WARNING, "bad vertex reference");
301 >                        polyFree(poly);
302                          return(0);
303 <                ac--;                   /* remove vertex & rotate */
304 <                cp = av[0];
305 <                for (i = 0; i < ac-1; i++)
254 <                        av[i] = av[i+2];
255 <                av[i] = cp;
303 >                }
304 >                poly->v[i].mX = vlist[vi[0]][ax];
305 >                poly->v[i].mY = vlist[vi[0]][ay];
306          }
307 <        return(puttri(av[0], av[1], av[2]));
307 >                                        /* break into triangles & output */
308 >        if (!polyTriangulate(poly, &tri_out)) {
309 >                sprintf(errmsg, "self-intersecting face with %d vertices", ac);
310 >                error(WARNING, errmsg);
311 >        }
312 >        polyFree(poly);
313 >        return(1);
314   }
315  
316  
317   static OBJECT
318 < getmod()                                /* get current modifier ID */
318 > getmod(void)                            /* get current modifier ID */
319   {
320          char    *mnam;
321          OBJECT  mod;
# Line 285 | Line 341 | getmod()                               /* get current modifier ID */
341  
342  
343   static int
344 < puttri(v1, v2, v3)                      /* convert a triangle */
345 < char    *v1, *v2, *v3;
344 > puttri(                 /* convert a triangle */
345 >        char    *v1,
346 >        char    *v2,
347 >        char    *v3
348 > )
349   {
350          VNDX    v1i, v2i, v3i;
351          RREAL   *v1c, *v2c, *v3c;
352          RREAL   *v1n, *v2n, *v3n;
353          
354 <        if (!cvtndx(v1i, v1) || !cvtndx(v2i, v2) || !cvtndx(v3i, v3))
354 >        if (!cvtndx(v1i, v1) || !cvtndx(v2i, v2) || !cvtndx(v3i, v3)) {
355 >                error(WARNING, "bad vertex reference");
356                  return(0);
357 <
357 >        }
358          if (v1i[1]>=0 && v2i[1]>=0 && v3i[1]>=0) {
359                  v1c = vtlist[v1i[1]];
360                  v2c = vtlist[v2i[1]];
# Line 315 | Line 375 | char   *v1, *v2, *v3;
375  
376  
377   static void
378 < freeverts()                     /* free all vertices */
378 > freeverts(void)                 /* free all vertices */
379   {
380          if (nvs) {
381                  free((void *)vlist);
# Line 333 | Line 393 | freeverts()                    /* free all vertices */
393  
394  
395   static int
396 < newv(x, y, z)                   /* create a new vertex */
397 < double  x, y, z;
396 > newv(                   /* create a new vertex */
397 >        double  x,
398 >        double  y,
399 >        double  z
400 > )
401   {
402          if (!(nvs%CHUNKSIZ)) {          /* allocate next block */
403                  if (nvs == 0)
# Line 354 | Line 417 | double x, y, z;
417  
418  
419   static int
420 < newvn(x, y, z)                  /* create a new vertex normal */
421 < double  x, y, z;
420 > newvn(                  /* create a new vertex normal */
421 >        double  x,
422 >        double  y,
423 >        double  z
424 > )
425   {
426          if (!(nvns%CHUNKSIZ)) {         /* allocate next block */
427                  if (nvns == 0)
# Line 377 | Line 443 | double x, y, z;
443  
444  
445   static int
446 < newvt(x, y)                     /* create a new texture map vertex */
447 < double  x, y;
446 > newvt(                  /* create a new texture map vertex */
447 >        double  x,
448 >        double  y
449 > )
450   {
451          if (!(nvts%CHUNKSIZ)) {         /* allocate next block */
452                  if (nvts == 0)
# Line 397 | Line 465 | double x, y;
465  
466  
467   static void
468 < syntax(er)                      /* report syntax error and exit */
469 < char    *er;
468 > syntax(                 /* report syntax error and exit */
469 >        char    *er
470 > )
471   {
472 <        sprintf(errmsg, "%s: Wavefront syntax error near line %d: %s\n",
472 >        sprintf(errmsg, "%s: Wavefront syntax error near line %d: %s",
473                          inpfile, lineno, er);
474          error(USER, errmsg);
475   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines