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

TclGraphics.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: TclGraphics.C,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.60 $       $Date: 2020/11/30 07:09:12 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  *   Parse the text input into a new graphics element.
00019  *
00020  ***************************************************************************/
00021 
00022 
00023 #include <stdlib.h> 
00024 #include "VMDApp.h"
00025 #include "Molecule.h"
00026 #include "MoleculeList.h"
00027 #include "MaterialList.h"
00028 #include "tcl.h"
00029 #include "TclCommands.h" // for my own, external function definitions
00030 #include "Scene.h"
00031 #include "MoleculeGraphics.h"
00032 
00033 // option 's' needs at least 'n' parameters
00034 #define AT_LEAST(n, s)                                            \
00035 {                                                                 \
00036   if (argc < n) {                                                 \
00037     Tcl_SetResult(interp,                                         \
00038               (char *) "graphics: " s ": not enough parameters",  \
00039               TCL_STATIC);                                        \
00040     return TCL_ERROR;                                             \
00041   }                                                               \
00042 }
00043 
00044 // option 's' takes exactly 'n' parameters
00045 #define MUST_HAVE(n, s)                                           \
00046 {                                                                 \
00047   if (argc != n) {                                                \
00048     Tcl_SetResult(interp,                                         \
00049       (char *) "graphics: " s ": incorrect number of parameters", \
00050       TCL_STATIC);                                                \
00051     return TCL_ERROR;                                             \
00052   }                                                               \
00053 }
00054 
00055 // evaluate data for a triangle
00056 static int tcl_graphics_triangle(MoleculeGraphics *gmol, 
00057                                  int argc, const char *argv[],
00058                                  Tcl_Interp *interp)
00059 {
00060   // the first three are {x, y, z} coordinates
00061   MUST_HAVE(3, "triangle");
00062   float vals[9];
00063   if (tcl_get_vector(argv[0], vals+0, interp) != TCL_OK ||
00064       tcl_get_vector(argv[1], vals+3, interp) != TCL_OK ||
00065       tcl_get_vector(argv[2], vals+6, interp) != TCL_OK   ) {
00066     return TCL_ERROR;
00067   }
00068 
00069   // I have a triangle, so add it
00070   char tmpstring[64];
00071   sprintf(tmpstring, "%d", gmol->add_triangle(vals+0, vals+3, vals+6));
00072   Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00073   return TCL_OK;
00074 }
00075 
00076 // a triangle with the normals specified
00077 static int tcl_graphics_trinorm(MoleculeGraphics *gmol, 
00078                                 int argc, const char *argv[],
00079                                 Tcl_Interp *interp)
00080 {
00081   // the first three are {x, y, z} coordinates
00082   // the next three are {x, y, z} normals
00083   MUST_HAVE(6, "trinorm");
00084   float vals[19];
00085   if (tcl_get_vector(argv[0], vals+0,  interp) != TCL_OK ||
00086       tcl_get_vector(argv[1], vals+3,  interp) != TCL_OK ||
00087       tcl_get_vector(argv[2], vals+6,  interp) != TCL_OK ||
00088       tcl_get_vector(argv[3], vals+9,  interp) != TCL_OK ||
00089       tcl_get_vector(argv[4], vals+12, interp) != TCL_OK ||
00090       tcl_get_vector(argv[5], vals+15, interp) != TCL_OK   ) {
00091     return TCL_ERROR;
00092   }
00093 
00094   // I have a triangle, so add it
00095   char tmpstring[64];
00096   sprintf(tmpstring, "%d",
00097           gmol->add_trinorm(vals+0, vals+3, vals+6, 
00098                             vals+9, vals+12, vals+15));
00099   Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00100   return TCL_OK;
00101 }
00102 
00103 // a triangle with the normals and colors specified
00104 static int tcl_graphics_tricolor(MoleculeGraphics *gmol, 
00105                                 int argc, const char *argv[],
00106                                 Tcl_Interp *interp)
00107 {
00108   // the first three are {x, y, z} coordinates
00109   // the next three are {x, y, z} normals
00110   MUST_HAVE(9, "tricolor");
00111   float vals[19];
00112   if (tcl_get_vector(argv[0], vals+0,  interp) != TCL_OK ||
00113       tcl_get_vector(argv[1], vals+3,  interp) != TCL_OK ||
00114       tcl_get_vector(argv[2], vals+6,  interp) != TCL_OK ||
00115       tcl_get_vector(argv[3], vals+9,  interp) != TCL_OK ||
00116       tcl_get_vector(argv[4], vals+12, interp) != TCL_OK ||
00117       tcl_get_vector(argv[5], vals+15, interp) != TCL_OK   ) {
00118     return TCL_ERROR;
00119   }
00120   int c1, c2, c3;
00121   if (Tcl_GetInt(interp, argv[6], &c1) != TCL_OK ||
00122       Tcl_GetInt(interp, argv[7], &c2) != TCL_OK ||
00123       Tcl_GetInt(interp, argv[8], &c3) != TCL_OK) {
00124     return TCL_ERROR;
00125   }
00126 
00127   // I have a triangle, so add it
00128   char tmpstring[64];
00129   sprintf(tmpstring, "%d",
00130           gmol->add_tricolor(vals+0, vals+3, vals+6, 
00131                             vals+9, vals+12, vals+15, c1, c2, c3));
00132   Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00133   return TCL_OK;
00134 }
00135 
00136 // a cylinder has endpoints, radius, and resolution
00137 static int tcl_graphics_cylinder(MoleculeGraphics *gmol, 
00138                                  int argc, const char *argv[],
00139                                  Tcl_Interp *interp)
00140 {
00141   // the first two are {x, y, z} coordinates
00142   AT_LEAST(2, "cylinder");
00143   float vals[6];
00144   if (tcl_get_vector(argv[0], vals+0,  interp) != TCL_OK ||
00145       tcl_get_vector(argv[1], vals+3,  interp) != TCL_OK) {
00146     return TCL_ERROR;
00147   }
00148   
00149   // get the optional values
00150   double radius = 1.0;
00151   int resolution = 6;
00152   int filled = 0;
00153   argc -= 2;
00154   argv += 2;
00155   if (argc %2) {
00156     Tcl_SetResult(interp, (char *) "graphics: cylinder has wrong number of options", TCL_STATIC);
00157     return TCL_ERROR;
00158   }
00159   while (argc) {
00160     if (!strcmp(argv[0], "radius")) {
00161       if (Tcl_GetDouble(interp, argv[1], &radius) != TCL_OK) {
00162         return TCL_ERROR;
00163       }
00164       if (radius <0) radius = 0;
00165       argc -= 2;
00166       argv += 2;
00167       continue;
00168     }
00169     if (!strcmp(argv[0], "resolution")) {
00170       if (Tcl_GetInt(interp, argv[1], &resolution) != TCL_OK) {
00171         return TCL_ERROR;
00172       }
00173       if (resolution < 0) resolution = 0;
00174       if (resolution > 30) resolution = 30;
00175       argc -= 2;
00176       argv += 2;
00177       continue;
00178     }
00179     if (!strcmp(argv[0], "filled")) {
00180       if (Tcl_GetBoolean(interp, argv[1], &filled) != TCL_OK) {
00181         return TCL_ERROR;
00182       }
00183       argc -= 2;
00184       argv += 2;
00185       continue;
00186     }
00187     // reaching here is an error
00188     Tcl_AppendResult(interp, "graphics: unknown option for cylinder: ",
00189                      argv[0], NULL);
00190     return TCL_ERROR;
00191   }
00192   
00193   // I have a cylinder, so add it
00194   char tmpstring[64];
00195   sprintf(tmpstring, "%d",
00196           gmol->add_cylinder(vals+0, vals+3, (float) radius, resolution, filled));
00197   Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00198   return TCL_OK;
00199 }
00200 
00201 // only has coordinates
00202 static int tcl_graphics_point(MoleculeGraphics *gmol, 
00203                               int argc, const char *argv[],
00204                               Tcl_Interp *interp)
00205 {
00206   MUST_HAVE(1, "point");
00207   float vals[3];
00208   if (tcl_get_vector(argv[0], vals+0, interp) != TCL_OK) {
00209     return TCL_ERROR;
00210   }
00211 
00212   // we've got a point, so add it
00213   char tmpstring[64];
00214   sprintf(tmpstring, "%d", gmol->add_point(vals+0));
00215   Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00216   return TCL_OK;
00217 }
00218 
00219 // only has coordinates
00220 static int tcl_graphics_pickpoint(MoleculeGraphics *gmol, 
00221                               int argc, const char *argv[],
00222                               Tcl_Interp *interp)
00223 {
00224   MUST_HAVE(1, "pickpoint");
00225   float vals[3];
00226   if (tcl_get_vector(argv[0], vals+0, interp) != TCL_OK) {
00227     return TCL_ERROR;
00228   }
00229 
00230   // we've got a point, so add it
00231   char tmpstring[64];
00232   sprintf(tmpstring, "%d", gmol->add_pickpoint(vals+0));
00233   Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00234   return TCL_OK;
00235 }
00236 
00237 
00238 // has begin and end points, a "style", and a width
00239 static int tcl_graphics_line(MoleculeGraphics *gmol, 
00240                              int argc, const char *argv[],
00241                              Tcl_Interp *interp)
00242 {
00243   // just need the start and end values
00244   AT_LEAST(2, "line");
00245   float vals[6];
00246   if (tcl_get_vector(argv[0], vals+0, interp) != TCL_OK ||
00247       tcl_get_vector(argv[1], vals+3, interp) != TCL_OK) {
00248     return TCL_ERROR;
00249   }
00250   // options:
00251   //  'style' is "solid" or "dashed"
00252   //  'width' is 0 .. 255;
00253   int line_style = ::SOLIDLINE;
00254   int width = 1;
00255   argc -= 2;
00256   argv += 2;
00257   if (argc %2) {
00258     Tcl_SetResult(interp, (char *) "graphics: line has wrong number of options", TCL_STATIC);
00259     return TCL_ERROR;
00260   }
00261   while (argc) {
00262     if (!strcmp(argv[0], "style")) {
00263       if (!strcmp(argv[1], "solid")) {
00264         line_style = ::SOLIDLINE;
00265       } else if (!strcmp(argv[1], "dashed")) {
00266         line_style = ::DASHEDLINE;
00267       } else {
00268         Tcl_AppendResult(interp, "graphics: don't understand the line style ",
00269                          argv[1], NULL);
00270         return TCL_ERROR;
00271       }
00272     } else if (!strcmp(argv[0], "width")) {
00273       if (Tcl_GetInt(interp, argv[1], &width) != TCL_OK) {
00274         return TCL_ERROR;
00275       }
00276       if (width > 255) width = 255;
00277       if (width < 0) width = 0;
00278     } else {
00279       Tcl_AppendResult(interp, "graphics: don't understand the line option ",
00280                        argv[0], NULL);
00281       return TCL_ERROR;
00282     }
00283     argc -= 2;
00284     argv += 2;
00285   }
00286 
00287   // otherwise, just draw the line
00288   char tmpstring[64];
00289   sprintf(tmpstring, "%d", gmol->add_line(vals+0, vals+3, line_style, width));
00290   Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00291   return TCL_OK;
00292 }
00293 
00294 // turn them on or off
00295 static int tcl_graphics_materials(MoleculeGraphics *gmol,
00296                                   int argc, const char *argv[],
00297                                   Tcl_Interp *interp)
00298 {
00299   MUST_HAVE(1, "materials");
00300   int val;
00301   if (Tcl_GetBoolean(interp, argv[0], &val) != TCL_OK) {
00302     return TCL_ERROR;
00303   }
00304   
00305   // enable/disable materials
00306   char tmpstring[64];
00307   sprintf(tmpstring, "%d", gmol->use_materials(val));
00308   Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00309   return TCL_OK;
00310 }
00311 
00312 // set material for this graphics molecule
00313 static int tcl_graphics_material(MoleculeGraphics *gmol,
00314                                   int argc, const char *argv[],
00315                                   Tcl_Interp *interp, MaterialList *mlist)
00316 {
00317   MUST_HAVE(1, "material");
00318   int val = mlist->material_index(argv[0]);
00319   if (val < 0) {
00320     char tmpstring[1024];
00321     sprintf(tmpstring, "graphics: invalid material: %s", argv[0]);
00322     Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00323     return TCL_ERROR;
00324   }
00325   const Material *mat = mlist->material(val); 
00326   char tmpstring[64];
00327   sprintf(tmpstring, "%d", gmol->use_material(mat));
00328   Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00329   return TCL_OK;
00330 } 
00331 
00332 // takes:
00333 //  a color index
00334 //  a color name (like "red")
00335 static int tcl_graphics_color(VMDApp *app, MoleculeGraphics *gmol,
00336                               int argc, const char *argv[],
00337                               Tcl_Interp *interp)
00338 {
00339   MUST_HAVE(1, "color");
00340   // is it a valid number?
00341   int id;
00342   Tcl_ResetResult(interp);
00343   if (Tcl_GetInt(interp, argv[0], &id) == TCL_OK) {
00344     // is it valid?
00345     if (id >=0 && id < MAXCOLORS) {
00346       char tmpstring[64];
00347       sprintf(tmpstring, "%d", gmol->use_color(id));
00348       Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00349       return TCL_OK;
00350     } else {
00351       char tmpstring[64];
00352       sprintf(tmpstring, "graphics: color index value '%d' out of range", id);
00353       Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00354       return TCL_ERROR;
00355     }
00356   }
00357   // is it a color name?
00358   Tcl_ResetResult(interp);
00359   id = app->color_index(argv[0]);
00360   if (id >= 0) { 
00361     char tmpstring[64];
00362     sprintf(tmpstring, "%d", gmol->use_color(id));
00363     Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00364     return TCL_OK;
00365   }
00366   // Otherwise there is a problem
00367   Tcl_AppendResult(interp, "graphics: unknown color: ", argv[0], NULL);
00368   return TCL_ERROR;
00369 }
00370 
00371 // cone has base and tip coordinates, width at the base, width at the tip and resolution
00372 static int tcl_graphics_cone(MoleculeGraphics *gmol,
00373                              int argc, const char *argv[],
00374                              Tcl_Interp *interp)
00375 {
00376   // the first two are {x, y, z}
00377   AT_LEAST(2, "cone");
00378   float vals[6];
00379   if (tcl_get_vector(argv[0], vals+0,  interp) != TCL_OK ||
00380       tcl_get_vector(argv[1], vals+3,  interp) != TCL_OK) {
00381     return TCL_ERROR;
00382   }
00383 
00384   // get the optional values
00385   double radius = 1.0;
00386   double radius2 = 0.0;
00387   int resolution = 6;
00388   argc -= 2;
00389   argv += 2;
00390   if (argc %2) {
00391     Tcl_SetResult(interp, (char *) "graphics: cone has wrong number of options", TCL_STATIC);
00392     return TCL_ERROR;
00393   }
00394   while (argc) {
00395     if (!strcmp(argv[0], "radius2")) {
00396       if (Tcl_GetDouble(interp, argv[1], &radius2) != TCL_OK) {
00397         return TCL_ERROR;
00398       }
00399       if (radius2 <0) radius2 = 0;
00400       argc -= 2;
00401       argv += 2;
00402       continue;
00403     }
00404     if (!strcmp(argv[0], "radius")) {
00405       if (Tcl_GetDouble(interp, argv[1], &radius) != TCL_OK) {
00406         return TCL_ERROR;
00407       }
00408       if (radius <0) radius = 0;
00409       argc -= 2;
00410       argv += 2;
00411       continue;
00412     }
00413     if (!strcmp(argv[0], "resolution")) {
00414       if (Tcl_GetInt(interp, argv[1], &resolution) != TCL_OK) {
00415         return TCL_ERROR;
00416       }
00417       if (resolution < 0) resolution = 0;
00418       if (resolution > 300) resolution = 300;
00419       argc -= 2;
00420       argv += 2;
00421       continue;
00422     }
00423 
00424     // reaching here is an error
00425     Tcl_AppendResult(interp, "graphics: unknown option for cone: ",
00426                      argv[0], NULL);
00427     return TCL_ERROR;
00428   }
00429 
00430   // I have a cone, so add it
00431   char tmpstring[64];
00432   sprintf(tmpstring, "%d",
00433           gmol->add_cone(vals+0, vals+3, (float) radius, (float) radius2, resolution));
00434   Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00435   return TCL_OK;
00436 }
00437 
00438 
00439 // sphere has a center, radius, and resolution
00440 static int tcl_graphics_sphere(MoleculeGraphics *gmol,
00441                                int argc, const char *argv[],
00442                                Tcl_Interp *interp)
00443 {
00444   // only really need the coordinates
00445   AT_LEAST(1, "sphere");
00446   float vals[3];
00447   if (tcl_get_vector(argv[0], vals+0,  interp) != TCL_OK) {
00448     return TCL_ERROR;
00449   }
00450 
00451   // get the optional values
00452   double radius = 1.0;
00453   int resolution = 6;
00454   argc -= 1;
00455   argv += 1;
00456   if (argc %2) {
00457     Tcl_SetResult(interp, (char *) "graphics: sphere has wrong number of options", TCL_STATIC);
00458     return TCL_ERROR;
00459   }
00460   while (argc) {
00461     if (!strcmp(argv[0], "radius")) {
00462       if (Tcl_GetDouble(interp, argv[1], &radius) != TCL_OK) {
00463         return TCL_ERROR;
00464       }
00465       if (radius <0) radius = 0;
00466       argc -= 2;
00467       argv += 2;
00468       continue;
00469     }
00470     if (!strcmp(argv[0], "resolution")) {
00471       if (Tcl_GetInt(interp, argv[1], &resolution) != TCL_OK) {
00472         return TCL_ERROR;
00473       }
00474       if (resolution < 0) resolution = 0;
00475       if (resolution > 30) resolution = 30;
00476       argc -= 2;
00477       argv += 2;
00478       continue;
00479     }
00480     // reaching here is an error
00481     Tcl_AppendResult(interp, "graphics: unknown option for sphere: ",
00482                      argv[0], NULL);
00483     return TCL_ERROR;
00484   }
00485 
00486   // I have a sphere, so add it
00487   char tmpstring[64];
00488   sprintf(tmpstring, "%d",
00489           gmol->add_sphere(vals+0, (float) radius, resolution));
00490   Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00491   return TCL_OK;
00492 }
00493 
00494 
00495 // text has a start point and a string to display
00496 static int tcl_graphics_text(MoleculeGraphics *gmol, int argc, const char *argv[],
00497                              Tcl_Interp *interp) {
00498   // have a vector and some text
00499   AT_LEAST(2, "text");
00500   float vals[3];
00501   if (tcl_get_vector(argv[0], vals+0,  interp) != TCL_OK) {
00502     return TCL_ERROR;
00503   }
00504 
00505   // get the optional size values
00506   const char* string = argv[1];
00507   double size = 1.0;
00508   double thickness = 1.0;
00509   argc -= 2;
00510   argv += 2;
00511 
00512   if (argc % 2) {
00513     Tcl_SetResult(interp, (char *) "graphics: text has wrong number of options", TCL_STATIC);
00514     return TCL_ERROR;
00515   }
00516 
00517   while (argc) {
00518     if (!strcmp(argv[0], "size")) {
00519       if (Tcl_GetDouble(interp, argv[1], &size) != TCL_OK) {
00520         return TCL_ERROR;
00521       }
00522       if (size <0) size = 0;
00523       argc -= 2;
00524       argv += 2;
00525       continue;
00526     }
00527 
00528     if (!strcmp(argv[0], "thickness")) {
00529       if (Tcl_GetDouble(interp, argv[1], &thickness) != TCL_OK) {
00530         return TCL_ERROR;
00531       }
00532       if (thickness <0) thickness = 0;
00533       argc -= 2;
00534       argv += 2;
00535       continue;
00536     }
00537 
00538     // reaching here is an error
00539     Tcl_AppendResult(interp, "graphics: unknown option for text: ",
00540                      argv[0], NULL);
00541     return TCL_ERROR;
00542   }
00543 
00544   // add the text
00545   char tmpstring[64];
00546   sprintf(tmpstring, "%d", gmol->add_text(vals+0, string, (float) size, (float) thickness));
00547   Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00548   return TCL_OK;
00549 }
00550 
00551 
00552 static int tcl_graphics_spheretube(MoleculeGraphics *gmol, int argc, const char *argv[], Tcl_Interp *interp) {
00553   // have a vector and some text
00554   AT_LEAST(2, "spheretube");
00555   float *coords = NULL; 
00556   float *radii = NULL;
00557   float radius = 0.0f;
00558   float *rgb3fv = NULL;
00559   int *colorids = NULL;
00560   int numcoords = 0, numcolors = 0, numcolorids = 0;
00561   int radset = 0, numradii = 0;
00562   int drawtubes = 0;
00563   int res = 8;
00564   
00565   if (tcl_get_vecarray(argv[0], numcoords, coords, interp) != TCL_OK) {
00566     delete [] coords;
00567     return TCL_ERROR;
00568   }
00569 
00570   // advance to process remaining command arguments
00571   argc -= 1;
00572   argv += 1;
00573 
00574   while (argc) {
00575     if (!strcmp(argv[0], "colors")) {
00576       if (tcl_get_vecarray(argv[1], numcolors, rgb3fv, interp) != TCL_OK) {
00577         delete [] coords;
00578         delete [] rgb3fv;
00579         delete [] colorids; 
00580         delete [] radii;
00581         return TCL_ERROR;
00582       }
00583 
00584       argc -= 2;
00585       argv += 2;
00586       continue;
00587     }
00588 
00589     if (!strcmp(argv[0], "colorids")) {
00590       if (tcl_get_intarray(argv[1], numcolorids, colorids, interp) != TCL_OK) {
00591         delete [] coords;
00592         delete [] rgb3fv;
00593         delete [] colorids; 
00594         delete [] radii;
00595         return TCL_ERROR;
00596       }
00597 
00598       rgb3fv = new float[numcolorids * 3];
00599       for (int idx=0; idx<numcolorids; idx++) {
00600         int id = colorids[idx];
00601         // is it valid?
00602         if (id <0 && id >= MAXCOLORS) {
00603           char tmpstring[64];
00604           sprintf(tmpstring, "graphics spheretubes: color index value '%d' out of range", id);
00605           Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00606           return TCL_ERROR;
00607         }
00608       }
00609 
00610       argc -= 2;
00611       argv += 2;
00612       continue;
00613     }
00614 
00615     if (!strcmp(argv[0], "radii")) {
00616       if (tcl_get_array(argv[1], numradii, radii, interp) != TCL_OK) {
00617         delete [] coords;
00618         delete [] rgb3fv;
00619         delete [] colorids; 
00620         delete [] radii;
00621         return TCL_ERROR;
00622       }
00623       radset = 1; // we got some radius information
00624       radius = float(radii[0]); // must set to first radius in case of 1 radii
00625 
00626       argc -= 2;
00627       argv += 2;
00628       continue;
00629     }
00630 
00631     if (!strcmp(argv[0], "radius")) {
00632       double trad = 0.0;
00633       if (Tcl_GetDouble(interp, argv[1], &trad) != TCL_OK) {
00634         delete [] coords;
00635         delete [] rgb3fv;
00636         delete [] colorids; 
00637         delete [] radii;
00638         return TCL_ERROR;
00639       }
00640       if (trad < 0) trad = 0;
00641       numradii = 1;
00642       radset = 1; // we got some radius information
00643       radius = float(trad);
00644 
00645       argc -= 2;
00646       argv += 2;
00647       continue;
00648     }
00649 
00650     if (!strcmp(argv[0], "drawtubes")) {
00651       if (Tcl_GetInt(interp, argv[1], &drawtubes) != TCL_OK) {
00652         delete [] coords;
00653         delete [] rgb3fv;
00654         delete [] colorids; 
00655         delete [] radii;
00656         return TCL_ERROR;
00657       }
00658       argc -= 2;
00659       argv += 2;
00660       continue;
00661     }
00662 
00663     if (!strcmp(argv[0], "resolution")) {
00664       if (Tcl_GetInt(interp, argv[1], &res) != TCL_OK) {
00665         delete [] coords;
00666         delete [] rgb3fv;
00667         delete [] colorids; 
00668         delete [] radii;
00669         return TCL_ERROR;
00670       }
00671       if (res < 8) res = 8;
00672       argc -= 2;
00673       argv += 2;
00674       continue;
00675     }
00676 
00677     // reaching here is an error
00678     Tcl_AppendResult(interp, "graphics: unknown option for spheretube: ",
00679                      argv[0], NULL);
00680 
00681     delete [] coords;
00682     delete [] rgb3fv;
00683     delete [] colorids; 
00684     delete [] radii;
00685     return TCL_ERROR;
00686   }
00687 
00688 #if 0
00689   printf("***spheretube: coords %d radii %d drawtubes: %d res %d\n", 
00690          numcoords/3, numradii, drawtubes, res);
00691 #endif
00692 
00693   if ((numcoords % 3)) {
00694     Tcl_SetResult(interp, (char *) "graphics: illegal spheretube coordinate vector length", TCL_STATIC);
00695     printf("total coordinate components not divible by 3!\n");
00696     delete [] coords;
00697     delete [] rgb3fv; 
00698     delete [] colorids; 
00699     delete [] radii;
00700     return TCL_ERROR;
00701   }
00702   if ((numradii > 1) && (numradii != (numcoords/3))) {
00703     Tcl_SetResult(interp, (char *) "graphics: spheretube requires matching count of coords and radii", TCL_STATIC);
00704     delete [] coords;
00705     delete [] rgb3fv; 
00706     delete [] colorids; 
00707     delete [] radii;
00708     return TCL_ERROR;
00709   }
00710   if ((numcolors > 0 || numcolorids > 0) && 
00711       (((numcolors != 0) && (numcolors != numcoords)) || 
00712        ((numcolorids != 0) && ((3*numcolorids) != numcoords)))) {
00713     Tcl_SetResult(interp, (char *) "graphics: spheretube requires matching count of coords and colors", TCL_STATIC);
00714     delete [] coords;
00715     delete [] rgb3fv; 
00716     delete [] colorids; 
00717     delete [] radii;
00718     return TCL_ERROR;
00719   }
00720   if ((!radset)) {
00721     Tcl_SetResult(interp, (char *) "graphics: spheretube requires either radius or radii parameter be set", TCL_STATIC);
00722     delete [] coords;
00723     delete [] rgb3fv; 
00724     delete [] colorids; 
00725     delete [] radii;
00726     return TCL_ERROR;
00727   }
00728 
00729   int colorcnt = 0;
00730   if (numcolors > 0)
00731     colorcnt = numcolors / 3;
00732   if (numcolorids > 0)
00733     colorcnt = numcolorids;
00734 
00735   char tmpstring[64];
00736   int gid = gmol->add_spheretube(numcoords/3, coords, numradii, 
00737                                  (numradii > 1) ? radii : &radius,
00738                                  colorcnt, rgb3fv, colorids, 
00739                                  drawtubes, res);
00740   sprintf(tmpstring, "%d", gid);
00741   Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00742   return TCL_OK;
00743 }
00744 
00745 
00747 // delete the given id
00748 static int tcl_graphics_delete(MoleculeGraphics *gmol, int argc, const char *argv[],
00749                                Tcl_Interp *interp) {
00750   if (argc != 1) {
00751     Tcl_SetResult(interp, (char *) "graphics: delete takes one parameter (either an index or 'all')", TCL_STATIC);
00752     return TCL_ERROR;
00753   }
00754   if (!strcmp(argv[0], "all")) {
00755     gmol->delete_all();
00756     return TCL_OK;
00757   }
00758   int id;
00759   if (Tcl_GetInt(interp, argv[0], &id) != TCL_OK) {
00760     return TCL_ERROR;
00761   }
00762   gmol->delete_id(id);
00763   return TCL_OK;
00764 }
00765 
00766 // delete the given id and have the next element replace this one
00767 static int tcl_graphics_replace(MoleculeGraphics *gmol, int argc, const char *argv[],
00768                                 Tcl_Interp *interp) {
00769   if (argc != 1) {
00770     Tcl_SetResult(interp, (char *) "graphics: replace takes one parameter, the index", TCL_STATIC);
00771     return TCL_ERROR;
00772   }
00773   int id;
00774   if (Tcl_GetInt(interp, argv[0], &id) != TCL_OK) {
00775     return TCL_ERROR;
00776   }
00777   gmol->replace_id(id);
00778   return TCL_OK;
00779 }
00780 
00781 // does a given id exist?
00782 static int tcl_graphics_exists(MoleculeGraphics *gmol, int argc, const char *argv[],
00783                                Tcl_Interp *interp) {
00784   if (argc != 1) {
00785     Tcl_SetResult(interp, (char *) "graphics: exists takes one parameter, the index", TCL_STATIC);
00786     return TCL_ERROR;
00787   }
00788   int id;
00789   if (Tcl_GetInt(interp, argv[0], &id) != TCL_OK) {
00790     return TCL_ERROR;
00791   }
00792 
00793   char tmpstring[64]; 
00794   sprintf(tmpstring, "%d", gmol->index_id(id) != -1);
00795   Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00796   return TCL_OK;
00797 }
00798 
00799 // return info about the graphics with a given id
00800 static int tcl_graphics_info(MoleculeGraphics *gmol,
00801                              int argc, const char *argv[],
00802                              Tcl_Interp *interp)
00803 {
00804   if (argc != 1) {
00805     Tcl_SetResult(interp, (char *) "graphics: info takes one parameter, the index", TCL_STATIC);
00806     return TCL_ERROR;
00807   }
00808   int id;
00809   if (Tcl_GetInt(interp, argv[0], &id) != TCL_OK) {
00810     return TCL_ERROR;
00811   }
00812   // since either NULL or a static char * is returned, this will work
00813   Tcl_AppendResult(interp, gmol->info_id(id), NULL);
00814   return TCL_OK;
00815 }
00816 
00817 
00818 // already parsed the "graphics" and "number" terms, what remains are
00819 //  add, delete, info, and list
00820 static int tcl_graphics(VMDApp *app, int molid, int argc, const char *argv[], 
00821                         Tcl_Interp *interp)
00822 {
00823   // Is this a graphics molecule?
00824   Molecule *mol = app->moleculeList->mol_from_id(molid);
00825   if (mol == NULL) {
00826     Tcl_SetResult(interp, (char *) "graphics: invalid graphics molecule", TCL_STATIC);
00827     return TCL_ERROR;
00828   }
00829   if (argc < 1) {
00830     Tcl_SetResult(interp, (char *) "graphics: not enough parameters", TCL_STATIC);
00831     return TCL_ERROR;
00832   }
00833   MoleculeGraphics *gmol = mol->moleculeGraphics();
00834   // what am I to do?
00835   if (!strcmp(argv[0], "list")) {
00836     if (argc != 1) {
00837       Tcl_SetResult(interp, (char *) "graphics: list takes no parameters", TCL_STATIC);
00838       return TCL_ERROR;
00839     }
00840     int num = gmol->num_elements();
00841     for (int i=0; i<num; i++) {
00842       int id = gmol->element_id(i);
00843       if (id >=0) {
00844         char s[16];
00845         sprintf(s, "%d", id);
00846         Tcl_AppendElement(interp, s);
00847       }
00848     }
00849     return TCL_OK;
00850   }
00851   // all the rest take more than one parameter
00852   if (argc < 2) {
00853     Tcl_SetResult(interp, (char *) "graphics: not enough parameters", TCL_STATIC);
00854     return TCL_ERROR;
00855   }
00856   if (!strcmp(argv[0], "triangle")) {
00857     return tcl_graphics_triangle(gmol, argc-1, argv+1, interp);
00858   }
00859   if (!strcmp(argv[0], "trinorm")) {
00860     return tcl_graphics_trinorm(gmol, argc-1, argv+1, interp);
00861   }
00862   if (!strcmp(argv[0], "tricolor")) {
00863     return tcl_graphics_tricolor(gmol, argc-1, argv+1, interp);
00864   }
00865   if (!strcmp(argv[0], "point")) {
00866     return tcl_graphics_point(gmol, argc-1, argv+1, interp);
00867   }
00868   if (!strcmp(argv[0], "pickpoint")) {
00869     return tcl_graphics_pickpoint(gmol, argc-1, argv+1, interp);
00870   }
00871   if (!strcmp(argv[0], "line")) {
00872     return tcl_graphics_line(gmol, argc-1, argv+1, interp);
00873   }
00874   if (!strcmp(argv[0], "cylinder")) {
00875     return tcl_graphics_cylinder(gmol, argc-1, argv+1, interp);
00876   }
00877   if (!strcmp(argv[0], "cone")) {
00878     return tcl_graphics_cone(gmol, argc-1, argv+1, interp);
00879   }
00880   if (!strcmp(argv[0], "sphere")) {
00881     return tcl_graphics_sphere(gmol, argc-1, argv+1, interp);
00882   }
00883   if (!strcmp(argv[0], "text")) {
00884     return tcl_graphics_text(gmol, argc-1, argv+1, interp);
00885   }
00886   if (!strcmp(argv[0], "spheretube")) {
00887     return tcl_graphics_spheretube(gmol, argc-1, argv+1, interp);
00888   }
00889   if (!strcmp(argv[0], "materials")) {
00890     return tcl_graphics_materials(gmol, argc-1, argv+1, interp);
00891   }
00892   if (!strcmp(argv[0], "material")) {
00893     return tcl_graphics_material(gmol, argc-1, argv+1, interp, 
00894       app->materialList);
00895   }
00896   if (!strcmp(argv[0], "color") || !strcmp(argv[1], "colour")) {
00897     return tcl_graphics_color(app, gmol, argc-1, argv+1, interp);
00898   }
00899   if (!strcmp(argv[0], "delete")) {
00900     return tcl_graphics_delete(gmol, argc-1, argv+1, interp);
00901   }
00902   if (!strcmp(argv[0], "exists")) {
00903    return tcl_graphics_exists(gmol, argc-1, argv+1, interp);
00904   } 
00905   if (!strcmp(argv[0], "replace")) {
00906    return tcl_graphics_replace(gmol, argc-1, argv+1, interp);
00907   }
00908   if (!strcmp(argv[0], "info")) {
00909    return tcl_graphics_info(gmol, argc-1, argv+1, interp);
00910   }
00911   Tcl_AppendResult(interp, "graphics: don't understand the command: ",
00912                    argv[0], NULL);
00913   return TCL_ERROR;
00914 }
00915 
00916 
00917 // interface to the 3d graphics
00918 int graphics_tcl(ClientData cd, Tcl_Interp *interp, int argc, const char *argv[]) {
00919   // need at least two arguments
00920   if (argc < 2) {
00921     Tcl_SetResult(interp, (char *) "graphics: not enough parameters", TCL_STATIC);
00922     return TCL_ERROR;
00923   }
00924 
00925   VMDApp *app = (VMDApp *)cd;
00926   // get the molid 
00927   int mol = -1;
00928   if (!strcmp(argv[1], "top")) {
00929     if (app->moleculeList->top()) {
00930       mol = app->moleculeList->top()->id();
00931     }
00932   } else {
00933     if (Tcl_GetInt(interp, argv[1], &mol) != TCL_OK) {
00934       return TCL_ERROR;
00935     }
00936   }
00937   // and call the "real" function
00938   return tcl_graphics(app, mol, argc-2, argv+2, interp);
00939 }
00940 
00941 

Generated on Fri Mar 29 02:46:15 2024 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002