ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/convertobj.c
Revision: 2.5
Committed: Fri Apr 16 15:18:33 2021 UTC (3 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.4: +17 -11 lines
Log Message:
fix: added handling of 32-bit RREAL

File Contents

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.5 static const char RCSid[] = "$Id: convertobj.c,v 2.4 2021/04/15 23:51:04 greg Exp $";
3 greg 2.1 #endif
4     /*
5     * convertobj.c
6     *
7     * Convert .OBJ scene to Radiance
8     *
9     * Created by Greg Ward on Thu Apr 22 2004.
10     */
11    
12 greg 2.2 #include "paths.h"
13 greg 2.4 #include "fvect.h"
14     #include "tmesh.h"
15 greg 2.1 #include "rterror.h"
16     #include "objutil.h"
17    
18 greg 2.4 #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; i--; ) /* remove normal indices */
52     f->v[i].nid = -1;
53     for (i = f->nv/2; i--; ) { /* and swap others around */
54     int j = f->nv-1 - i;
55     int vi = f->v[i].vid;
56     int ti = f->v[i].tid;
57     f->v[i].vid = f->v[j].vid;
58     f->v[i].tid = f->v[j].tid;
59     f->v[j].vid = vi;
60     f->v[j].tid = ti;
61     }
62     return(0);
63     }
64     f->flags |= FACE_RESERVED; /* else we got one to smooth */
65     return(1);
66     }
67    
68     /* Callback to write out smoothed Radiance triangle */
69     static int
70     trismooth(Scene *sc, Face *f, void *ptr)
71     {
72     FILE *fp = (FILE *)ptr;
73     BARYCCM bcm;
74 greg 2.5 FVECT coor[3];
75 greg 2.4 int i;
76    
77     if (f->nv != 3)
78     return(0); /* should never happen */
79 greg 2.5 #ifdef SMLFLT
80     for (i = 3; i--; ) {
81     double *v = sc->vert[f->v[i].vid].p;
82     VCOPY(coor[i], v);
83     }
84     if (comp_baryc(&bcm, coor[0], coor[1], coor[2]) < 0)
85     return(0); /* degenerate?? */
86     #else
87     if (comp_baryc(&bcm, sc->vert[f->v[0].vid].p,
88     sc->vert[f->v[1].vid].p, sc->vert[f->v[2].vid].p) < 0)
89 greg 2.4 return(0); /* degenerate?? */
90 greg 2.5 #endif
91 greg 2.4 for (i = 3; i--; ) { /* assign BC normals */
92     float *tnrm = sc->norm[f->v[i].nid];
93 greg 2.5 coor[0][i] = tnrm[0];
94     coor[1][i] = tnrm[1];
95     coor[2][i] = tnrm[2];
96 greg 2.4 } /* print texture */
97     fprintf(fp, "\n%s texfunc %s\n4 dx dy dz %s\n0\n",
98     sc->matname[f->mat], TEXNAME, TCALNAME);
99 greg 2.5 fput_baryc(&bcm, coor, 3, fp); /* with BC normals */
100 greg 2.4 fprintf(fp, "\n%s polygon %s.%d\n0\n0\n9\n",
101     TEXNAME, sc->grpname[f->grp], ++fcnt);
102     for (i = 0; i < 3; i++) { /* then triangle */
103     double *v = sc->vert[f->v[i].vid].p;
104     fprintf(fp, "\t%18.12g %18.12g %18.12g\n", v[0], v[1], v[2]);
105     }
106     return(1);
107     }
108    
109 greg 2.1 /* Callback to convert face to Radiance */
110     static int
111     radface(Scene *sc, Face *f, void *ptr)
112     {
113     FILE *fp = (FILE *)ptr;
114     int i;
115    
116     fprintf(fp, "\n%s polygon %s.%d\n0\n0\n%d\n", sc->matname[f->mat],
117     sc->grpname[f->grp], ++fcnt, 3*f->nv);
118     for (i = 0; i < f->nv; i++) {
119     Vertex *vp = sc->vert + f->v[i].vid;
120     fprintf(fp, "\t%18.12g %18.12g %18.12g\n",
121     vp->p[0], vp->p[1], vp->p[2]);
122     }
123     return(1);
124     }
125    
126     /* Convert indicated faces to Radiance, return # written or -1 on error */
127     int
128     toRadiance(Scene *sc, FILE *fp, int flreq, int flexc)
129     {
130     int n;
131    
132     if (sc == NULL || sc->nfaces <= 0 || fp == NULL)
133     return(0);
134 greg 2.4 /* not passing empties */
135     flexc |= FACE_DEGENERATE;
136     /* reset counter if not stdout */
137     fcnt *= (fp == stdout);
138 greg 2.1 /* write comments */
139     for (n = 0; n < sc->ndescr; n++)
140     fprintf(fp, "# %s\n", sc->descr[n]);
141 greg 2.4 /* flag faces to smooth */
142     n = foreachFace(sc, checksmooth, flreq, flexc, NULL);
143     if (n > 0) { /* write smooth faces */
144     Scene *smoothies = dupScene(sc, flreq|FACE_RESERVED, flexc);
145     if (!smoothies)
146     return(-1);
147     n = triangulateScene(smoothies);
148     if (n >= 0)
149     n = foreachFace(smoothies, trismooth, 0, 0, fp);
150     freeScene(smoothies);
151     }
152     if (n < 0)
153     return(-1);
154     /* write flat faces */
155     n += foreachFace(sc, radface, flreq, flexc|FACE_RESERVED, fp);
156    
157 greg 2.1 if (fflush(fp) < 0) {
158 greg 2.3 error(SYSTEM, "Error writing Radiance scene data");
159 greg 2.1 return(-1);
160     }
161     return(n);
162     }
163    
164     /* Convert faces to Radiance file, return # written or -1 on error */
165     int
166     writeRadiance(Scene *sc, const char *fspec, int flreq, int flexc)
167     {
168     extern char *progname;
169     FILE *fp;
170     int n;
171    
172     if (sc == NULL || sc->nfaces <= 0 || fspec == NULL || !*fspec)
173     return(0);
174     #if POPEN_SUPPORT
175     if (fspec[0] == '!') {
176     if ((fp = popen(fspec+1, "w")) == NULL) {
177     sprintf(errmsg, "%s: cannot execute", fspec);
178     error(SYSTEM, errmsg);
179 greg 2.3 return(-1);
180 greg 2.1 }
181     } else
182     #endif
183     if ((fp = fopen(fspec, "w")) == NULL) {
184     sprintf(errmsg, "%s: cannot open for writing", fspec);
185     error(SYSTEM, errmsg);
186 greg 2.3 return(-1);
187 greg 2.1 }
188     /* start off header */
189     fprintf(fp, "# Radiance scene file converted from .OBJ by %s\n#\n",
190     progname);
191     n = toRadiance(sc, fp, flreq, flexc); /* write file */
192     #if POPEN_SUPPORT
193 greg 2.3 if (fspec[0] == '!') {
194     if (pclose(fp)) {
195     sprintf(errmsg, "%s: error writing to command\n", fspec);
196     error(SYSTEM, errmsg);
197     return(-1);
198     }
199     } else
200 greg 2.1 #endif
201 greg 2.3 fclose(fp); /* close it (already flushed) */
202 greg 2.1 return(n);
203     }