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