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

cmd_render.C

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

Generated on Fri Apr 19 02:43:48 2024 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002