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