1 /* Copyright (C) 1992-1998 The Geometry Center
2 * Copyright (C) 1998-2000 Stuart Levy, Tamara Munzner, Mark Phillips
3 *
4 * This file is part of Geomview.
5 *
6 * Geomview is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * Geomview is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with Geomview; see the file COPYING. If not, write
18 * to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
19 * USA, or visit http://www.gnu.org.
20 */
21
22 #if HAVE_CONFIG_H
23 # include "config.h"
24 #endif
25
26 #if 0
27 static char copyright[] = "Copyright (C) 1992-1998 The Geometry Center\n\
28 Copyright (C) 1998-2000 Stuart Levy, Tamara Munzner, Mark Phillips";
29 #endif
30
31
32 /* Authors: Scott Wisdom, Stuart Levy, Tamara Munzner, Mark Phillips */
33
34 #include "common.h"
35 #include "drawer.h"
36 #include "lang.h"
37 #include "ui.h"
38 #include "mg.h"
39 #include "rman.h"
40
41 #include "mgrib.h"
42 #include <string.h>
43
44 /* for mgrib */
45
46 static char defname[] = "geom";
47 struct _rman rman = {MG_RIBCYLINDER, MG_RIBASCII, 0, MG_RIBTIFF, MG_RIBDOBG, defname};
48
49 static int ribtype(char *s, int type);
50
51 static char RHelp[] = "\
52 Renderman:\n\
53 RR send RIB output to <fileprefix>NNN.rib (default fileprefix == \"geom\")\n\
54 RC Emulate lines using cylinders (default)\n\
55 RP Emulate lines using polygons\n\
56 Ra choose ASCII RIB format (default)\n\
57 Rb choose BINARY RIB format\n\
58 Rt choose Display token to specify .tiff file (default)\n\
59 Rf choose Display token to specify framebuffer\n\
60 Rs Simulate background color with Polygon (default)\n\
61 Rx No background simulation - fully transparent (alpha) background\n\
62 ";
63
64 /*
65 * Interpret R<suffix> keyboard commands.
66 */
rman_do(int suffix,int hasnumber,int number)67 void rman_do(int suffix, int hasnumber, int number)
68 {
69 switch(suffix) {
70 case '?': /* help message */
71 printf("%s", RHelp);
72 break;
73
74 case 'R': /* Write RenderMan snapshot */
75 if(hasnumber) rman.seqno = number;
76 gv_rib_snapshot(FOCUSID, NULL);
77 break;
78
79 case 'C': /* (for photorman) chooses cylinder line emulation */
80 rman.line = MG_RIBCYLINDER;
81 break;
82
83 case 'P': /* (for photorman) chooses polygon line emulation */
84 rman.line = MG_RIBPOLYGON;
85 break;
86
87 case 'a': /* chooses ASCII format for RIB output */
88 rman.format = MG_RIBASCII;
89 break;
90
91 case 'b': /* chooses BINARY format for RIB output */
92 rman.format = MG_RIBBINARY;
93 break;
94 case 't': /* toggles Display to be tiff file or framebuffer */
95 rman.display = MG_RIBTIFF;
96 break;
97 case 'f': /* choose Display token to specify framebuffer */
98 rman.display = MG_RIBFRAME;
99 break;
100 case 's': /* simulate background color with polygon */
101 rman.background = MG_RIBDOBG;
102 break;
103 case 'x': /* no background color simulation - transparent background */
104 rman.background = MG_RIBNOBG;
105 break;
106 }
107
108 }
109
110 LDEFINE(rib_display, LVOID,
111 "(rib-display [frame|tiff] FILEPREFIX)\n\
112 Set Renderman display to framebuffer (popup screen window) or a\n\
113 TIFF format disk file. FILEPREFIX is used to construct\n\
114 names of the form \"prefixNNNN.suffix\". (i.e. foo0000.rib)\n\
115 The number is incremented on every call to \"rib-snapshot\" and\n\
116 reset to 0000 when \"rib-display\" is called. TIFF files are given\n\
117 the same prefix and number as the RIB file (i.e. foo0004.rib\n\
118 generates foo0004.tiff). The default FILEPREFIX is \"geom\" and\n\
119 the default format is TIFF. (Note that geomview just generates a\n\
120 RIB file, which must then be rendered.)")
121 {
122 char *fileprefix;
123 int type;
124
125 LDECLARE(("rib-display", LBEGIN,
126 LKEYWORD, &type,
127 LSTRING, &fileprefix,
128 LEND));
129 type = ribtype("rib-display", type);
130 if (rman.fileprefix && rman.fileprefix != defname) OOGLFree(rman.fileprefix);
131 rman.fileprefix = strdup(fileprefix);
132 rman.display = type;
133 rman.seqno = 0;
134 return Lt;
135 }
136
137 LDEFINE(rib_snapshot, LVOID,
138 "(rib-snapshot CAM-ID [filename])\n\
139 Write Renderman snapshot (in RIB format) of CAM-ID to <filename>.\n\
140 If no filename specified, see \"rib-display\" for explanation of\n\
141 the filename used.")
142 {
143 DView *view;
144 Camera *cam = NULL;
145 WnWindow *win;
146 const Appearance *ap;
147 mgcontext *ctx;
148 char fname[1024];
149 char displayname[1024];
150 char *fileprefix = rman.fileprefix ? rman.fileprefix : defname;
151 char *strend = NULL;
152 FILE *f = NULL;
153 int id, mgspace;
154 char *filename = NULL;
155
156 LDECLARE(("rib-snapshot", LBEGIN,
157 LID, &id,
158 LOPTIONAL, LSTRING, &filename,
159 LEND));
160
161
162 if (filename) { /* explicit filename, don't use incremented fileprefix */
163 if (filename[0] == '-') { /* treat '-' as stdout */
164 sprintf(fname, "stdout");
165 sprintf(displayname, "geom.tiff");
166 f = stdout;
167 } else {
168 sprintf(fname, "%s", filename);
169 if ((strend = strstr(filename, ".rib"))) { /* toss ".rib" */
170 strncpy(displayname, filename, strend-filename);
171 displayname[strend-filename] = '\0';
172 } else {
173 strcpy(displayname, filename);
174 }
175 strcat(displayname, ".tiff");
176 f = fopen(fname, "w");
177 }
178 } else { /* autoincrement */
179 sprintf(fname, "%s%04d.rib", fileprefix, rman.seqno);
180 sprintf(displayname, "%s%04d.tiff", fileprefix, rman.seqno);
181 f = fopen(fname, "w");
182 rman.seqno++;
183 }
184
185 if(f == NULL) {
186 OOGLError(1, "Can't create %s: %s", fname, sperror());
187 return Lnil;
188 }
189
190 if (rman.display == MG_RIBFRAME) {
191 strcpy(displayname, fname);
192 }
193
194 fprintf(stderr, "Writing %s ...", fname);
195
196 if(!ISCAM(id) || (view = (DView *)drawer_get_object(id)) == NULL) {
197 OOGLError(1, "rib-snapshot: bad view!");
198 return Lnil;
199 }
200 mgctxselect(view->mgctx);
201 mgctxget(MG_CAMERA, &cam);
202 mgctxget(MG_SPACE, &mgspace);
203 #if 0
204 /* Copy so that changed flags are set <- cH: what does that mean ???? */
205 ap = ApCopy(mggetappearance(NULL), NULL);
206 #else
207 ap = mggetappearance();
208 #endif
209 mgctxget(MG_WINDOW, &win);
210 if(cam == NULL || ap == NULL || win == NULL) {
211 OOGLError(1, "rib-snapshot: trouble, %x %x %x", cam,ap,win);
212 return Lnil;
213 }
214
215 mgdevice_RIB();
216 ctx = mgctxcreate(MG_CAMERA, cam,
217 MG_APPEAR, ap,
218 MG_WINDOW, win,
219 MG_BACKGROUND, &view->backcolor,
220 MG_SPACE, spaceof(WORLDGEOM),
221 MG_RIBFORMAT, rman.format,
222 MG_RIBLINEMODE, rman.line,
223 MG_RIBFILE, f,
224 MG_RIBDISPLAY, rman.display,
225 MG_RIBDISPLAYNAME, displayname,
226 MG_RIBBACKING, rman.background,
227 MG_RIBSCENE, "geomview RIB snapshot",
228 MG_RIBCREATOR, "mgrib driver - geomview",
229 MG_SPACE, mgspace,
230 MG_END);
231 {
232 /* Try to be as realistic as possible when dumping a RenderMan snapshot.
233 * Create a RenderMan drawing context, install (hopefully) all the
234 * attributes that draw_view() doesn't reset on its own,
235 * plug the RenderMan ctx into the camera, and force a redraw.
236 * Then undo the subterfuge.
237 */
238 bool oldredraw = view->redraw;
239 bool oldchanged = view->changed;
240 mgcontext *oldctx = view->mgctx;
241 view->mgctx = ctx;
242 view->redraw = true;
243 gv_draw(view->id);
244 view->redraw = oldredraw, view->changed = oldchanged;
245 view->mgctx = oldctx;
246 }
247 mgrib_flushbuffer(); /* now necessary to flush buffer to file */
248
249 mgctxdelete(ctx);
250 #if 0
251 ApDelete(ap);
252 #endif
253 mgctxselect(view->mgctx); /* Revert to previous device */
254
255 if (f != stdout)
256 fclose(f);
257 fprintf(stderr, " done.\n");
258
259 return Lt;
260 }
261
ribtype(char * s,int type)262 static int ribtype(char *s, int type)
263 {
264 switch (type) {
265 case TIFF_KEYWORD: return MG_RIBTIFF;
266 case FRAME_KEYWORD: return MG_RIBFRAME;
267 default:
268 fprintf(stderr, "%s: invalid rib type (assuming \"tiff\")\n",s);
269 return MG_RIBTIFF;
270 }
271 }
272
273 /*
274 * Local Variables: ***
275 * mode: c ***
276 * c-basic-offset: 2 ***
277 * End: ***
278 */
279