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: DrawForce.C,v $ 00013 * $Author: johns $ $Locker: $ $State: Exp $ 00014 * $Revision: 1.53 $ $Date: 2011/01/20 22:37:43 $ 00015 * 00016 *************************************************************************** 00017 * DESCRIPTION: 00018 * 00019 * Another Child Displayable component for a remote molecule; this displays 00020 * and stores the information about the interactive forces being applied to 00021 * the molecule. If no forces are being used, this draws nothing. 00022 * 00023 * The force information is retrieved from the Atom list in the parent 00024 * molecule. No forces are stored here. 00025 * 00026 * This name is now a misnomer as accelerations are changed, _not_ forces. 00027 * This eliminates the problem of having hydrogens acceleterating 12 time 00028 * faster than carbons, etc. 00029 * 00030 * And now I'm changing it back. We should draw the actual force... 00031 * 00032 ***************************************************************************/ 00033 00034 #include "DrawForce.h" 00035 #include "DrawMolecule.h" 00036 #include "DisplayDevice.h" 00037 #include "Scene.h" 00038 #include "Atom.h" 00039 #include "Timestep.h" 00040 #include "Inform.h" 00041 #include "utilities.h" 00042 #include "Mouse.h" 00043 #include "VMDApp.h" 00044 00045 // Force arrow scaling constant 00046 // XXX ideally this should be a user-defined scaling coefficient 00047 // settable in the text commands and GUI interfaces 00048 #if 1 00049 // Since we now have MUCH faster machines for running simulations, 00050 // we should expect IMD users to be able to apply weaker pulling 00051 // forces to achieve the same end results now. Given this, we 00052 // now use a much larger scaling factor on the force arrows than 00053 // we did in the past. 00054 #define DRAW_FORCE_SCALE 1.0f 00055 #else 00056 // old force arrow scaling factor 00057 #define DRAW_FORCE_SCALE 0.3333f 00058 #endif 00059 00061 00062 DrawForce::DrawForce(DrawMolecule *mr) 00063 : Displayable(mr) { 00064 00065 // save data 00066 mol = mr; 00067 00068 // initialize variables 00069 needRegenerate = TRUE; 00070 colorCat = (-1); 00071 } 00072 00073 00075 00076 void DrawForce::do_color_changed(int ccat) { 00077 // right now this does nothing, since we always redraw the list. But 00078 // the general thing it would do is set the flag that a redraw is needed, 00079 // so looking ahead I'll do this now. 00080 if(ccat == colorCat) { 00081 needRegenerate = TRUE; 00082 } 00083 } 00084 00086 00087 // regenerate the command list 00088 void DrawForce::create_cmdlist(void) { 00089 // do we need to recreate everything? 00090 if(needRegenerate) { 00091 // regenerate both data block and display commands 00092 needRegenerate = FALSE; 00093 reset_disp_list(); 00094 00095 // only put in commands if there is a current frame 00096 Timestep *ts = mol->current(); 00097 if (ts) { 00098 const float *tsforce = ts->force; 00099 00100 // if we have a force array, draw arrows for all non-zero forces 00101 if (tsforce != NULL) { 00102 append(DMATERIALON); 00103 00104 // for each atom, if it has a nonzero user force, then display it 00105 int maxidx = mol->nAtoms * 3; 00106 for (int idx=0; idx<maxidx; idx+=3) { 00107 // check for nonzero forces 00108 if (tsforce[idx]>0.0f || tsforce[idx+1]>0.0f || tsforce[idx+2]>0.0f || 00109 tsforce[idx]<0.0f || tsforce[idx+1]<0.0f || tsforce[idx+2]<0.0f) { 00110 // get position of atom, and the position of the force vector 00111 float fval[3], p2[3], p3[3]; 00112 float *p1 = ts->pos + idx; 00113 for (int k=0; k<3; k++) { 00114 fval[k] = tsforce[idx + k] * DRAW_FORCE_SCALE; 00115 p2[k] = p1[k] + fval[k]; 00116 p3[k] = p1[k] + 0.8f * fval[k]; 00117 } 00118 00119 // find length of force 00120 float p2norm = norm(fval); 00121 00122 // set arrow color 00123 int sc = (int)p2norm; 00124 if (sc >= MAPCLRS) 00125 sc = MAPCLRS - 1; 00126 cmdColorIndex.putdata(MAPCOLOR(sc), cmdList); 00127 00128 // compute the cone radii 00129 float rada = 0.2f * p2norm; 00130 if (rada > 0.3f) 00131 rada = 0.3f; 00132 float radb = 1.5f * rada; 00133 00134 // draw the arrow with two cones 00135 cmdCone.putdata(p3, p1, rada, 0, 9, cmdList); 00136 cmdCone.putdata(p3, p2, radb, 0, 9, cmdList); 00137 } 00138 } 00139 } 00140 } 00141 } 00142 } 00143 00144 00146 // prepare for drawing ... do any updates needed right before draw. 00147 void DrawForce::prepare() { 00148 00149 if (parent->needUpdate()) { 00150 needRegenerate = TRUE; 00151 } 00152 00153 create_cmdlist(); 00154 } 00155
1.2.14 written by Dimitri van Heesch,
© 1997-2002