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

Comparing ray/src/common/convertobj.c (file contents):
Revision 2.1 by greg, Mon Mar 30 18:28:35 2020 UTC vs.
Revision 2.6 by greg, Sat Apr 17 14:51:33 2021 UTC

# Line 9 | Line 9 | static const char RCSid[] = "$Id$";
9   *  Created by Greg Ward on Thu Apr 22 2004.
10   */
11  
12 < #include <stdio.h>
12 > #include "paths.h"
13 > #include "fvect.h"
14 > #include "tmesh.h"
15   #include "rterror.h"
16   #include "objutil.h"
17  
18 + #define TEXNAME         "T-nor"
19 +
20 + static int      fcnt = 0;                       /* face output counter */
21 +
22 + /* Callback for face smoothing detection */
23 + static int
24 + checksmooth(Scene *sc, Face *f, void *ptr)
25 + {
26 +        int     nrev = 0;
27 +        Normal  fnrm;
28 +        int     i;
29 +
30 +        f->flags &= ~FACE_RESERVED;             /* using reserved flag */
31 +
32 +        for (i = f->nv; i--; )
33 +                if (f->v[i].nid < 0)
34 +                        return(0);              /* missing normal */
35 +
36 +        if (faceArea(sc, f, fnrm) == 0)         /* degenerate?? */
37 +                return(0);
38 +                                                /* check each normal */
39 +        for (i = f->nv; i--; ) {
40 +                float   *tnrm = sc->norm[f->v[i].nid];
41 +                double  dprod = DOT(tnrm, fnrm);
42 +                if (dprod >= COSTOL)            /* this one agrees? */
43 +                        continue;
44 +                if (dprod > -COSTOL)            /* active smoothing? */
45 +                        break;
46 +                ++nrev;                         /* count opposite face normal */
47 +        }
48 +        if ((i < 0) & !nrev)                    /* all normals agree w/ face? */
49 +                return(0);
50 +        if (nrev == f->nv) {                    /* all reversed? */
51 +                for (i = f->nv/2; i--; ) {      /* swap vertices around */
52 +                        int     j = f->nv-1 - i;
53 +                        VertEnt tve = f->v[i];
54 +                        f->v[i] = f->v[j];
55 +                        f->v[j] = tve;
56 +                }
57 +                return(0);
58 +        }
59 +        f->flags |= FACE_RESERVED;              /* else we got one to smooth */
60 +        return(1);
61 + }
62 +
63 + /* Callback to write out smoothed Radiance triangle */
64 + static int
65 + trismooth(Scene *sc, Face *f, void *ptr)
66 + {
67 +        FILE            *fp = (FILE *)ptr;
68 +        BARYCCM         bcm;
69 +        FVECT           coor[3];
70 +        int             i;
71 +
72 +        if (f->nv != 3)
73 +                return(0);                      /* should never happen */
74 + #ifdef  SMLFLT
75 +        for (i = 3; i--; ) {
76 +                double  *v = sc->vert[f->v[i].vid].p;
77 +                VCOPY(coor[i], v);
78 +        }
79 +        if (comp_baryc(&bcm, coor[0], coor[1], coor[2]) < 0)
80 +                return(0);                      /* degenerate?? */
81 + #else
82 +        if (comp_baryc(&bcm, sc->vert[f->v[0].vid].p,
83 +                        sc->vert[f->v[1].vid].p, sc->vert[f->v[2].vid].p) < 0)
84 +                return(0);                      /* degenerate?? */
85 + #endif
86 +        for (i = 3; i--; ) {                    /* assign BC normals */
87 +                float   *tnrm = sc->norm[f->v[i].nid];
88 +                coor[0][i] = tnrm[0];
89 +                coor[1][i] = tnrm[1];
90 +                coor[2][i] = tnrm[2];
91 +        }                                       /* print texture */
92 +        fprintf(fp, "\n%s texfunc %s\n4 dx dy dz %s\n0\n",
93 +                        sc->matname[f->mat], TEXNAME, TCALNAME);
94 +        fput_baryc(&bcm, coor, 3, fp);          /* with BC normals */
95 +        fprintf(fp, "\n%s polygon %s.%d\n0\n0\n9\n",
96 +                        TEXNAME, sc->grpname[f->grp], ++fcnt);
97 +        for (i = 0; i < 3; i++) {               /* then triangle */
98 +                double  *v = sc->vert[f->v[i].vid].p;
99 +                fprintf(fp, "\t%18.12g %18.12g %18.12g\n", v[0], v[1], v[2]);
100 +        }
101 +        return(1);
102 + }
103 +
104   /* Callback to convert face to Radiance */
105   static int
106   radface(Scene *sc, Face *f, void *ptr)
107   {
20        static int      fcnt = 0;
108          FILE            *fp = (FILE *)ptr;
109          int             i;
110          
24        if (f->flags & FACE_DEGENERATE)
25                return(0);
111          fprintf(fp, "\n%s polygon %s.%d\n0\n0\n%d\n", sc->matname[f->mat],
112                                  sc->grpname[f->grp], ++fcnt, 3*f->nv);
113          for (i = 0; i < f->nv; i++) {
# Line 41 | Line 126 | toRadiance(Scene *sc, FILE *fp, int flreq, int flexc)
126  
127          if (sc == NULL || sc->nfaces <= 0 || fp == NULL)
128                  return(0);
129 +                                                /* not passing empties */
130 +        flexc |= FACE_DEGENERATE;
131 +                                                /* reset counter if not stdout */
132 +        fcnt *= (fp == stdout);
133                                                  /* write comments */
134          for (n = 0; n < sc->ndescr; n++)
135                  fprintf(fp, "# %s\n", sc->descr[n]);
136 <                                                /* write faces */
137 <        n = foreachFace(sc, radface, flreq, flexc, (void *)fp);
136 >                                                /* flag faces to smooth */
137 >        n = foreachFace(sc, checksmooth, flreq, flexc, NULL);
138 >        if (n > 0) {                            /* write smooth faces */
139 >                Scene   *smoothies = dupScene(sc, flreq|FACE_RESERVED, flexc);
140 >                if (!smoothies)
141 >                        return(-1);
142 >                n = triangulateScene(smoothies);
143 >                if (n >= 0)
144 >                        n = foreachFace(smoothies, trismooth, 0, 0, fp);
145 >                freeScene(smoothies);
146 >        }
147 >        if (n < 0)
148 >                return(-1);
149 >                                                /* write flat faces */
150 >        n += foreachFace(sc, radface, flreq, flexc|FACE_RESERVED, fp);
151 >
152          if (fflush(fp) < 0) {
153 <                error(SYSTEM, "Error flushing Radiance scene data");
153 >                error(SYSTEM, "Error writing Radiance scene data");
154                  return(-1);
155          }
156          return(n);
# Line 68 | Line 171 | writeRadiance(Scene *sc, const char *fspec, int flreq,
171                  if ((fp = popen(fspec+1, "w")) == NULL) {
172                          sprintf(errmsg, "%s: cannot execute", fspec);
173                          error(SYSTEM, errmsg);
174 <                        return(0);
174 >                        return(-1);
175                  }
176          } else
177   #endif
178          if ((fp = fopen(fspec, "w")) == NULL) {
179                  sprintf(errmsg, "%s: cannot open for writing", fspec);
180                  error(SYSTEM, errmsg);
181 <                return(0);
181 >                return(-1);
182          }
183                                                  /* start off header */
184          fprintf(fp, "# Radiance scene file converted from .OBJ by %s\n#\n",
185                                                  progname);
186          n = toRadiance(sc, fp, flreq, flexc);   /* write file */
187   #if POPEN_SUPPORT
188 <        if (fspec[0] == '!')
189 <                pclose(fp);
190 <        else
188 >        if (fspec[0] == '!') {
189 >                if (pclose(fp)) {
190 >                        sprintf(errmsg, "%s: error writing to command\n", fspec);
191 >                        error(SYSTEM, errmsg);
192 >                        return(-1);
193 >                }
194 >        } else
195   #endif
196 <        fclose(fp);                             /* close file */
196 >        fclose(fp);                             /* close it (already flushed) */
197          return(n);
198   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines