00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "GeometryMol.h"
00027 #include "MoleculeList.h"
00028 #include "Molecule.h"
00029 #include "Displayable.h"
00030 #include "DispCmds.h"
00031 #include "utilities.h"
00032 #include "VMDApp.h"
00033 #include "TextEvent.h"
00034 #include "CommandQueue.h"
00035
00037 class GeometryMonitor : public DrawMoleculeMonitor {
00038 private:
00039 GeometryMol *mygeo;
00040
00041 public:
00042 GeometryMonitor(GeometryMol *g, int id) : mygeo(g), molid(id) { }
00043 void notify(int id) {
00044 mygeo->calculate();
00045 mygeo->update();
00046 }
00047 const int molid;
00048 };
00049
00051 GeometryMol::GeometryMol(int n, int *mols, int *atms, const int *cells,
00052 MoleculeList *mlist, CommandQueue *cq, Displayable *d)
00053 : Displayable(d) {
00054
00055 objIndex = new int[n];
00056 comIndex = new int[n];
00057 cellIndex = new int[3*n];
00058 if (cells) {
00059 memcpy(cellIndex, cells, 3*n*sizeof(int));
00060 } else {
00061 memset(cellIndex, 0, 3*n*sizeof(int));
00062 }
00063 geomValue = 0.0;
00064 numItems = n;
00065 hasValue = TRUE;
00066
00067 my_color = 8;
00068 my_text_size = 1.0f;
00069 my_text_offset[0] = my_text_offset[1] = 0;
00070 my_text_format = "%R%d:%a";
00071
00072 molList = mlist;
00073 cmdqueue = cq;
00074 gmName = NULL;
00075 uniquegmName = NULL;
00076
00077 for(int i=0; i < numItems; i++) {
00078 objIndex[i] = mols[i];
00079 comIndex[i] = atms[i];
00080
00081
00082 if(i > 0 && objIndex[i-1]==objIndex[i] && comIndex[i-1]==comIndex[i] &&
00083 !memcmp(cellIndex+3*i, cellIndex+3*(i-1), 3*sizeof(int))) {
00084
00085
00086 comIndex[0] = (-1);
00087 }
00088
00089 Molecule *m = molList->mol_from_id(mols[i]);
00090 if (m) {
00091 GeometryMonitor *mon = new GeometryMonitor(this, objIndex[i]);
00092 m->register_monitor(mon);
00093 monitors.append(mon);
00094 }
00095 }
00096
00097
00098 sort_items();
00099
00100
00101 geom_set_name();
00102 }
00103
00104
00106 GeometryMol::~GeometryMol(void) {
00107
00108 if(gmName)
00109 delete [] gmName;
00110 if(uniquegmName)
00111 delete [] uniquegmName;
00112 delete [] objIndex;
00113 delete [] comIndex;
00114 delete [] cellIndex;
00115 for (int i=0; i<monitors.num(); i++) {
00116 GeometryMonitor *mon = monitors[i];
00117 Molecule *m = molList->mol_from_id(mon->molid);
00118 if (m) m->unregister_monitor(mon);
00119 delete mon;
00120 }
00121 }
00122
00123
00125
00126 void GeometryMol::atom_full_name(char *buf, Molecule *mol, int ind) {
00127 sprintf(buf, "%-d/%-d", mol->id(), ind);
00128 }
00129
00130 void GeometryMol::atom_short_name(char *buf, Molecule *mol, int ind) {
00131 MolAtom *nameAtom = mol->atom(ind);
00132 sprintf(buf, "%s%d:%s",
00133 mol->resNames.name(nameAtom->resnameindex),
00134 nameAtom->resid,
00135 mol->atomNames.name(nameAtom->nameindex));
00136 }
00137
00138 void GeometryMol::atom_formatted_name(JString &str, Molecule *mol, int ind) {
00139 MolAtom *atom = mol->atom(ind);
00140 str = my_text_format;
00141 char buf[32];
00142
00143 JString resname = mol->resNames.name(atom->resnameindex);
00144 str.gsub("%R", (const char *)resname);
00145
00146 resname.to_camel();
00147 str.gsub("%r", (const char *)resname);
00148
00149 sprintf(buf, "%d", atom->resid);
00150 str.gsub("%d", buf);
00151
00152 str.gsub("%a", mol->atomNames.name(atom->nameindex));
00153
00154 sprintf(buf, "%4.3f", mol->charge()[ind]);
00155 str.gsub("%q", buf);
00156
00157 sprintf(buf, "%d", ind);
00158 str.gsub("%i", buf);
00159 }
00160
00161
00162 void GeometryMol::geom_set_name(void) {
00163 char namebuf[256];
00164 char namebuf2[256];
00165 char cellbuf[256];
00166 Molecule *mol;
00167 register int i;
00168
00169 if(items() < 1)
00170 return;
00171
00172
00173 if((mol = check_mol(objIndex[0], comIndex[0]))) {
00174 atom_full_name(namebuf, mol, comIndex[0]);
00175 atom_short_name(namebuf2, mol, comIndex[0]);
00176 sprintf(cellbuf, "-%d-%d-%d", cellIndex[0], cellIndex[1], cellIndex[2]);
00177 strcat(namebuf, cellbuf);
00178 } else
00179 return;
00180
00181
00182 for(i = 1; i < items(); i++) {
00183 if((mol = check_mol(objIndex[i], comIndex[i]))) {
00184 strcat(namebuf, "/");
00185 atom_full_name(namebuf+strlen(namebuf), mol, comIndex[i]);
00186 strcat(namebuf2, "/");
00187 atom_short_name(namebuf2+strlen(namebuf2), mol, comIndex[i]);
00188 sprintf(cellbuf, "-%d-%d-%d", cellIndex[3*i+0], cellIndex[3*i+1],
00189 cellIndex[3*i+2]);
00190 strcat(namebuf, cellbuf);
00191 } else {
00192 return;
00193 }
00194 }
00195
00196
00197 if(gmName)
00198 delete [] gmName;
00199 if(uniquegmName)
00200 delete [] uniquegmName;
00201
00202 uniquegmName = stringdup(namebuf);
00203 gmName = stringdup(namebuf2);
00204 }
00205
00206
00207
00208
00209 void GeometryMol::sort_items(void) {
00210 register int i,j;
00211
00212
00213 if( (comIndex[0] > comIndex[items()- 1]) ||
00214 (comIndex[0] == comIndex[items()-1] &&
00215 objIndex[0] > objIndex[items()-1]) ) {
00216 for(i=0, j=(items() - 1); i < j; i++, j--) {
00217 int tmpindex = comIndex[i];
00218 comIndex[i] = comIndex[j];
00219 comIndex[j] = tmpindex;
00220 tmpindex = objIndex[i];
00221 objIndex[i] = objIndex[j];
00222 objIndex[j] = tmpindex;
00223 int celltmp[3];
00224 memcpy(celltmp, cellIndex+3*i, 3*sizeof(int));
00225 memcpy(cellIndex+3*i, cellIndex+3*j, 3*sizeof(int));
00226 memcpy(cellIndex+3*j, celltmp, 3*sizeof(int));
00227 }
00228 }
00229 }
00230
00231
00232
00233
00234 Molecule *GeometryMol::check_mol(int m, int a) {
00235
00236 Molecule *mol = molList->mol_from_id(m);
00237
00238 if(!mol || a < 0 || a >= mol->nAtoms)
00239 mol = NULL;
00240
00241 return mol;
00242 }
00243
00244
00245
00246
00247 Molecule *GeometryMol::transformed_atom_coord(int ind, float *pos) {
00248 Molecule *mol;
00249
00250
00251 int a=comIndex[ind];
00252 if((mol = normal_atom_coord(ind, pos)) && mol->atom_displayed(a)) {
00253
00254
00255 (mol->tm).multpoint3d(pos, pos);
00256
00257
00258 return mol;
00259 }
00260
00261
00262 return NULL;
00263 }
00264
00265
00266
00267
00268 Molecule *GeometryMol::normal_atom_coord(int ind, float *pos) {
00269 Timestep *now;
00270 Molecule *mol;
00271
00272 int m=objIndex[ind];
00273 int a=comIndex[ind];
00274 const int *cell = cellIndex+3*ind;
00275
00276
00277 if((mol = check_mol(m, a)) && (now = mol->current())) {
00278 memcpy((void *)pos, (void *)(now->pos + 3*a), 3*sizeof(float));
00279
00280
00281 Matrix4 mat;
00282 now->get_transform_from_cell(cell, mat);
00283 mat.multpoint3d(pos, pos);
00284
00285 return mol;
00286 }
00287
00288
00289 return NULL;
00290 }
00291
00292
00293
00294 void GeometryMol::display_line(float *p1, float *p2, VMDDisplayList *d) {
00295 DispCmdLine cmdLineGeom;
00296 cmdLineGeom.putdata(p1, p2, d);
00297 }
00298
00299
00300
00301 void GeometryMol::display_string(const char *str, VMDDisplayList *d) {
00302 DispCmdTextOffset cmdTextOffset;
00303 cmdTextOffset.putdata(my_text_offset[0], my_text_offset[1], d);
00304
00305 DispCmdTextSize cmdTextSize;
00306 cmdTextSize.putdata(my_text_size, d);
00307
00308 DispCmdText cmdTextGeom;
00309 cmdTextGeom.putdata(valuePos, str, d);
00310 }
00311
00313
00314
00315 const char *GeometryMol::name(void) {
00316 return (gmName ? gmName : "");
00317 }
00318
00319
00320
00321
00322 const char *GeometryMol::unique_name(void) {
00323 return (uniquegmName ? uniquegmName : name());
00324 }
00325
00326
00327
00328 int GeometryMol::ok(void) {
00329 register int i;
00330
00331 for(i=0; i < numItems; i++)
00332 if(!check_mol(objIndex[i], comIndex[i]))
00333 return FALSE;
00334
00335 return TRUE;
00336 }
00337
00338
00339
00340 int GeometryMol::calculate_all(ResizeArray<float> &valArray) {
00341 int i, max_ts, orig_ts;
00342
00343
00344 Molecule *mol = molList->mol_from_id(objIndex[0]);
00345 if( ! has_value() || !mol )
00346 return FALSE;
00347
00348
00349 max_ts = mol->numframes()-1;
00350 if((orig_ts = mol->frame()) < 0)
00351 return FALSE;
00352
00353
00354 for(i=0; i <= max_ts; i++) {
00355 mol->override_current_frame(i);
00356 valArray.append(calculate());
00357 }
00358
00359
00360 mol->override_current_frame(orig_ts);
00361 calculate();
00362
00363 return TRUE;
00364 }
00365
00366
00367
00368
00369 void GeometryMol::set_pick_selection(int , int num, int *atoms) {
00370 cmdqueue->runcommand(new PickSelectionEvent(num, atoms));
00371 }
00372
00373 void GeometryMol::set_pick_selection() {
00374 cmdqueue->runcommand(new PickSelectionEvent(0, 0));
00375 }
00376
00377 void GeometryMol::set_pick_value(double newval) {
00378 cmdqueue->runcommand(new PickValueEvent(newval));
00379 }
00380