Main Page   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-2008 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.106 $      $Date: 2008/04/20 05:23:10 $
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 6.0
00080 
00081 // default res of spheres
00082 #define DEF_SPH_RES  8.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 }
00107   },
00108 
00109   // Bonds
00110   { "Bonds", 2, {
00111     {  AtomRep::BONDRAD, 0.3f },
00112     {  AtomRep::BONDRES, DEF_BOND_RES },
00113     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 }
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 }
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 }
00141   },
00142 
00143   // VDW
00144   { "VDW", 2, {
00145     {  AtomRep::SPHERERAD, 1.0f},
00146     {  AtomRep::SPHERERES, DEF_SPH_RES },
00147     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 }
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 }
00167   },
00168 
00169 
00170   //
00171   // Secondary structure reps
00172   //
00173 
00174   // C-alpha trace
00175   { "Trace", 2, {
00176     {  AtomRep::BONDRAD, 0.3f},
00177     {  AtomRep::BONDRES, DEF_BOND_RES},
00178     UNUSED, UNUSED, UNUSED, UNUSED }
00179   },
00180 
00181   // Tube
00182   { "Tube", 2, {
00183     {  AtomRep::BONDRAD, 0.3f },
00184     {  AtomRep::BONDRES, DEF_BOND_RES},
00185     UNUSED, UNUSED, UNUSED, UNUSED }
00186   },
00187 
00188   // Ribbons
00189   { "Ribbons", 3, {
00190     {  AtomRep::BONDRAD, 0.3f},
00191     {  AtomRep::BONDRES, DEF_BOND_RES},
00192     {  AtomRep::LINETHICKNESS, 2.0f},
00193     UNUSED, UNUSED, UNUSED }
00194   },
00195 
00196   // NewRibbons
00197   { "NewRibbons", 4, {
00198     {  AtomRep::BONDRAD, 0.3f },
00199     {  AtomRep::BONDRES, DEF_BOND_RES },
00200     {  AtomRep::LINETHICKNESS, 3.0f},
00201     {  AtomRep::SPHERERAD, 0},  // spline basis
00202     UNUSED, UNUSED }
00203   },
00204 
00205   // Structure
00206   { "Cartoon", 3, {
00207     {  AtomRep::BONDRAD, 2.1f},
00208     {  AtomRep::BONDRES, DEF_CART_RES },
00209     {  AtomRep::LINETHICKNESS, 5.0f},
00210     UNUSED, UNUSED, UNUSED }
00211   },
00212 
00213   // NewCartoon
00214   { "NewCartoon", 4, {
00215     {  AtomRep::BONDRAD, 0.3f },
00216     {  AtomRep::BONDRES, DEF_BOND_RES },
00217     {  AtomRep::LINETHICKNESS, 4.5f},
00218     {  AtomRep::SPHERERAD, 0},  // spline basis
00219     UNUSED, UNUSED }
00220   },
00221 
00222 #ifdef VMDWITHCARBS
00223   // PaperChain
00224   { "PaperChain", 2, {
00225     {  AtomRep::LINETHICKNESS, 1.0f }, // bipyramid_height : height of the pyramids drawn to represent rings
00226     {  AtomRep::ISOSTEPSIZE, 10 }, // maxringsize : maximum number of atoms in a small ring
00227     UNUSED, UNUSED, UNUSED, UNUSED, UNUSED }
00228   },
00229     
00230   // Twister
00231   { "Twister", 7, {
00232     {  AtomRep::LINETHICKNESS, 1 }, // start_end_centroid : 0 - start ribbons at the edge of the ring, 1 - start ribbons at the ring centroids
00233     {  AtomRep::BONDRES, 0 }, // hide_shared_links: 0 - show all linkage paths, 1 - hide linkage paths which share edges with other paths
00234     {  AtomRep::SPHERERAD, 10 }, // rib_steps : number of steps to use when drawing ribbons
00235     {  AtomRep::BONDRAD, 0.3 }, // rib_width : width of the ribbon
00236     {  AtomRep::SPHERERES, 0.05 }, // rib_height : height of the ribbon
00237     {  AtomRep::ISOSTEPSIZE, 10 }, // maxringsize : maximum number of atoms in a small ring
00238     {  AtomRep::ISOLINETHICKNESS, 5 } // maxpathlength : maximum number of atoms in a path joining two small rings
00239     }
00240   },
00241 #endif
00242 
00243 
00244   //
00245   // Surface, Isosurface, and Solvent reps
00246   //
00247 
00248 #ifdef VMDMSMS
00249   // MSMS surface
00250   { "MSMS", 4, {
00251     {  AtomRep::SPHERERAD, 1.5f }, // probe radius
00252     {  AtomRep::SPHERERES, 1.5f }, // density
00253     {  AtomRep::LINETHICKNESS, 0}, // all atoms
00254     {  AtomRep::BONDRES, 0},       // wireframe
00255     UNUSED, UNUSED }
00256   },
00257 #endif
00258 
00259 #ifdef VMDSURF
00260   // Surf
00261   { "Surf", 2, {
00262     {  AtomRep::SPHERERAD, 1.4f }, // probe radius
00263     {  AtomRep::BONDRES, 0},       // wireframe
00264     UNUSED, UNUSED, UNUSED, UNUSED }
00265   },
00266 #endif
00267 
00268   // Slice of volumetric data
00269   { "VolumeSlice", 4, {
00270     { AtomRep::SPHERERAD,  0.5f }, // slice
00271     { AtomRep::SPHERERES,     0 }, // VolID
00272     { AtomRep::LINETHICKNESS, 0 }, // slice axis
00273     { AtomRep::BONDRES,       2 },  // quality
00274     UNUSED, UNUSED }
00275   },
00276 
00277   // Isosurface of volumetric data
00278   { "Isosurface", 6, {
00279     { AtomRep::SPHERERAD,    0.5f }, // isoval
00280     { AtomRep::SPHERERES,        0}, // VolID
00281     { AtomRep::LINETHICKNESS,    2}, // draw box and isosurface by default
00282     { AtomRep::BONDRES,          2}, // use points method by default
00283     { AtomRep::ISOSTEPSIZE,      1}, // use step size of one by default
00284     { AtomRep::ISOLINETHICKNESS, 1}, // lines are thickness one by default
00285     UNUSED }
00286   },
00287 
00288 #ifdef VMDFIELDLINES
00289   // Volumetric gradient field lines
00290   { "FieldLines", 5, {
00291     { AtomRep::SPHERERES,      0},  // VolID
00292     { AtomRep::SPHERERAD,   1.8f},  // seed value
00293     { AtomRep::BONDRAD,    10.0f},  // minimum line length
00294     { AtomRep::BONDRES,    50.0f},  // maximum line length
00295     { AtomRep::LINETHICKNESS,  1},  // line thickness
00296     UNUSED, UNUSED }
00297   },
00298 #endif
00299 
00300   // Beads 
00301   { "Beads", 2, {
00302     {  AtomRep::SPHERERAD, 1.0f},
00303     {  AtomRep::SPHERERES, DEF_SPH_RES },
00304     UNUSED, UNUSED, UNUSED, UNUSED }
00305   },
00306 
00307   // Dotted
00308   { "Dotted", 2, {
00309     {  AtomRep::SPHERERAD, 1.0f},
00310     {  AtomRep::SPHERERES, DEF_SPH_RES},
00311     UNUSED, UNUSED, UNUSED, UNUSED }
00312   },
00313 
00314   // Dot surface
00315   { "Solvent", 3, {
00316     {  AtomRep::SPHERERAD, 0 }, // probe
00317     // the max value is set in the constructor for AtomRep, so don't
00318     // change things around too much!
00319     {  AtomRep::SPHERERES, 7.0f},  // detail
00320     {  AtomRep::LINETHICKNESS, 1.0f }, // method
00321     UNUSED, UNUSED, UNUSED }
00322   }
00323 };
00324 
00325 
00327 // constructor; parse string and see if OK
00328 AtomRep::AtomRep(void) {
00329   int i, j;
00330  
00331   // initialize variables
00332   repMethod  = DEFAULT_ATOMREP;
00333   repData = repDataStorage[repMethod];
00334   strcpy(cmdStr, AtomRepInfo[repMethod].name);
00335   for(j=0; j < TOTAL; j++) {
00336     memset(repDataStorage[j], 0, MAX_ATOMREP_DATA*sizeof(float));
00337     for(i=0; i < AtomRepInfo[j].numdata ; i++)
00338       repDataStorage[j][AtomRepInfo[j].repdata[i].index] =
00339         AtomRepInfo[j].repdata[i].defValue;
00340   }
00341 
00342 }
00343 
00344 AtomRep::~AtomRep(void) { }
00345 
00347 // parse the given command, and store results.  Return success.
00348 int AtomRep::parse_cmd(const char *newcmd) {
00349   int argc, i, j;
00350   char *argv[256], *cmdStrTok = NULL;
00351 
00352   // make sure the new command is not too long
00353   if(newcmd && strlen(newcmd) > MAX_ATOMREP_CMD) {
00354     msgErr << "Atom representation string is too long (over ";
00355     msgErr << MAX_ATOMREP_CMD << " characters)." << sendmsg;
00356     return FALSE;
00357   }
00358 
00359   // XXX Hack to make the "Off" rep work: alias to "Lines"
00360   if (!strupncmp(newcmd, "off", 3)) newcmd = "Lines";
00361 
00362   // tokenize the command
00363   if(!newcmd || !(cmdStrTok = str_tokenize(newcmd, &argc, argv))) {
00364     // no command; keep current settings
00365     return TRUE;
00366   }
00367 
00368   // see if the command matches a representation we know about
00369   for(i=0; i < AtomRep::TOTAL; i++) {
00370     const AtomRepParamStruct *ari = &(AtomRepInfo[i]);
00371 
00372     if(!strupncmp(argv[0], ari->name, CMDLEN)) {
00373       // the name matches; make sure we do not have too many arguments
00374       if((argc - 1) > ari->numdata) {
00375         msgErr << "Incorrect atom representation command '" << newcmd << "':";
00376         msgErr << "\n  '" << ari->name << "' only takes " << ari->numdata;
00377         msgErr << " arguments maximum." << sendmsg;
00378 
00379         delete [] cmdStrTok;
00380         return FALSE;
00381       }
00382 
00383       // indicate that we've changed to a new rep method
00384       repMethod = i;
00385       repData = repDataStorage[i];
00386 
00387       // copy out the data from the command and store it
00388       for(j=1; j < argc; j++) {
00389         // if a '-' is given, do not change that parameter
00390         if(!(argv[j][0] == '-' && argv[j][1] == '\0'))
00391           repData[ari->repdata[j-1].index] = (float) atof(argv[j]);
00392       }
00393 
00394       // found a match; break from for loop
00395       break;
00396     }
00397   }
00398 
00399   // if i is at the end of the list, we did not find a match
00400   if(i == AtomRep::TOTAL) {
00401     msgErr << "Unknown atom representation command '" << newcmd << "'.";
00402     msgErr << sendmsg;
00403 
00404     delete [] cmdStrTok;
00405     return FALSE;
00406   }
00407 
00408   // if we are here, everything went OK
00409   strcpy(cmdStr, newcmd);
00410 
00411   delete [] cmdStrTok;
00412   return TRUE;
00413 }
00414 
00415 
00417 
00418 // copy contents of another atomrep
00419 AtomRep &AtomRep::operator=(const AtomRep &ar) {
00420   strcpy(cmdStr, ar.cmdStr);
00421   repMethod = ar.repMethod;
00422   repData = repDataStorage[repMethod];
00423   for(int j=0; j < TOTAL; j++)
00424     for(int i=0; i < MAX_ATOMREP_DATA; i++)
00425       repDataStorage[j][i] = ar.repDataStorage[j][i];
00426 
00427   return *this;
00428 }
00429 

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