Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

cmd_render.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr                                                                       
00003  *cr            (C) Copyright 1995-2008 The Board of Trustees of the           
00004  *cr                        University of Illinois                       
00005  *cr                         All Rights Reserved                        
00006  *cr                                                                   
00007  ***************************************************************************/
00008 
00009 #include <stdlib.h>
00010 #include <tcl.h>
00011 #include "config.h"
00012 #include "utilities.h"
00013 #include "VMDApp.h"
00014 
00015 #define CHECK_RENDER(x) if (!app->filerender_valid(x)) { delete [] extstr; Tcl_AppendResult(interp, "No render method: ", x, NULL); return TCL_ERROR; }
00016 
00017 int text_cmd_render(ClientData cd, Tcl_Interp *interp, int argc,
00018                             const char *argv[]) {
00019 
00020   VMDApp *app = (VMDApp *)cd;
00021 
00022   if(argc >= 3) {
00023     char *extstr = NULL;
00024     if(argc > 3)
00025       extstr = combine_arguments(argc, argv, 3);
00026    
00027     if(!strupncmp(argv[1], "options", CMDLEN)) {
00028       const char *opt = app->filerender_option(argv[2], NULL);
00029       if (!opt) {
00030         Tcl_AppendResult(interp, "render:\n",
00031         "No rendering method '", argv[2], "' available.", NULL);
00032         return TCL_ERROR;
00033       } 
00034       if (extstr == NULL) { //print the option
00035         Tcl_AppendResult(interp, opt, NULL);
00036       } else {
00037         app->filerender_option(argv[2], extstr);
00038         delete [] extstr;
00039 
00040       }
00041       return TCL_OK;  
00042 
00043     } else if (!strupncmp(argv[1], "default", CMDLEN)) { 
00044       const char *opt = app->filerender_default_option(argv[2]);
00045       if (!opt) {
00046         Tcl_AppendResult(interp, "render:\n",
00047         "No rendering method '", argv[2], "' available.", NULL);
00048         return TCL_ERROR;
00049       }
00050       Tcl_AppendResult(interp, opt, NULL);
00051       return TCL_OK;
00052 
00053     } else if (!strupncmp(argv[1], "hasaa", CMDLEN)) {
00054       CHECK_RENDER(argv[2])
00055       Tcl_SetObjResult(interp, Tcl_NewIntObj(app->filerender_has_antialiasing(argv[2])));
00056       return TCL_OK;
00057     
00058     } else if (!strupncmp(argv[1], "aalevel", CMDLEN)) {
00059       int aalevel = -1;
00060       if (argc ==4) {
00061         if (Tcl_GetInt(interp, argv[3], &aalevel) != TCL_OK) 
00062           return TCL_ERROR;
00063       }
00064       CHECK_RENDER(argv[2])
00065       Tcl_SetObjResult(interp, Tcl_NewIntObj(app->filerender_aalevel(argv[2], aalevel)));
00066       return TCL_OK;
00067     } else if (!strupncmp(argv[1], "imagesize", CMDLEN)) {
00068       int w=0, h=0;
00069       CHECK_RENDER(argv[2])
00070       if (argc == 4) {
00071         int listn;
00072         const char **listelem;
00073         if (Tcl_SplitList(interp, argv[3], &listn, &listelem) != TCL_OK) {
00074           return TCL_ERROR;
00075         }
00076         if (listn != 2) {
00077           Tcl_SetResult(interp, (char *) "Image size list must have two elements", TCL_STATIC);
00078           Tcl_Free((char *)listelem);
00079         }
00080         if (Tcl_GetInt(interp, listelem[0], &w) != TCL_OK ||
00081             Tcl_GetInt(interp, listelem[1], &h) != TCL_OK) {
00082           Tcl_Free((char *)listelem);
00083           return TCL_ERROR;
00084         }
00085         Tcl_Free((char *)listelem);
00086       } else if (argc != 3 && argc > 4) {
00087         Tcl_SetResult(interp, (char *) "Usage: render imagesize <method> {width height}", TCL_STATIC);
00088         return TCL_ERROR;
00089       }
00090       if (!app->filerender_imagesize(argv[2], &w, &h)) {
00091         Tcl_SetResult(interp, (char *) "Unable to set/get image size.", TCL_STATIC);
00092         return TCL_ERROR;
00093       }
00094       
00095       char tmpstring[128];
00096       sprintf(tmpstring, "%d %d", w, h);
00097       Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00098       return TCL_OK;
00099     } else if (!strupncmp(argv[1], "hasimagesize", CMDLEN)) {
00100       int rc = app->filerender_has_imagesize(argv[2]);
00101       Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
00102       return TCL_OK;
00103 
00104     } else if (!strupncmp(argv[1], "aspectratio", CMDLEN)) {
00105       CHECK_RENDER(argv[2])
00106       double daspect = -1;
00107       if (argc == 4) {
00108         if (Tcl_GetDouble(interp, argv[3], &daspect) != TCL_OK) 
00109           return TCL_ERROR;
00110       }
00111       float aspect = (float)daspect;
00112       if (!app->filerender_aspectratio(argv[2], &aspect)) {
00113         Tcl_SetResult(interp, (char *) "Unable to get aspect ratio.", TCL_STATIC);
00114         return TCL_ERROR;
00115       }
00116       Tcl_SetObjResult(interp, Tcl_NewDoubleObj(aspect));
00117       return TCL_OK;
00118     } else if (!strupncmp(argv[1], "formats", CMDLEN)) {
00119       CHECK_RENDER(argv[2])
00120       int n = app->filerender_numformats(argv[2]);
00121       for (int i=0; i<n; i++) {
00122         Tcl_AppendElement(interp, app->filerender_get_format(argv[2], i));
00123       }
00124       return TCL_OK;
00125 
00126     } else if (!strupncmp(argv[1], "format", CMDLEN)) {
00127       CHECK_RENDER(argv[2])
00128       if (argc == 3) {
00129         Tcl_AppendElement(interp, app->filerender_cur_format(argv[2]));
00130         return TCL_OK;
00131       }
00132       if (app->filerender_set_format(argv[2], argv[3])) return TCL_OK;
00133       Tcl_AppendResult(interp, 
00134           "Unable to set render output format to ", argv[3]);
00135       return TCL_ERROR;
00136 
00137     } else {
00138       app->display_update();
00139       int retval = app->filerender_render(argv[1], argv[2], extstr);
00140       if(extstr)
00141         delete [] extstr;
00142       return retval ? TCL_OK : TCL_ERROR;
00143     }
00144 
00145   } else if (argc == 2) {
00146     for (int i=0; i<app->filerender_num(); i++) 
00147       Tcl_AppendElement(interp, app->filerender_name(i));
00148     return TCL_OK;
00149   } 
00150 
00151   // if here, something went wrong, so return an error message
00152   Tcl_AppendResult(interp, "render usage:\n",
00153                    "render list\n",
00154                    "render options <method>\n",
00155                    "render options <method> <new default exec command>\n",
00156                    "render default <method>\n",
00157                    "render <method> <filename> [exec command]\n",
00158                     NULL
00159                    );
00160   return TCL_ERROR;
00161 }
00162 
00163 
00164 // XXX this fails to compile on Windows due to Tk's ridiculous 
00165 // insistence of including X11 headers as part of tk.h, we've gotta
00166 // find a better way of coping with this.
00167 #if defined(VMDTK)  && !defined(_MSC_VER)
00168 #include <tk.h>
00169 #include "DisplayDevice.h"
00170 int text_cmd_tkrender(ClientData cd, Tcl_Interp *interp, int argc,
00171                             const char *argv[]) {
00172   if (!Tcl_PkgPresent(interp, "Tk", TK_VERSION, 0)) {
00173     Tcl_SetResult(interp, "Tk not available.", TCL_STATIC);
00174     return TCL_ERROR;
00175   }
00176   if (argc != 2) {
00177     Tcl_SetResult(interp, "tkrender usage:\ntkrender <photo handle>\n",
00178         TCL_STATIC);
00179     return TCL_ERROR;
00180   }
00181   Tk_PhotoHandle handle = Tk_FindPhoto(interp, argv[1]);
00182   if (!handle) {
00183     Tcl_AppendResult(interp, "photo handle '", argv[1], "' has not been created.", NULL);
00184     return TCL_ERROR;
00185   }
00186 
00187   int xs=0, ys=0;
00188   DisplayDevice *display = ((VMDApp *)cd)->display;
00189   display->update(TRUE);
00190   unsigned char *img = display->readpixels(xs, ys);
00191   display->update(TRUE);
00192 
00193   if (!img) {
00194     Tcl_SetResult(interp, "Error reading pixel data from display device.",
00195         TCL_STATIC);
00196     return TCL_ERROR;
00197   }
00198 
00199   // OpenGL and Tk use opposite row order for pixel data.
00200   // Here we assume that readpixels returned data in packed RGB format.
00201   Tk_PhotoImageBlock blk = {
00202     img+3*xs*(ys-1),  // pixel pointer; points to start of top row on screen.
00203     xs,        // width
00204     ys,        // height
00205     -3*xs,     // address difference between two vertically adjacent pixels
00206     3,         // address difference between two horizontally adjacent pixels
00207     {0,1,2,3}  // r, g, b, a offsets within each pixel.
00208   };
00209   // set the size of the photo object to match the screen size.  One could
00210   // also create a new photo object with no size information, but that would
00211   // likely to lead to memory leaks in various scripts.  There's also currently
00212   // no way to read out the size of the display in VMD (sad, I know), so
00213   // it's just easier to set it here.
00214 #if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION < 5
00215   Tk_PhotoSetSize(handle, xs, ys);
00216   Tk_PhotoPutBlock(handle, &blk, 0, 0, xs, ys, TK_PHOTO_COMPOSITE_SET);
00217 #else
00218   Tk_PhotoSetSize(interp, handle, xs, ys);
00219   Tk_PhotoPutBlock(interp, handle, &blk, 0, 0, xs, ys, TK_PHOTO_COMPOSITE_SET);
00220 #endif
00221   free(img);
00222   return TCL_OK;
00223 }
00224 
00225 #endif

Generated on Fri Jul 4 01:27:15 2008 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002