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 (3 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

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: writewfobj.c,v 2.4 2020/12/18 00:15:47 greg Exp $";
3 #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 #include "paths.h"
13 #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 deleteUnreferenced(sc); /* clean up, first */
97 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 fprintf(stderr, " Writing faces %-50s\r",
105 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 if (verbose)
113 fprintf(stderr, "Wrote %d faces \n",
114 sc->nfaces);
115 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 return(-1);
134 }
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 return(-1);
141 }
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 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 #endif
154 fclose(fp); /* close it (already flushed) */
155 return(n);
156 }