ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/writewfobj.c
Revision: 2.5
Committed: Fri Feb 12 01:57:49 2021 UTC (4 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R4, HEAD
Changes since 2.4: +2 -95 lines
Log Message:
feat: added ability to choose faces when duplicating scene

File Contents

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.5 static const char RCSid[] = "$Id: writewfobj.c,v 2.4 2020/12/18 00:15:47 greg Exp $";
3 greg 2.1 #endif
4     /*
5     * writewfobj.c
6     *
7     * Routines for writing out Wavefront file.
8     *
9     * Created by Greg Ward on Thu Feb 12 2004.
10     */
11    
12 greg 2.2 #include "paths.h"
13 greg 2.1 #include "rterror.h"
14     #include "objutil.h"
15    
16     /* Write out header comments */
17     static void
18     write_header(Scene *sc, FILE *fp)
19     {
20     int i;
21    
22     for (i = 0; i < sc->ndescr; i++)
23     fprintf(fp, "# %s\n", sc->descr[i]);
24     fputs("#\n", fp);
25     fprintf(fp, "# %d final faces\n", sc->nfaces);
26     fprintf(fp,
27     "#\t%d vertices, %d texture coordinates, %d surface normals\n",
28     sc->nverts, sc->ntex, sc->nnorms);
29     fputs("#\n\n", fp);
30     }
31    
32     /* Write out vertex lists */
33     static void
34     write_verts(Scene *sc, FILE *fp)
35     {
36     int i;
37    
38     fputs("# Vertex positions\n", fp);
39     for (i = 0; i < sc->nverts; i++)
40     fprintf(fp, "v %.12g %.12g %.12g\n",
41     sc->vert[i].p[0],
42     sc->vert[i].p[1],
43     sc->vert[i].p[2]);
44     fputs("\n# Vertex texture coordinates\n", fp);
45     for (i = 0; i < sc->ntex; i++)
46     fprintf(fp, "vt %.6g %.6g\n",
47     sc->tex[i].u, sc->tex[i].v);
48     fputs("\n# Vertex normals\n", fp);
49     for (i = 0; i < sc->nnorms; i++)
50     fprintf(fp, "vn %.6f %.6f %.6f\n",
51     sc->norm[i][0],
52     sc->norm[i][1],
53     sc->norm[i][2]);
54     fputc('\n', fp);
55     }
56    
57     /* Write out an object group */
58     static void
59     write_group(const Scene *sc, int gid, FILE *fp)
60     {
61     int mid = -1;
62     const Face *f;
63     int j;
64    
65     fprintf(fp, "# Face group\ng %s\n", sc->grpname[gid]);
66     for (f = sc->flist; f != NULL; f = f->next) {
67     if (f->grp != gid)
68     continue;
69     if (f->mat != mid)
70     fprintf(fp, "usemtl %s\n", sc->matname[mid=f->mat]);
71     fputc('f', fp);
72     for (j = 0; j < f->nv; j++) {
73     fprintf(fp, " %d/", f->v[j].vid - sc->nverts);
74     if (f->v[j].tid >= 0)
75     fprintf(fp, "%d/", f->v[j].tid - sc->ntex);
76     else
77     fputc('/', fp);
78     if (f->v[j].nid >= 0)
79     fprintf(fp, "%d", f->v[j].nid - sc->nnorms);
80     }
81     fputc('\n', fp);
82     }
83     fprintf(fp, "# End of face group %s\n\n", sc->grpname[gid]);
84     }
85    
86     /* Write a .OBJ to stream, return # faces written */
87     int
88     toOBJ(Scene *sc, FILE *fp)
89     {
90     int i;
91    
92     if (sc == NULL || sc->nfaces <= 0 || fp == NULL)
93     return(0);
94     if (verbose)
95     fputs(" Removing unreferenced vertices\r", stderr);
96 greg 2.5 deleteUnreferenced(sc); /* clean up, first */
97 greg 2.1 if (verbose)
98     fputs(" Writing vertices \r", stderr);
99     write_header(sc, fp); /* write out header */
100     write_verts(sc, fp); /* write out vertex lists */
101     /* write out each object group */
102     for (i = 0; i < sc->ngrps; i++) {
103     if (verbose)
104 greg 2.4 fprintf(stderr, " Writing faces %-50s\r",
105 greg 2.1 sc->grpname[i]);
106     write_group(sc, i, fp);
107     }
108     if (fflush(fp) < 0) {
109     error(SYSTEM, "Error flushing .OBJ output");
110     return(-1);
111     }
112 greg 2.4 if (verbose)
113     fprintf(stderr, "Wrote %d faces \n",
114     sc->nfaces);
115 greg 2.1 return(sc->nfaces);
116     }
117    
118     /* Write a .OBJ file, return # faces written */
119     int
120     writeOBJ(Scene *sc, const char *fspec)
121     {
122     extern char *progname;
123     FILE *fp;
124     int n;
125    
126     if (sc == NULL || sc->nfaces <= 0 || fspec == NULL || !*fspec)
127     return(0);
128     #if POPEN_SUPPORT
129     if (fspec[0] == '!') {
130     if ((fp = popen(fspec+1, "w")) == NULL) {
131     sprintf(errmsg, "%s: cannot execute", fspec);
132     error(SYSTEM, errmsg);
133 greg 2.3 return(-1);
134 greg 2.1 }
135     } else
136     #endif
137     if ((fp = fopen(fspec, "w")) == NULL) {
138     sprintf(errmsg, "%s: cannot open for writing", fspec);
139     error(SYSTEM, errmsg);
140 greg 2.3 return(-1);
141 greg 2.1 }
142     /* start off header */
143     fprintf(fp, "# Wavefront .OBJ file created by %s\n#\n", progname);
144     n = toOBJ(sc, fp); /* write scene */
145     #if POPEN_SUPPORT
146 greg 2.3 if (fspec[0] == '!') {
147     if (pclose(fp)) {
148     sprintf(errmsg, "%s: error writing to command\n", fspec);
149     error(SYSTEM, errmsg);
150     return(-1);
151     }
152     } else
153 greg 2.1 #endif
154 greg 2.3 fclose(fp); /* close it (already flushed) */
155 greg 2.1 return(n);
156     }