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

AtomRep.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr                                                                       
00003  *cr            (C) Copyright 1995-2011 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: AtomRep.C,v $
00013  *      $Author: johns $        $Locker:  $                $State: Exp $
00014  *      $Revision: 1.126 $      $Date: 2011/10/12 22:49:45 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  * 
00019  * Parse and maintain the data for how a molecule should be represented.
00020  *
00021  ***************************************************************************/
00022 
00023 #include <string.h>
00024 #include <stdlib.h>
00025 #include "AtomRep.h"
00026 #include "Inform.h"
00027 #include "utilities.h"
00028 #include "config.h"
00029 
00030 /***********************  NOTES on ADDING NEW REPRESENTATIONS ************
00031  So, you wanna add a new representation ... here's what you have to do:
00032  1. Choose a a name for the rep, and decide how many parameters it needs.
00033     This object has support for up to MAX_ATOMREP_DATA parameters.
00034  2. Choose the order in which these will be specified in the text command.
00035  3. Add a new identifier in the main RepMethod enumeration for this new
00036     rep.  The order is important; where you put the new item is where it
00037     will appear in lists of the different representations.
00038  4. Add a new element to the AtomRepInfo structure array (below).  This element
00039     defines the name of the new rep, and gives info about all the parameters
00040     needed for that rep.  You must put the item into the array in the same
00041     position where the new enum value was inserted into RepMethod.
00042  5. Once this structure is properly defined, the GUI and text interface will
00043     properly process and display the info for the new rep.  At this point,
00044     you must add the code to display the new rep in DrawMolItem.
00045  6. Sit back and enjoy ...
00046 
00047  FORMAT for AtomRepInfo STRUCTURE:
00048  ---------------------------------
00049  Easiest thing to do is to copy an item with the same number of parameters,
00050  and change the necessary values.  The items in each structure are:
00051         a. Integer enum code for the rep (same as was put in RepMethod enum)
00052         b. Name of rep (should be a single small word; this is the name
00053            used in the GUI list, and what the user calls the rep when typing
00054            in a command to change to this rep)
00055         c. Number of parameters required.
00056         d. An array of Structures which define how each parameter is used
00057            for the representation.  The format for these items are:
00058                 1. Index of the parameter in the AtomRep internal data
00059                    storage array.  This should be used when retrieving the
00060                    data; call 'get_data' with this index value to retrieve
00061                    the value for this parameter.  Each parameter for the
00062                    representation should have a different index, and they
00063                    should be in the range 0 ... MAX_ATOMREP_DATA-1.
00064                    There is an enumeration giving names for these indices,
00065                    which is used right now primarily for historical reasons.
00066                    Older parts of VMD used explicit calls to routines to get
00067                    values for things such as the line thickness and sphere
00068                    resolution, and these routines are still present.  But
00069                    since new reps may not necessarily have characteristics
00070                    which map to these items, this should not be used in the
00071                    future.
00072                 2. Default value
00073  ***************************************************************************/
00074 
00075 // default res of cartoon cylinders
00076 #define DEF_CART_RES 12.0  
00077 
00078 // default res of bond cylinders
00079 #define DEF_BOND_RES 10.0
00080 
00081 // default res of spheres
00082 #define DEF_SPH_RES  12.0 
00083 
00084 // default res of licorice reps
00085 #define DEF_LIC_RES  10.0 
00086 
00087 // default thickness of lines
00088 #define DEF_LINE_RES 1.0 
00089 
00090 // default point size
00091 #define DEF_POINT_SIZE 1.0 
00092 
00093 //const AtomRepDataInfo UNUSED = {0, 0.0};
00094 #define UNUSED {0, 0.0}
00095 
00096 // define structures which indicate what data is needed by each rep
00097 const AtomRepParamStruct AtomRepInfo[AtomRep::TOTAL] = {
00098   //
00099   // Bond-oriented reps
00100   //
00101 
00102   // Lines
00103   { "Lines", 2, {
00104     {  AtomRep::LINETHICKNESS, DEF_LINE_RES },
00105     {  AtomRep::ISOLINETHICKNESS, 0.0f },
00106     UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED }
00107   },
00108 
00109   // Bonds
00110   { "Bonds", 2, {
00111     {  AtomRep::BONDRAD, 0.3f },
00112     {  AtomRep::BONDRES, DEF_BOND_RES },
00113     UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED }
00114   },
00115 
00116   // DynamicBonds
00117   { "DynamicBonds", 3, {
00118     {  AtomRep::SPHERERAD, 3.0f },  // distance
00119     {  AtomRep::BONDRAD, 0.3f },
00120     {  AtomRep::BONDRES, DEF_BOND_RES },
00121     UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED }
00122   },
00123 
00124   // HBonds
00125   { "HBonds", 3, {
00126     {  AtomRep::BONDRAD, 3.0f},     // distance
00127     {  AtomRep::SPHERERAD, 20.0f},  // angle
00128     {  AtomRep::LINETHICKNESS, 1.0f}, 
00129     UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED }
00130   },
00131 
00132 
00133   //
00134   // Atom-oriented reps
00135   //
00136 
00137   // Points
00138   { "Points", 1, { 
00139     {  AtomRep::LINETHICKNESS, DEF_POINT_SIZE},  // size
00140     UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED }
00141   },
00142 
00143   // VDW
00144   { "VDW", 2, {
00145     {  AtomRep::SPHERERAD, 1.0f},
00146     {  AtomRep::SPHERERES, DEF_SPH_RES },
00147     UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED }
00148   },
00149 
00150   // CPK
00151   { "CPK", 5, {
00152     {  AtomRep::SPHERERAD, 1.0f},
00153     {  AtomRep::BONDRAD, 0.3f},
00154     {  AtomRep::SPHERERES, DEF_SPH_RES},
00155     {  AtomRep::BONDRES, DEF_BOND_RES},
00156     {  AtomRep::ISOLINETHICKNESS, 0.0f },
00157     UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED }
00158   },
00159 
00160   // Licorice
00161   { "Licorice", 4, {
00162     {  AtomRep::BONDRAD, 0.3f },
00163     {  AtomRep::SPHERERES, DEF_LIC_RES},
00164     {  AtomRep::BONDRES, DEF_LIC_RES},
00165     {  AtomRep::ISOLINETHICKNESS, 0.0f }, // if nonzero, cutoff distance
00166     UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED }
00167   },
00168 
00169 
00170 #ifdef VMDPOLYHEDRA
00171   // Polyhedra
00172   { "Polyhedra", 1, {
00173     {  AtomRep::SPHERERAD, 3.0f },  // distance
00174     UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED }
00175   },
00176 #endif
00177 
00178   //
00179   // Secondary structure reps
00180   //
00181 
00182   // C-alpha trace
00183   { "Trace", 2, {
00184     {  AtomRep::BONDRAD, 0.3f},
00185     {  AtomRep::BONDRES, DEF_BOND_RES},
00186     UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED }
00187   },
00188 
00189   // Tube
00190   { "Tube", 2, {
00191     {  AtomRep::BONDRAD, 0.3f },
00192     {  AtomRep::BONDRES, DEF_BOND_RES},
00193     UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED }
00194   },
00195 
00196   // Ribbons
00197   { "Ribbons", 3, {
00198     {  AtomRep::BONDRAD, 0.3f},
00199     {  AtomRep::BONDRES, DEF_BOND_RES},
00200     {  AtomRep::LINETHICKNESS, 2.0f},
00201     UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED }
00202   },
00203 
00204   // NewRibbons
00205   { "NewRibbons", 4, {
00206     {  AtomRep::BONDRAD, 0.3f },
00207     {  AtomRep::BONDRES, 10.0f },
00208     {  AtomRep::LINETHICKNESS, 3.0f},
00209     {  AtomRep::SPHERERAD, 0},  // spline basis
00210     UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED }
00211   },
00212 
00213   // Structure
00214   { "Cartoon", 3, {
00215     {  AtomRep::BONDRAD, 2.1f},
00216     {  AtomRep::BONDRES, DEF_CART_RES },
00217     {  AtomRep::LINETHICKNESS, 5.0f},
00218     UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED }
00219   },
00220 
00221   // NewCartoon
00222   { "NewCartoon", 4, {
00223     {  AtomRep::BONDRAD, 0.3f },
00224     {  AtomRep::BONDRES, 10.0f },
00225     {  AtomRep::LINETHICKNESS, 4.5f},
00226     {  AtomRep::SPHERERAD, 0},  // spline basis
00227     UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED }
00228   },
00229 
00230 #ifdef VMDWITHCARBS
00231   // PaperChain
00232   { "PaperChain", 2, {
00233     {  AtomRep::LINETHICKNESS, 1.0f }, // bipyramid_height : height of the pyramids drawn to represent rings
00234     {  AtomRep::ISOSTEPSIZE, 10 }, // maxringsize : maximum number of atoms in a small ring
00235     UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED }
00236   },
00237     
00238   // Twister
00239   { "Twister", 7, {
00240     {  AtomRep::LINETHICKNESS, 1 }, // start_end_centroid : 0 - start ribbons at the edge of the ring, 1 - start ribbons at the ring centroids
00241     {  AtomRep::BONDRES, 0 }, // hide_shared_links: 0 - show all linkage paths, 1 - hide linkage paths which share edges with other paths
00242     {  AtomRep::SPHERERAD, 10 }, // rib_steps : number of steps to use when drawing ribbons
00243     {  AtomRep::BONDRAD, 0.3f }, // rib_width : width of the ribbon
00244     {  AtomRep::SPHERERES, 0.05f }, // rib_height : height of the ribbon
00245     {  AtomRep::ISOSTEPSIZE, 10 }, // maxringsize : maximum number of atoms in a small ring
00246     {  AtomRep::ISOLINETHICKNESS, 5 }, // maxpathlength : maximum number of atoms in a path joining two small rings
00247     UNUSED, UNUSED, UNUSED, UNUSED, UNUSED }
00248   },
00249 #endif
00250 
00251 
00252   //
00253   // Surface, Isosurface, and Solvent reps
00254   //
00255 
00256 #ifdef VMDQUICKSURF
00257   // QuickSurf
00258   { "QuickSurf", 4, {
00259     {  AtomRep::SPHERERAD, 1.0f },  // sphere radius multiplier
00260     {  AtomRep::BONDRAD,   0.5f },  // density isovalue for surface
00261     {  AtomRep::GRIDSPACING, 1.0f}, // lattice grid spacing 
00262     {  AtomRep::BONDRES, 0 },       // quality
00263     UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED }
00264   },
00265 #endif
00266 
00267 #ifdef VMDMSMS
00268   // MSMS surface
00269   { "MSMS", 4, {
00270     {  AtomRep::SPHERERAD, 1.5f }, // probe radius
00271     {  AtomRep::SPHERERES, 1.5f }, // density
00272     {  AtomRep::LINETHICKNESS, 0}, // all atoms
00273     {  AtomRep::BONDRES, 0},       // wireframe
00274     UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED }
00275   },
00276 #endif
00277 
00278 #ifdef VMDSURF
00279   // Surf
00280   { "Surf", 2, {
00281     {  AtomRep::SPHERERAD, 1.4f }, // probe radius
00282     {  AtomRep::BONDRES, 0},       // wireframe
00283     UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED }
00284   },
00285 #endif
00286 
00287   // Slice of volumetric data
00288   { "VolumeSlice", 4, {
00289     { AtomRep::SPHERERAD,  0.5f }, // slice
00290     { AtomRep::SPHERERES,     0 }, // VolID
00291     { AtomRep::LINETHICKNESS, 0 }, // slice axis
00292     { AtomRep::BONDRES,       2 },  // quality
00293     UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED }
00294   },
00295 
00296   // Isosurface of volumetric data
00297   { "Isosurface", 6, {
00298     { AtomRep::SPHERERAD,    0.5f }, // isoval
00299     { AtomRep::SPHERERES,        0}, // VolID
00300     { AtomRep::LINETHICKNESS,    2}, // draw box and isosurface by default
00301     { AtomRep::BONDRES,          2}, // use points method by default
00302     { AtomRep::ISOSTEPSIZE,      1}, // use step size of one by default
00303     { AtomRep::ISOLINETHICKNESS, 1}, // lines are thickness one by default
00304     UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED }
00305   },
00306 
00307   // Volumetric gradient field lines
00308   { "FieldLines", 5, {
00309     { AtomRep::SPHERERES,      0},  // VolID
00310     { AtomRep::SPHERERAD,   1.8f},  // seed value
00311     { AtomRep::BONDRAD,    10.0f},  // minimum line length
00312     { AtomRep::BONDRES,    50.0f},  // maximum line length
00313     { AtomRep::LINETHICKNESS,  1},  // line thickness
00314     UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED }
00315   },
00316 
00317   // Molecular orbital
00318   { "Orbital", 10, {
00319     { AtomRep::SPHERERAD,     0.05f}, // isoval
00320     { AtomRep::SPHERERES,         0}, // Orbital ID
00321     { AtomRep::LINETHICKNESS,     0}, // draw only isosurface by default
00322     { AtomRep::BONDRES,           0}, // use solid method by default
00323     { AtomRep::GRIDSPACING,  0.075f}, // default orbital grid spacing
00324     { AtomRep::ISOLINETHICKNESS,  1}, // lines are thickness one by default
00325     { AtomRep::WAVEFNCTYPE,       0}, // default wavefunction type 
00326     { AtomRep::WAVEFNCSPIN,       0}, // default wavefunction spin
00327     { AtomRep::WAVEFNCEXCITATION, 0}, // default wavefunction excitation
00328     { AtomRep::ISOSTEPSIZE,       1}, // use step size of one by default
00329     UNUSED, UNUSED }
00330   },
00331 
00332   // Beads 
00333   { "Beads", 2, {
00334     {  AtomRep::SPHERERAD, 1.0f},
00335     {  AtomRep::SPHERERES, DEF_SPH_RES },
00336     UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED }
00337   },
00338 
00339   // Dotted
00340   { "Dotted", 2, {
00341     {  AtomRep::SPHERERAD, 1.0f},
00342     {  AtomRep::SPHERERES, DEF_SPH_RES},
00343     UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED }
00344   },
00345 
00346   // Dot surface
00347   { "Solvent", 3, {
00348     {  AtomRep::SPHERERAD, 0 }, // probe
00349     // the max value is set in the constructor for AtomRep, so don't
00350     // change things around too much!
00351     {  AtomRep::SPHERERES, 7.0f},  // detail
00352     {  AtomRep::LINETHICKNESS, 1.0f }, // method
00353     UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED }
00354   }
00355 };
00356 
00357 
00359 // constructor; parse string and see if OK
00360 AtomRep::AtomRep(void) {
00361   int i, j;
00362  
00363   // initialize variables
00364   repMethod  = DEFAULT_ATOMREP;
00365   repData = repDataStorage[repMethod];
00366   strcpy(cmdStr, AtomRepInfo[repMethod].name);
00367   for(j=0; j < TOTAL; j++) {
00368     memset(repDataStorage[j], 0, MAX_ATOMREP_DATA*sizeof(float));
00369     for(i=0; i < AtomRepInfo[j].numdata ; i++)
00370       repDataStorage[j][AtomRepInfo[j].repdata[i].index] =
00371         AtomRepInfo[j].repdata[i].defValue;
00372   }
00373 
00374 }
00375 
00376 AtomRep::~AtomRep(void) { }
00377 
00379 // parse the given command, and store results.  Return success.
00380 int AtomRep::parse_cmd(const char *newcmd) {
00381   int argc, i, j;
00382   char *argv[256], *cmdStrTok = NULL;
00383 
00384   // make sure the new command is not too long
00385   if(newcmd && strlen(newcmd) > MAX_ATOMREP_CMD) {
00386     msgErr << "Atom representation string is too long (over ";
00387     msgErr << MAX_ATOMREP_CMD << " characters)." << sendmsg;
00388     return FALSE;
00389   }
00390 
00391   // XXX Hack to make the "Off" rep work: alias to "Lines"
00392   if (!strupncmp(newcmd, "off", 3)) newcmd = "Lines";
00393 
00394   // tokenize the command
00395   if(!newcmd || !(cmdStrTok = str_tokenize(newcmd, &argc, argv))) {
00396     // no command; keep current settings
00397     return TRUE;
00398   }
00399 
00400   // see if the command matches a representation we know about
00401   for(i=0; i < AtomRep::TOTAL; i++) {
00402     const AtomRepParamStruct *ari = &(AtomRepInfo[i]);
00403 
00404     if(!strupncmp(argv[0], ari->name, CMDLEN)) {
00405       // the name matches; make sure we do not have too many arguments
00406       if((argc - 1) > ari->numdata) {
00407         msgErr << "Incorrect atom representation command '" << newcmd << "':";
00408         msgErr << "\n  '" << ari->name << "' only takes " << ari->numdata;
00409         msgErr << " arguments maximum." << sendmsg;
00410 
00411         delete [] cmdStrTok;
00412         return FALSE;
00413       }
00414 
00415       // indicate that we've changed to a new rep method
00416       repMethod = i;
00417       repData = repDataStorage[i];
00418 
00419       // copy out the data from the command and store it
00420       for(j=1; j < argc; j++) {
00421         // if a '-' is given, do not change that parameter
00422         if(!(argv[j][0] == '-' && argv[j][1] == '\0'))
00423           repData[ari->repdata[j-1].index] = (float) atof(argv[j]);
00424       }
00425 
00426       // found a match; break from for loop
00427       break;
00428     }
00429   }
00430 
00431   // if i is at the end of the list, we did not find a match
00432   if(i == AtomRep::TOTAL) {
00433     msgErr << "Unknown atom representation command '" << newcmd << "'.";
00434     msgErr << sendmsg;
00435 
00436     delete [] cmdStrTok;
00437     return FALSE;
00438   }
00439 
00440   // if we are here, everything went OK
00441   strcpy(cmdStr, newcmd);
00442 
00443   delete [] cmdStrTok;
00444   return TRUE;
00445 }
00446 
00447 
00449 
00450 // copy contents of another atomrep
00451 AtomRep &AtomRep::operator=(const AtomRep &ar) {
00452   strcpy(cmdStr, ar.cmdStr);
00453   repMethod = ar.repMethod;
00454   repData = repDataStorage[repMethod];
00455   for(int j=0; j < TOTAL; j++)
00456     for(int i=0; i < MAX_ATOMREP_DATA; i++)
00457       repDataStorage[j][i] = ar.repDataStorage[j][i];
00458 
00459   return *this;
00460 }
00461 

Generated on Wed May 16 01:48:59 2012 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002