00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <stdio.h>
00025 #include <ctype.h>
00026
00027 #include "MoleculeList.h"
00028 #include "Inform.h"
00029 #include "Scene.h"
00030 #include "MaterialList.h"
00031 #include "VMDApp.h"
00032 #include "ParseTree.h"
00033 #include "MoleculeGraphics.h"
00034 #include "CommandQueue.h"
00035 #include "TextEvent.h"
00036
00037
00038 #define DEFAULT_ATOMSEL "all"
00039
00041 MoleculeList::MoleculeList(VMDApp *vmdapp, Scene *sc)
00042 : app(vmdapp), scene (sc), molList(8) {
00043
00044 topMol = NULL;
00045 defaultAtomColor = AtomColorName[DEFAULT_ATOMCOLOR];
00046 defaultAtomRepresentation = AtomRepInfo[DEFAULT_ATOMREP].name;
00047 defaultAtomSelection = DEFAULT_ATOMSEL;
00048 defaultAtomMaterial = app->materialList->material_name(0);
00049
00050 currAtomRep = new AtomRep();
00051 currAtomSel = stringdup(DEFAULT_ATOMSEL);
00052 currMaterial = 0;
00053 lastCenter[0] = 0;
00054 lastCenter[1] = 0;
00055 lastCenter[2] = 0;
00056 lastCenter[3] = 1;
00057
00058 #if defined(MLIST_USE_HASH)
00059 inthash_init(&indexIDhash, 5003);
00060 #endif
00061
00062 init_colors();
00063 }
00064
00065
00067 MoleculeList::~MoleculeList(void) {
00068 int i;
00069
00070
00071 for (i=0; i < num(); i++) {
00072 delete molecule(i);
00073 }
00074
00075 #if defined(MLIST_USE_HASH)
00076 inthash_destroy(&indexIDhash);
00077 #endif
00078
00079 delete currAtomColor;
00080 delete currAtomRep;
00081 delete [] currAtomSel;
00082 }
00083
00084
00085 void MoleculeList::init_colors(void) {
00086
00087 currAtomColor = new AtomColor(this, scene);
00088
00089
00090 colorCatIndex[MLCAT_NAMES] = scene->add_color_category("Name");
00091 colorCatIndex[MLCAT_TYPES] = scene->add_color_category("Type");
00092 colorCatIndex[MLCAT_ELEMENTS] = scene->add_color_category("Element");
00093 colorCatIndex[MLCAT_RESNAMES] = scene->add_color_category("Resname");
00094 colorCatIndex[MLCAT_RESTYPES] = scene->add_color_category("Restype");
00095 colorCatIndex[MLCAT_CHAINS] = scene->add_color_category("Chain");
00096 colorCatIndex[MLCAT_SEGNAMES] = scene->add_color_category("Segname");
00097 colorCatIndex[MLCAT_CONFORMATIONS] = scene->add_color_category("Conformation");
00098 colorCatIndex[MLCAT_MOLECULES] = scene->add_color_category("Molecule");
00099 colorCatIndex[MLCAT_SPECIAL] = scene->add_color_category("Highlight");
00100 colorCatIndex[MLCAT_SSTRUCT] = scene->add_color_category("Structure");
00101 colorCatIndex[MLCAT_SURFACES] = scene->add_color_category("Surface");
00102
00103
00104 scene->add_color_item(
00105 colorCatIndex[MLCAT_RESTYPES], "Unassigned", scene->color_index("cyan"));
00106 scene->add_color_item(
00107 colorCatIndex[MLCAT_ELEMENTS], "X", scene->color_index("cyan"));
00108 }
00109
00110
00112
00113
00114 void MoleculeList::add_color_names(int molIndx) {
00115 int i, indx, catIndx;
00116 char newname[2];
00117 NameList<int> *molnames;
00118 Molecule *m;
00119
00120 strcpy(newname, " ");
00121
00122
00123 if(!(m = molecule(molIndx)))
00124 return;
00125
00126
00127
00128
00129
00130
00131 molnames = &(m->atomNames);
00132 int numatomnames = molnames->num();
00133 catIndx = colorCatIndex[MLCAT_NAMES];
00134 for (i=0; i < numatomnames; i++) {
00135
00136 const char *c = molnames->name(i);
00137
00138 while (*c && isdigit(*c))
00139 c++;
00140
00141 if (!(*c))
00142 c = molnames->name(i);
00143
00144 newname[0] = (char)toupper(*c);
00145
00146
00147 indx = scene->add_color_item(catIndx, newname,
00148 scene->num_category_items(catIndx) % VISCLRS);
00149
00150
00151 molnames->set_data(i, indx);
00152 }
00153
00154
00155 molnames = &(m->atomTypes);
00156 int numatomtypes = molnames->num();
00157 catIndx = colorCatIndex[MLCAT_TYPES];
00158 for (i=0; i < numatomtypes; i++) {
00159
00160 const char *c = molnames->name(i);
00161
00162 while (*c && isdigit(*c))
00163 c++;
00164
00165 if (!(*c))
00166 c = molnames->name(i);
00167
00168 newname[0] = (char)toupper(*c);
00169
00170
00171 indx = scene->add_color_item(catIndx, newname,
00172 scene->num_category_items(catIndx) % VISCLRS);
00173
00174
00175 molnames->set_data(i, indx);
00176 }
00177
00178
00179 molnames = &(m->resNames);
00180 int numresnames = molnames->num();
00181 catIndx = colorCatIndex[MLCAT_RESNAMES];
00182 for (i=0; i < numresnames; i++) {
00183 indx = scene->add_color_item(catIndx, molnames->name(i),
00184 scene->num_category_items(catIndx) % VISCLRS);
00185 molnames->set_data(i, indx);
00186
00187
00188 if (resTypes.typecode(molnames->name(i)) < 0) {
00189
00190 resTypes.add_name(molnames->name(i), "Unassigned");
00191 }
00192 }
00193
00194
00195 molnames = &(m->chainNames);
00196 int numchainnames = molnames->num();
00197 catIndx = colorCatIndex[MLCAT_CHAINS];
00198 for (i=0; i < numchainnames; i++) {
00199 indx = scene->add_color_item(catIndx, molnames->name(i),
00200 scene->num_category_items(catIndx) % VISCLRS);
00201 molnames->set_data(i, indx);
00202 }
00203
00204
00205 molnames = &(m->segNames);
00206 int numsegnames = molnames->num();
00207 catIndx = colorCatIndex[MLCAT_SEGNAMES];
00208 for (i=0; i < numsegnames; i++) {
00209 indx = scene->add_color_item(catIndx, molnames->name(i),
00210 scene->num_category_items(catIndx) % VISCLRS);
00211 molnames->set_data(i, indx);
00212 }
00213
00214
00215 molnames = &(m->altlocNames);
00216 int numconformations = molnames->num();
00217 catIndx = colorCatIndex[MLCAT_CONFORMATIONS];
00218 for (i=0; i < numconformations; i++) {
00219 const char *confname = molnames->name(i);
00220 if (confname[0] == '\0') {
00221 confname = "all";
00222 }
00223 indx = scene->add_color_item(catIndx, confname,
00224 scene->num_category_items(catIndx) % VISCLRS);
00225 molnames->set_data(i, indx);
00226 }
00227
00228
00229 catIndx = colorCatIndex[MLCAT_MOLECULES];
00230 char buf[20];
00231 sprintf(buf, "%d", m->id());
00232 scene->add_color_item(catIndx, buf,
00233 scene->num_category_items(catIndx) % VISCLRS);
00234 }
00235
00236
00237
00238 void MoleculeList::add_molecule(Molecule *newmol) {
00239 int newmolindex;
00240
00241
00242 molList.append(newmol);
00243 newmolindex = molList.num() - 1;
00244
00245 #if defined(MLIST_USE_HASH)
00246
00247 inthash_insert(&indexIDhash, newmol->id(), newmolindex);
00248 #endif
00249
00250
00251 make_top(newmolindex);
00252 }
00253
00254
00255
00256 void MoleculeList::make_top(Molecule *m) {
00257 #if 1
00258 if (!m) {
00259 topMol = m;
00260 } else if (m && mol_index_from_id(m->id()) >= 0) {
00261 topMol = m;
00262 }
00263 #else
00264 topMol = m;
00265 #endif
00266 app->commandQueue->runcommand(new MoleculeEvent(
00267 m ? m->id() : -1, MoleculeEvent::MOL_TOP));
00268 }
00269
00270
00271
00272 int MoleculeList::del_molecule(int id) {
00273 Molecule *m, *newtopmol = NULL;
00274
00275
00276 if (!(m = mol_from_id(id)))
00277 return FALSE;
00278
00279 int n = mol_index_from_id(id);
00280
00281
00282 if (is_top(n)) {
00283 if (n+1 < num()) {
00284 newtopmol = molecule(n+1);
00285 } else if (n-1 >= 0) {
00286 newtopmol = molecule(n-1);
00287 } else {
00288 newtopmol = topMol;
00289 }
00290 }
00291
00292 delete m;
00293 molList.remove(n);
00294 #if defined(MLIST_USE_HASH)
00295
00296
00297
00298 inthash_destroy(&indexIDhash);
00299 int molcount = num();
00300 int ml;
00301 inthash_init(&indexIDhash, 5003);
00302 for (ml=0; ml<molcount; ml++) {
00303 inthash_insert(&indexIDhash, molecule(ml)->id(), ml);
00304 }
00305 #endif
00306
00307
00308 if (newtopmol != NULL) {
00309 if (newtopmol != topMol) {
00310 make_top(newtopmol);
00311 } else {
00312 make_top((Molecule *)NULL);
00313 }
00314 }
00315
00316 return TRUE;
00317 }
00318
00319
00320
00321 int MoleculeList::del_all_molecules(void) {
00322 int lastmol;
00323 while ((lastmol=num()) > 0) {
00324 int n = lastmol - 1;
00325 Molecule *m = molecule(n);
00326 delete m;
00327 molList.remove(n);
00328 }
00329 inthash_destroy(&indexIDhash);
00330 inthash_init(&indexIDhash, 5003);
00331 make_top((Molecule *)NULL);
00332
00333 return TRUE;
00334 }
00335
00336 int MoleculeList::set_default_color(const char *s) {
00337 AtomColor ac(this, scene);
00338 int success = ac.change(s);
00339 if (success) {
00340 defaultAtomColor = s;
00341 }
00342 return success;
00343 }
00344
00345 int MoleculeList::set_default_representation(const char *s) {
00346 AtomRep ar;
00347 int success = ar.change(s);
00348 if (success) {
00349 defaultAtomRepresentation = s;
00350 }
00351 return success;
00352 }
00353
00354 int MoleculeList::set_default_selection(const char *s) {
00355 ParseTree *tree = app->atomSelParser->parse(s);
00356 if (!tree) return FALSE;
00357 delete tree;
00358 defaultAtomSelection = s;
00359 return TRUE;
00360 }
00361
00362 int MoleculeList::set_default_material(const char *s) {
00363 if (app->materialList->material_index(s) < 0)
00364 return FALSE;
00365 defaultAtomMaterial = s;
00366 return TRUE;
00367 }
00368
00369
00370 int MoleculeList::set_color(char *s) {
00371 return (currAtomColor->change(s));
00372 }
00373
00374
00375
00376 int MoleculeList::set_representation(char *s) {
00377 return (currAtomRep->change(s));
00378 }
00379
00380
00381
00382 int MoleculeList::set_selection(const char *s) {
00383
00384 ParseTree *tree = app->atomSelParser->parse(s);
00385 if (!tree) return FALSE;
00386 delete tree;
00387 delete [] currAtomSel;
00388 currAtomSel = stringdup(s);
00389 return TRUE;
00390 }
00391
00392
00393
00394 int MoleculeList::set_material(char *s) {
00395 currMaterial = app->materialList->material_index(s);
00396 if (currMaterial < 0) {
00397 currMaterial = 0;
00398 msgErr << "Invalid material specified: " << s << sendmsg;
00399 msgErr << "Using default: " << app->materialList->material_name(0)
00400 << sendmsg;
00401 return 0;
00402 }
00403 return 1;
00404 }
00405
00406
00407
00408 const char *MoleculeList::material(void) {
00409 return app->materialList->material_name(currMaterial);
00410 }
00411
00412
00413
00414 int MoleculeList::add_rep(int n) {
00415 Molecule *mol = molecule(n);
00416 if (!mol) return FALSE;
00417 AtomColor *ac = new AtomColor(*currAtomColor);
00418 AtomRep *ar = new AtomRep(*currAtomRep);
00419 AtomSel *as = new AtomSel(mol->app, app->atomSelParser, mol->id());
00420 const Material *mat = app->materialList->material(currMaterial);
00421 as->change(currAtomSel, mol);
00422 ac->find(mol);
00423 mol->add_rep(ac, ar, as, mat);
00424 return TRUE;
00425 }
00426
00427
00428
00429
00430 int MoleculeList::change_rep(int m, int n) {
00431 Molecule *mol = molecule(n);
00432 if (!mol) return FALSE;
00433 return (mol->change_rep(m, currAtomColor, currAtomRep, currAtomSel) &&
00434 change_repmat(m, n, material()));
00435 }
00436
00437
00438
00439 int MoleculeList::change_repcolor(int m, int n, char *s) {
00440 Molecule *mol = molecule(n);
00441 if (mol) {
00442 AtomColor ac(*currAtomColor);
00443 if (ac.change(s))
00444 return (mol->change_rep(m, &ac, NULL, NULL));
00445 }
00446 return FALSE;
00447 }
00448
00449
00450
00451 int MoleculeList::change_repmethod(int m, int n, char *s) {
00452 Molecule *mol = molecule(n);
00453 if (mol) {
00454 AtomRep ar(*currAtomRep);
00455 if (ar.change(s))
00456 return (mol->change_rep(m, NULL, &ar, NULL));
00457 }
00458 return FALSE;
00459 }
00460
00461
00462
00463 int MoleculeList::change_repsel(int m, int n, const char *s) {
00464 Molecule *mol = molecule(n);
00465 if (!mol) return FALSE;
00466 ParseTree *tree = app->atomSelParser->parse(s);
00467 if (!tree) return FALSE;
00468 delete tree;
00469 return (mol->change_rep(m, NULL, NULL, s));
00470 }
00471
00472
00473
00474 int MoleculeList::change_repmat(int m, int n, const char *s) {
00475 Molecule *mol = molecule(n);
00476 if (mol) {
00477 int ind = app->materialList->material_index(s);
00478 if (ind >= 0) {
00479 DrawMolItem *d = mol->component(m);
00480 if (d) {
00481 d->change_material(app->materialList->material(ind));
00482 return TRUE;
00483 }
00484 }
00485 }
00486 return FALSE;
00487 }
00488
00489
00490
00491 int MoleculeList::del_rep(int m, int n) {
00492 Molecule *mol = molecule(n);
00493 if (mol != NULL)
00494 return (mol->del_rep(m) != 0);
00495 return 0;
00496 }
00497
00498
00499
00500 void MoleculeList::center_from_top_molecule_reps() {
00501 float x, y, z;
00502
00503 if (topMol && topMol->cov(x,y,z)) {
00504 lastCenter[0] = x;
00505 lastCenter[1] = y;
00506 lastCenter[2] = z;
00507 lastCenter[3] = topMol->scale_factor();
00508 }
00509 }
00510
00511
00512 void MoleculeList::center_top_molecule(void) {
00513 if (topMol) {
00514 topMol->reset_transformation();
00515 topMol->mult_scale(lastCenter[3]);
00516 topMol->add_cent_trans(-lastCenter[0], -lastCenter[1], -lastCenter[2]);
00517 }
00518 }
00519
00520
00521 void MoleculeList::center_all_molecules(void) {
00522 int i;
00523 int n = num();
00524 for (i=0; i<n; i++) {
00525 molecule(i)->reset_transformation();
00526 molecule(i)->mult_scale(lastCenter[3]);
00527 molecule(i)->add_cent_trans(-lastCenter[0], -lastCenter[1], -lastCenter[2]);
00528 }
00529 }
00530
00531
00532
00533
00534 Molecule *MoleculeList::check_pickable(Pickable *pobj) {
00535 int i, j, mnum, repnum;
00536
00537
00538 mnum = num();
00539 for (i=0; i < mnum; i++) {
00540
00541 Molecule *mol = molecule(i);
00542 if (pobj == mol)
00543 return mol;
00544
00545
00546 repnum = mol->components();
00547 for (j=0; j < repnum; j++)
00548 if (pobj == mol->component(j))
00549 return mol;
00550
00551
00552 if (pobj == mol->moleculeGraphics())
00553 return mol;
00554 }
00555
00556 return NULL;
00557 }
00558