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 <stdio.h>
00027 #include <stdlib.h>
00028 #include <sys/types.h>
00029 #include <math.h>
00030 #include <ctype.h>
00031
00032 #include "DrawMolItem.h"
00033 #include "Molecule.h"
00034 #include "DispCmds.h"
00035 #include "Inform.h"
00036 #include "Scene.h"
00037 #include "TextEvent.h"
00038 #include "BondSearch.h"
00039 #include "DisplayDevice.h"
00040 #ifdef VMDMSMS
00041 #include "MSMSInterface.h"
00042 #endif
00043 #ifdef VMDSURF
00044 #include "Surf.h"
00045 #endif
00046 #include "VMDApp.h"
00047 #include "VolumetricData.h"
00048
00050 DrawMolItem::DrawMolItem(const char *nm, DrawMolecule *dm, AtomColor *ac,
00051 AtomRep *ar, AtomSel *as)
00052 : Displayable(dm) {
00053
00054
00055 mol = dm;
00056 avg = new float[3*mol->nAtoms];
00057 avgsize = 0;
00058 atomColor = ac;
00059 atomRep = ar;
00060 atomSel = as;
00061 structwarningcount = 0;
00062
00063 name = stringdup(nm);
00064 framesel = stringdup("now");
00065 tubearray = NULL;
00066
00067 colorlookups = new ColorLookup[MAXCOLORS];
00068
00069
00070 create_modified_CR_spline_basis(spline_basis, 1.25f);
00071
00072
00073 waveftype = -1;
00074 wavefspin = -1;
00075 wavefexcitation = -1;
00076 gridorbid = -1;
00077 orbgridspacing = -1.0f;
00078 orbgridisdensity = -1;
00079 orbvol = NULL;
00080
00081
00082 voltexVolid = -1;
00083 voltexColorMethod = -1;
00084 voltexDataMin = 0;
00085 voltexDataMax = 0;
00086
00087
00088 needRegenerate = MOL_REGEN | COL_REGEN | SEL_REGEN;
00089 update_pbc = 0;
00090 update_ss = 0;
00091 update_ts = 0;
00092 update_traj = 0;
00093 isOn = TRUE;
00094 }
00095
00097 DrawMolItem::~DrawMolItem(void) {
00098 if (tubearray) {
00099 for (int i=0; i<tubearray->num(); i++)
00100 delete (*tubearray)[i];
00101 delete tubearray;
00102 tubearray = NULL;
00103 }
00104
00105 delete atomColor;
00106 delete atomRep;
00107 delete atomSel;
00108 delete [] colorlookups;
00109 delete [] name;
00110 delete [] avg;
00111 delete [] framesel;
00112 delete orbvol;
00113 }
00114
00115 int DrawMolItem::emitstructwarning(void) {
00116 if (structwarningcount < 30) {
00117 structwarningcount++;
00118 return 1;
00119 }
00120
00121 if (structwarningcount == 30) {
00122 msgErr << "Maximum structure display warnings reached, further warnings will be suppressed" << sendmsg;
00123 structwarningcount++;
00124 return 0;
00125 }
00126
00127 structwarningcount++;
00128 return 0;
00129 }
00130
00131 void DrawMolItem::update_lookups(AtomColor *ac, AtomSel *sel,
00132 ColorLookup *lookups) {
00133 int i;
00134 for (i=0; i<MAXCOLORS; i++) {
00135 lookups[i].num = 0;
00136 }
00137 for (i=0; i<sel->num_atoms; i++) {
00138 if (sel->on[i]) {
00139 int color = ac->color[i];
00140 lookups[color].append(i);
00141 }
00142 }
00143 }
00144
00145 void DrawMolItem::set_pbc(int pbc) {
00146 cmdList->pbc = pbc;
00147 change_pbc();
00148
00149
00150
00151
00152 mol->notify();
00153 }
00154
00155 int DrawMolItem::get_pbc() const {
00156 return cmdList->pbc;
00157 }
00158
00159 void DrawMolItem::set_pbc_images(int n) {
00160 if (n < 1) return;
00161 cmdList->npbc = n;
00162 need_matrix_recalc();
00163 mol->notify();
00164 }
00165 int DrawMolItem::get_pbc_images() const {
00166 return cmdList->npbc;
00167 }
00168
00169 static void parse_frames(const char *beg, int len, int maxframe,
00170 ResizeArray<int>& frames) {
00171 if (!len) {
00172 msgErr << "parse_frames got zero-length string!" << sendmsg;
00173 return;
00174 }
00175 const char *firstsep = NULL, *secondsep = NULL;
00176 int i;
00177 for (i=0; i<len; i++) {
00178 if (beg[i] == ':') {
00179 firstsep = beg+i;
00180 break;
00181 }
00182 }
00183 for (++i; i < len; i++) {
00184 if (beg[i] == ':') {
00185 secondsep = beg+i;
00186 break;
00187 }
00188 }
00189 char *endptr;
00190 long first, second, third;
00191 first = strtol(beg, &endptr, 0);
00192 if (endptr == beg) {
00193 msgErr << "frame element is invalid: " << beg << sendmsg;
00194 return;
00195 }
00196 second = third = first;
00197 if (firstsep) {
00198 firstsep++;
00199
00200 if (!(*firstsep)) {
00201 second = maxframe;
00202 } else {
00203 second = strtol(firstsep, &endptr, 0);
00204 if (endptr == firstsep) {
00205 msgErr << "frame element is invalid: " << beg << sendmsg;
00206 return;
00207 }
00208 }
00209 }
00210 if (secondsep) {
00211 secondsep++;
00212 if (!(*secondsep)) {
00213 third = maxframe;
00214 } else {
00215 third = strtol(secondsep, &endptr, 0);
00216 if (endptr == secondsep) {
00217 msgErr << "frame element is invalid: " << beg << sendmsg;
00218 return;
00219 }
00220 }
00221 }
00222
00223 if (!firstsep) {
00224
00225 frames.append((int)first);
00226 } else if (!secondsep) {
00227 for (long i=first; i <= second; i++) {
00228
00229 frames.append((int)i);
00230 }
00231 } else {
00232 for (long i=first; i <= third; i += second) {
00233
00234 frames.append((int)i);
00235 }
00236 }
00237 }
00238
00239 void DrawMolItem::set_drawframes(const char *frames) {
00240 if (!frames) return;
00241 while (isspace(*frames)) frames++;
00242 if (!strncmp(frames, "now", 3) && !strncmp(framesel, "now", 3)) return;
00243 delete [] framesel;
00244 framesel = stringdup(frames);
00245 needRegenerate |= MOL_REGEN;
00246 }
00247
00249
00250 void DrawMolItem::create_cmdlist() {
00251 int i;
00252
00253
00254 if (needRegenerate) {
00255
00256 repNumber = -1;
00257 for (i = 0; i < mol->components(); i++) {
00258 if (this == mol->component(i))
00259 repNumber = i;
00260 }
00261
00262 if (needRegenerate & COL_REGEN)
00263 atomColor->find(mol);
00264
00265 if (needRegenerate & SEL_REGEN)
00266 atomSel->change(NULL, mol);
00267
00268 if (needRegenerate & REP_REGEN) {
00269
00270 char *newcmdstr = stringdup(atomRep->cmdStr);
00271 atomRep->change(newcmdstr);
00272 delete [] newcmdstr;
00273 }
00274
00275 reset_disp_list();
00276
00277
00278
00279
00280
00281 char repbuf[2048];
00282 sprintf(repbuf, "vmd_mol%d_rep%d", mol->id(), repNumber);
00283 cmdBeginRepGeomGroup.putdata(repbuf, cmdList);
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302 if (atomColor->method() == AtomColor::VOLUME ||
00303 atomRep->method() == AtomRep::VOLSLICE) {
00304
00305 updateVolumeTexture();
00306
00307 float v0[3], v1[3], v2[3], v3[3];
00308 volumeTexture.calculateTexgenPlanes(v0, v1, v2, v3);
00309 DispCmdVolumeTexture cmdVolTexture;
00310 cmdVolTexture.putdata(
00311 volumeTexture.getTextureID(),
00312 volumeTexture.getTextureSize(),
00313 volumeTexture.getTextureMap(),
00314 v0, v1, v2, v3,
00315 cmdList);
00316 }
00317
00318 if (strcmp(framesel, "now")) {
00319
00320 ResizeArray<int> frames;
00321 const char *endptr = framesel;
00322 int maxframe = mol->numframes() - 1;
00323 do {
00324 const char *begptr = endptr;
00325 while (isspace(*begptr)) begptr++;
00326 endptr = begptr;
00327 while (*endptr && !isspace(*endptr)) endptr++;
00328 parse_frames(begptr, endptr-begptr, maxframe, frames);
00329 } while (*endptr);
00330
00331 int curframe = mol->frame();
00332
00333
00334 for (i=0; i<frames.num(); i++) {
00335 int frame = frames[i];
00336 if (frame < 0 || frame > maxframe)
00337 continue;
00338
00339 mol->override_current_frame(frame);
00340
00341
00342
00343
00344 switch (atomColor->method()) {
00345 case AtomColor::USER:
00346 case AtomColor::USER2:
00347 case AtomColor::USER3:
00348 case AtomColor::USER4:
00349 case AtomColor::PHYSICALTIME:
00350 case AtomColor::TIMESTEP:
00351 case AtomColor::VELOCITY:
00352 atomColor->find(mol);
00353 break;
00354 }
00355 do_create_cmdlist();
00356 }
00357 mol->override_current_frame(curframe);
00358 } else {
00359 do_create_cmdlist();
00360 }
00361
00362
00363 if (atomColor->method() == AtomColor::VOLUME ||
00364 atomRep->method() == AtomRep::VOLSLICE) {
00365 append(DVOLTEXOFF);
00366 }
00367
00368 cacheskip(1);
00369 } else {
00370 cacheskip(0);
00371 }
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383 if (atomColor->method() == AtomColor::VOLUME ||
00384 atomRep->method() == AtomRep::VOLSLICE) {
00385 cacheskip(1);
00386 }
00387
00388 needRegenerate = NO_REGEN;
00389 }
00390
00391
00392
00393 void DrawMolItem::do_create_cmdlist(void) {
00394 float *framepos;
00395 int i;
00396
00397
00398 if (mol->current()) {
00399 if (atomSel->do_update)
00400 atomSel->change(NULL, mol);
00401
00402 if (atomColor->do_update)
00403 atomColor->find(mol);
00404
00405 framepos = (mol->current())->pos;
00406
00407
00408 if (avgsize && atomSel->selected > 0) {
00409 const int curframe = mol->frame();
00410 const int begframe = curframe - avgsize;
00411 const int endframe = curframe + avgsize;
00412 const int lastframe = mol->numframes() - 1;
00413 #if 0
00414
00415
00416
00417
00418
00419
00420 const int atomloopfirst = atomSel->firstsel;
00421 const int atomlooplast = 3*(atomSel->lastsel+1);
00422 #else
00423
00424 const int atomloopfirst = 0;
00425 const int atomlooplast = 3*mol->nAtoms;
00426 #endif
00427 const float rescale = 1.0f/(2.0f*avgsize+1.0f);
00428
00429 #define VMDPBCSMOOTH 1
00430 #ifdef VMDPBCSMOOTH
00431
00432 int isortho,usepbc;
00433 float a,b,c,alpha,beta,gamma;
00434
00435
00436 isortho=usepbc=1;
00437 a=b=c=9999999.0f;
00438 alpha=beta=gamma=90.0f;
00439
00440
00441 const float *ref = mol->get_frame(curframe)->pos;
00442 #endif
00443
00444 memset(avg, 0, 3*mol->nAtoms*sizeof(float));
00445
00446 for (i=begframe; i<=endframe; i++) {
00447 int ind = i;
00448 if (ind < 0)
00449 ind = 0;
00450 else if (ind > lastframe)
00451 ind = lastframe;
00452 const float *ts = mol->get_frame(ind)->pos;
00453
00454 #ifdef VMDPBCSMOOTH
00455
00456 a = mol->get_frame(ind)->a_length;
00457 b = mol->get_frame(ind)->b_length;
00458 c = mol->get_frame(ind)->c_length;
00459 alpha = mol->get_frame(ind)->alpha;
00460 beta = mol->get_frame(ind)->beta;
00461 gamma = mol->get_frame(ind)->gamma;
00462
00463
00464 if (fabsf(a*b*c) < 0.0001)
00465 usepbc=0;
00466
00467
00468 if ((alpha != 90.0) || (beta != 90.0) || (gamma != 90.0))
00469 isortho=0;
00470
00471
00472 if (!isortho)
00473 usepbc=0;
00474
00475 if (usepbc) {
00476 const float ahalf=a*0.5f;
00477 const float bhalf=b*0.5f;
00478 const float chalf=c*0.5f;
00479
00480
00481
00482
00483 for (int j=atomloopfirst; j<atomlooplast; j += 3) {
00484 float adiff=ts[j ]-ref[j ];
00485 avg[j ] += ts[j ] + ((adiff < -ahalf) ? a : ( (adiff > ahalf) ? -a : 0));
00486 float bdiff=ts[j+1]-ref[j+1];
00487 avg[j+1] += ts[j+1] + ((bdiff < -bhalf) ? b : ( (bdiff > bhalf) ? -b : 0));
00488 float cdiff=ts[j+2]-ref[j+2];
00489 avg[j+2] += ts[j+2] + ((cdiff < -chalf) ? c : ( (cdiff > chalf) ? -c : 0));
00490 }
00491 } else {
00492 for (int j=atomloopfirst; j<atomlooplast; j++) {
00493 avg[j] += ts[j];
00494 }
00495 }
00496 #else
00497 for (int j=atomloopfirst; j<atomlooplast; j++) {
00498 avg[j] += ts[j];
00499 }
00500 #endif
00501
00502 }
00503
00504
00505 for (int j=atomloopfirst; j<atomlooplast; j++)
00506 avg[j] *= rescale;
00507
00508 framepos = avg;
00509 }
00510
00511
00512 switch (atomRep->method()) {
00513 case AtomRep::LINES:
00514 draw_lines(framepos,
00515 (int)atomRep->get_data(AtomRep::LINETHICKNESS),
00516 atomRep->get_data(AtomRep::ISOLINETHICKNESS));
00517 place_picks(framepos);
00518 break;
00519
00520 case AtomRep::BONDS:
00521 draw_bonds(framepos,
00522 atomRep->get_data(AtomRep::BONDRAD),
00523 (int)atomRep->get_data(AtomRep::BONDRES),
00524 atomRep->get_data(AtomRep::ISOLINETHICKNESS));
00525 place_picks(framepos);
00526 break;
00527
00528 case AtomRep::DYNAMICBONDS:
00529 draw_dynamic_bonds(framepos,
00530 atomRep->get_data(AtomRep::BONDRAD),
00531 (int)atomRep->get_data(AtomRep::BONDRES),
00532 atomRep->get_data(AtomRep::SPHERERAD));
00533 break;
00534
00535 case AtomRep::HBONDS:
00536 draw_hbonds(framepos,
00537 atomRep->get_data(AtomRep::SPHERERAD),
00538 (int)atomRep->get_data(AtomRep::LINETHICKNESS),
00539 atomRep->get_data(AtomRep::BONDRAD));
00540 break;
00541
00542 case AtomRep::POINTS:
00543 draw_points(framepos, atomRep->get_data(AtomRep::LINETHICKNESS));
00544 place_picks(framepos);
00545 break;
00546
00547 case AtomRep::VDW:
00548 draw_solid_spheres(framepos,
00549 (int)atomRep->get_data(AtomRep::SPHERERES),
00550 atomRep->get_data(AtomRep::SPHERERAD),
00551 0.0);
00552 place_picks(framepos);
00553 break;
00554
00555 case AtomRep::CPK:
00556 draw_cpk_licorice(framepos, 1,
00557 atomRep->get_data(AtomRep::BONDRAD),
00558 (int)atomRep->get_data(AtomRep::BONDRES),
00559 atomRep->get_data(AtomRep::SPHERERAD),
00560 (int)atomRep->get_data(AtomRep::SPHERERES),
00561 (int)atomRep->get_data(AtomRep::LINETHICKNESS),
00562 atomRep->get_data(AtomRep::ISOLINETHICKNESS));
00563 place_picks(framepos);
00564 break;
00565
00566 case AtomRep::LICORICE:
00567 draw_cpk_licorice(framepos, 0,
00568 atomRep->get_data(AtomRep::BONDRAD),
00569 (int)atomRep->get_data(AtomRep::BONDRES),
00570 atomRep->get_data(AtomRep::SPHERERAD),
00571 (int)atomRep->get_data(AtomRep::SPHERERES),
00572 (int)atomRep->get_data(AtomRep::LINETHICKNESS),
00573 atomRep->get_data(AtomRep::ISOLINETHICKNESS));
00574 place_picks(framepos);
00575 break;
00576
00577 #ifdef VMDPOLYHEDRA
00578 case AtomRep::POLYHEDRA:
00579 draw_polyhedra(framepos, atomRep->get_data(AtomRep::SPHERERAD));
00580 break;
00581 #endif
00582
00583 case AtomRep::TRACE:
00584 draw_trace(framepos,
00585 atomRep->get_data(AtomRep::BONDRAD),
00586 (int)atomRep->get_data(AtomRep::BONDRES),
00587 (int)atomRep->get_data(AtomRep::LINETHICKNESS));
00588 place_picks(framepos);
00589 break;
00590
00591 case AtomRep::TUBE:
00592 draw_tube(framepos,
00593 atomRep->get_data(AtomRep::BONDRAD),
00594 (int)atomRep->get_data(AtomRep::BONDRES));
00595 break;
00596
00597 case AtomRep::RIBBONS:
00598 draw_ribbons(framepos,
00599 atomRep->get_data(AtomRep::BONDRAD) / 3.0f,
00600 (int)atomRep->get_data(AtomRep::BONDRES),
00601 atomRep->get_data(AtomRep::LINETHICKNESS));
00602 break;
00603
00604 case AtomRep::NEWRIBBONS:
00605 draw_ribbons_new(framepos,
00606 atomRep->get_data(AtomRep::BONDRAD) / 3.0f,
00607 (int)atomRep->get_data(AtomRep::BONDRES),
00608 (int)atomRep->get_data(AtomRep::SPHERERAD),
00609 atomRep->get_data(AtomRep::LINETHICKNESS));
00610 break;
00611
00612 #ifdef VMDWITHCARBS
00613 case AtomRep::RINGS_PAPERCHAIN:
00614 draw_rings_paperchain(framepos,
00615 atomRep->get_data(AtomRep::LINETHICKNESS),
00616 (int)atomRep->get_data(AtomRep::ISOSTEPSIZE)
00617 );
00618 place_picks(framepos);
00619 break;
00620
00621 case AtomRep::RINGS_TWISTER:
00622 draw_rings_twister(framepos,
00623 (int)atomRep->get_data(AtomRep::LINETHICKNESS),
00624 (int)atomRep->get_data(AtomRep::BONDRES),
00625 (int)atomRep->get_data(AtomRep::SPHERERAD),
00626 atomRep->get_data(AtomRep::BONDRAD),
00627 atomRep->get_data(AtomRep::SPHERERES),
00628 (int)atomRep->get_data(AtomRep::ISOSTEPSIZE),
00629 (int)atomRep->get_data(AtomRep::ISOLINETHICKNESS)
00630 );
00631 place_picks(framepos);
00632 break;
00633 #endif
00634
00635 case AtomRep::NEWCARTOON:
00636 draw_cartoon_ribbons(framepos,
00637 (int)atomRep->get_data(AtomRep::BONDRES),
00638 atomRep->get_data(AtomRep::BONDRAD),
00639 (float) atomRep->get_data(AtomRep::LINETHICKNESS),
00640 1,
00641 (int)atomRep->get_data(AtomRep::SPHERERAD));
00642 break;
00643
00644 case AtomRep::STRUCTURE:
00645 draw_structure(framepos,
00646 atomRep->get_data(AtomRep::BONDRAD),
00647 (int)atomRep->get_data(AtomRep::BONDRES),
00648 (int)atomRep->get_data(AtomRep::LINETHICKNESS));
00649 break;
00650
00651 #ifdef VMDMSMS
00652 case AtomRep::MSMS:
00653 draw_msms(framepos,
00654 (int)atomRep->get_data(AtomRep::BONDRES),
00655 (atomRep->get_data(AtomRep::LINETHICKNESS) < 0.5),
00656 atomRep->get_data(AtomRep::SPHERERAD),
00657 atomRep->get_data(AtomRep::SPHERERES));
00658 break;
00659 #endif
00660 #ifdef VMDSURF
00661 case AtomRep::SURF:
00662 draw_surface(framepos,
00663 (int)atomRep->get_data(AtomRep::BONDRES),
00664 atomRep->get_data(AtomRep::SPHERERAD));
00665 break;
00666 #endif
00667 #ifdef VMDQUICKSURF
00668 case AtomRep::QUICKSURF:
00669 draw_quicksurf(framepos,
00670 int(atomRep->get_data(AtomRep::BONDRES)),
00671 atomRep->get_data(AtomRep::SPHERERAD),
00672 atomRep->get_data(AtomRep::BONDRAD),
00673 atomRep->get_data(AtomRep::GRIDSPACING));
00674 break;
00675 #endif
00676
00677 case AtomRep::VOLSLICE:
00678 draw_volslice((int)atomRep->get_data(AtomRep::SPHERERES),
00679 atomRep->get_data(AtomRep::SPHERERAD),
00680 (int)atomRep->get_data(AtomRep::LINETHICKNESS),
00681 (int)atomRep->get_data(AtomRep::BONDRES));
00682 break;
00683
00684 case AtomRep::FIELDLINES:
00685 draw_volume_field_lines((int)atomRep->get_data(AtomRep::SPHERERES),
00686 atomRep->get_data(AtomRep::SPHERERAD),
00687 atomRep->get_data(AtomRep::BONDRAD),
00688 atomRep->get_data(AtomRep::BONDRES),
00689 atomRep->get_data(AtomRep::LINETHICKNESS));
00690 break;
00691
00692 case AtomRep::ISOSURFACE:
00693 draw_isosurface((int)atomRep->get_data(AtomRep::SPHERERES),
00694 atomRep->get_data(AtomRep::SPHERERAD),
00695 (int)atomRep->get_data(AtomRep::LINETHICKNESS),
00696 (int)atomRep->get_data(AtomRep::BONDRES),
00697 (int)atomRep->get_data(AtomRep::ISOSTEPSIZE),
00698 (int)atomRep->get_data(AtomRep::ISOLINETHICKNESS));
00699 break;
00700
00701 case AtomRep::ORBITAL:
00702 draw_orbital(
00703 #if 1
00704 (getenv("VMDMODENSITY") != NULL),
00705 #else
00706 0,
00707 #endif
00708 (int)atomRep->get_data(AtomRep::WAVEFNCTYPE),
00709 (int)atomRep->get_data(AtomRep::WAVEFNCSPIN),
00710 (int)atomRep->get_data(AtomRep::WAVEFNCEXCITATION),
00711 (int)atomRep->get_data(AtomRep::SPHERERES),
00712 atomRep->get_data(AtomRep::SPHERERAD),
00713 (int)atomRep->get_data(AtomRep::LINETHICKNESS),
00714 (int)atomRep->get_data(AtomRep::BONDRES),
00715 atomRep->get_data(AtomRep::GRIDSPACING),
00716 (int)atomRep->get_data(AtomRep::ISOSTEPSIZE),
00717 (int)atomRep->get_data(AtomRep::ISOLINETHICKNESS));
00718 break;
00719
00720 case AtomRep::BEADS:
00721 draw_residue_beads(framepos,
00722 (int)atomRep->get_data(AtomRep::SPHERERES),
00723 atomRep->get_data(AtomRep::SPHERERAD));
00724 break;
00725
00726 case AtomRep::DOTTED:
00727 draw_dotted_spheres(framepos,
00728 atomRep->get_data(AtomRep::SPHERERAD),
00729 (int)atomRep->get_data(AtomRep::SPHERERES));
00730 place_picks(framepos);
00731 break;
00732
00733 case AtomRep::SOLVENT:
00734 draw_dot_surface(framepos,
00735 atomRep->get_data(AtomRep::SPHERERAD),
00736 (int)atomRep->get_data(AtomRep::SPHERERES),
00737 (int)atomRep->get_data(AtomRep::LINETHICKNESS) - 1);
00738 place_picks(framepos);
00739 break;
00740 default:
00741 msgErr << "Illegal atom representation in DrawMolecule." << sendmsg;
00742 }
00743 } else {
00744
00745 switch (atomRep->method()) {
00746 case AtomRep::VOLSLICE:
00747 draw_volslice((int)atomRep->get_data(AtomRep::SPHERERES),
00748 atomRep->get_data(AtomRep::SPHERERAD),
00749 (int)atomRep->get_data(AtomRep::LINETHICKNESS),
00750 (int)atomRep->get_data(AtomRep::BONDRES));
00751 break;
00752
00753 case AtomRep::ISOSURFACE:
00754 draw_isosurface((int)atomRep->get_data(AtomRep::SPHERERES),
00755 atomRep->get_data(AtomRep::SPHERERAD),
00756 (int)atomRep->get_data(AtomRep::LINETHICKNESS),
00757 (int)atomRep->get_data(AtomRep::BONDRES),
00758 (int)atomRep->get_data(AtomRep::ISOSTEPSIZE),
00759 (int)atomRep->get_data(AtomRep::ISOLINETHICKNESS));
00760 break;
00761
00762 case AtomRep::FIELDLINES:
00763 draw_volume_field_lines((int)atomRep->get_data(AtomRep::SPHERERES),
00764 atomRep->get_data(AtomRep::SPHERERAD),
00765 atomRep->get_data(AtomRep::BONDRAD),
00766 atomRep->get_data(AtomRep::BONDRES),
00767 atomRep->get_data(AtomRep::LINETHICKNESS));
00768 break;
00769 }
00770 }
00771 }
00772
00773
00774
00775 void DrawMolItem::place_picks(float *pos) {
00776 DispCmdPickPointArray cmdPickPointArray;
00777
00778
00779
00780 int selseglen = atomSel->lastsel-atomSel->firstsel+1;
00781 cmdPickPointArray.putdata(selseglen, atomSel->selected, atomSel->firstsel,
00782 &atomSel->on[atomSel->firstsel],
00783 pos + 3*atomSel->firstsel, cmdList);
00784 }
00785
00786
00788
00789 void DrawMolItem::do_color_changed(int ccat) {
00790
00791
00792 if ((ccat == scene->category_index("Display")) ||
00793 (ccat == scene->category_index("Axes"))) {
00794 needRegenerate |= COL_REGEN;
00795 }
00796
00797
00798 if (atomColor && atomColor->current_color_use(ccat)) {
00799 change_color(atomColor);
00800 }
00801 }
00802
00803 void DrawMolItem::do_color_rgb_changed(int color) {
00804 int ccat;
00805
00806
00807
00808 ccat = scene->category_index("Display");
00809 if ((color == scene->category_item_value(ccat, "Background")) ||
00810 (color == scene->category_item_value(ccat, "Foreground")))
00811 needRegenerate |= COL_REGEN;
00812
00813 ccat = scene->category_index("Axes");
00814 if ((color == scene->category_item_value(ccat, "X")) ||
00815 (color == scene->category_item_value(ccat, "Y")) ||
00816 (color == scene->category_item_value(ccat, "Z")) ||
00817 (color == scene->category_item_value(ccat, "Origin")) ||
00818 (color == scene->category_item_value(ccat, "Labels")))
00819 needRegenerate |= COL_REGEN;
00820
00821
00822 const int *colors = atomColor->color;
00823 for (int i=0; i<mol->nAtoms; i++) {
00824 if (colors[i] == color) {
00825 change_color(atomColor);
00826 break;
00827 }
00828 }
00829 }
00830
00831 void DrawMolItem::do_color_scale_changed() {
00832 if (atomColor->uses_colorscale()) {
00833 atomColor->find(mol);
00834 needRegenerate |= COL_REGEN;
00835 }
00836 }
00837
00839
00840
00841 int DrawMolItem::change_color(AtomColor *ac) {
00842 if (ac) {
00843 *atomColor = *ac;
00844 needRegenerate |= COL_REGEN;
00845 return TRUE;
00846 } else
00847 return FALSE;
00848 }
00849
00850
00851 int DrawMolItem::representation_index(void) {
00852 int totalreps = mol->components();
00853 for (int i=0; i < totalreps; i++)
00854 if (mol->component(i) == this)
00855 return i;
00856
00857 msgErr << "Unknown molecular representation found." << sendmsg;
00858 return 0;
00859 }
00860
00861
00862 void DrawMolItem::prepare() {
00863
00864
00865 if (!displayed()) return;
00866
00867
00868 if (atomColor->method() == AtomColor::THROB) {
00869 needRegenerate |= COL_REGEN;
00870 }
00871
00872
00873 if ((update_pbc || update_ts) && cmdList->pbc) {
00874 update_pbc_transformations();
00875 update_pbc = 0;
00876 need_matrix_recalc();
00877 }
00878
00879
00880 if (update_ss) {
00881 if (atomRep->method() == AtomRep::STRUCTURE ||
00882 atomRep->method() == AtomRep::NEWCARTOON)
00883 needRegenerate |= MOL_REGEN;
00884
00885 if (atomColor->method() == AtomColor::STRUCTURE)
00886 needRegenerate |= COL_REGEN;
00887
00888 update_ss = 0;
00889 }
00890
00891
00892 if (update_ts) {
00893
00894
00895 if (!strcmp(framesel, "now")) {
00896 needRegenerate |= MOL_REGEN;
00897
00898
00899
00900
00901 switch (atomColor->method()) {
00902 case AtomColor::USER:
00903 case AtomColor::USER2:
00904 case AtomColor::USER3:
00905 case AtomColor::USER4:
00906 case AtomColor::PHYSICALTIME:
00907 case AtomColor::TIMESTEP:
00908 case AtomColor::VELOCITY:
00909 needRegenerate |= COL_REGEN;
00910 break;
00911 }
00912 }
00913
00914 update_ts = 0;
00915 }
00916
00917
00918 if (update_traj) {
00919
00920
00921 if (strcmp(framesel, "now")) {
00922
00923 Molecule *m = (Molecule *)mol;
00924 if (!m->file_in_progress()) {
00925 needRegenerate |= MOL_REGEN;
00926 update_traj = 0;
00927 }
00928 }
00929 }
00930
00931 create_cmdlist();
00932 }
00933
00934 void DrawMolItem::update_pbc_transformations() {
00935 const Timestep *ts = mol->current();
00936 if (!ts) return;
00937
00938 cmdList->transX.identity();
00939 cmdList->transY.identity();
00940 cmdList->transZ.identity();
00941 ts->get_transforms(cmdList->transX, cmdList->transY, cmdList->transZ);
00942 cmdList->transXinv = cmdList->transX;
00943 cmdList->transYinv = cmdList->transY;
00944 cmdList->transZinv = cmdList->transZ;
00945 cmdList->transXinv.inverse();
00946 cmdList->transYinv.inverse();
00947 cmdList->transZinv.inverse();
00948 }
00949
00950
00951
00952 int DrawMolItem::change_rep(AtomRep *ar) {
00953 if (!ar) return FALSE;
00954
00955 #ifdef VMDMSMS
00956
00957 if (atomRep->method() == AtomRep::MSMS && ar->method() != AtomRep::MSMS)
00958 msms.clear();
00959 #endif
00960
00961 #ifdef VMDSURF
00962
00963 if (atomRep->method() == AtomRep::SURF && ar->method() != AtomRep::SURF)
00964 surf.clear();
00965 #endif
00966
00967
00968 if (atomRep->method() == AtomRep::ORBITAL && ar->method() != AtomRep::ORBITAL) {
00969 waveftype = -1;
00970 wavefspin = -1;
00971 wavefexcitation = -1;
00972 gridorbid=-1;
00973 orbgridspacing = -1.0f;
00974 delete orbvol;
00975 orbvol=NULL;
00976 }
00977
00978
00979
00980
00981 if ((atomRep->method() == AtomRep::TUBE ||
00982 atomRep->method() == AtomRep::STRUCTURE) &&
00983 (ar->method() != AtomRep::TUBE &&
00984 ar->method() != AtomRep::STRUCTURE)) {
00985 if (tubearray) {
00986 for (int i=0; i<tubearray->num(); i++)
00987 delete (*tubearray)[i];
00988 delete tubearray;
00989 tubearray = NULL;
00990 }
00991 }
00992
00993 *atomRep = *ar;
00994 needRegenerate |= REP_REGEN;
00995 return TRUE;
00996 }
00997
00998
00999
01000 int DrawMolItem::change_sel(const char *cmdStr) {
01001 if (!cmdStr) return TRUE;
01002 if (atomSel->change(cmdStr, mol) == AtomSel::NO_PARSE) return FALSE;
01003 mol->notify();
01004
01005
01006 needRegenerate |= SEL_REGEN;
01007 return TRUE;
01008 }
01009
01010
01011 void DrawMolItem::force_recalc(int r) {
01012 needRegenerate |= r;
01013 }
01014
01015
01016 int DrawMolItem::atom_displayed(int n) {
01017 return (atomSel != NULL && mol != NULL &&
01018 n >= 0 && n < mol->nAtoms && atomSel->on[n]);
01019 }
01020
01022 void DrawMolItem::draw_lines(float *framepos, int thickness, float cutoff) {
01023 update_lookups(atomColor, atomSel, colorlookups);
01024 int *nbonds = NULL;
01025 int *bondlists = NULL;
01026 if (cutoff > 0) {
01027 nbonds = new int[mol->nAtoms];
01028 memset(nbonds, 0, mol->nAtoms*sizeof(int));
01029 bondlists = new int[MAXATOMBONDS * mol->nAtoms];
01030 GridSearchPair *pairlist = vmd_gridsearch1(framepos, mol->nAtoms, atomSel->on,
01031 cutoff, 0, mol->nAtoms * 27);
01032 GridSearchPair *p, *tmp;
01033 for (p=pairlist; p != NULL; p=tmp) {
01034 MolAtom *atom1 = mol->atom(p->ind1);
01035 MolAtom *atom2 = mol->atom(p->ind2);
01036
01037
01038
01039 if ((atom1->altlocindex != atom2->altlocindex) &&
01040 ((mol->altlocNames.name(atom1->altlocindex)[0] != '\0') &&
01041 (mol->altlocNames.name(atom2->altlocindex)[0] != '\0'))) {
01042 tmp = p->next;
01043 free(p);
01044 continue;
01045 }
01046
01047
01048 if (atom1->atomType == ATOMHYDROGEN &&
01049 atom2->atomType == ATOMHYDROGEN) {
01050 tmp = p->next;
01051 free(p);
01052 continue;
01053 }
01054 bondlists[p->ind1 * MAXATOMBONDS + nbonds[p->ind1]] = p->ind2;
01055 bondlists[p->ind2 * MAXATOMBONDS + nbonds[p->ind2]] = p->ind1;
01056 nbonds[p->ind1]++;
01057 nbonds[p->ind2]++;
01058 tmp = p->next;
01059 free(p);
01060 continue;
01061 }
01062 }
01063
01064 sprintf(commentBuffer, "MoleculeID: %d ReprID: %d Beginning Lines",
01065 mol->id(), repNumber);
01066 cmdCommentX.putdata(commentBuffer, cmdList);
01067
01068
01069 append(DMATERIALOFF);
01070 cmdLineType.putdata(SOLIDLINE, cmdList);
01071 cmdLineWidth.putdata(thickness, cmdList);
01072
01073 for (int i=0; i<MAXCOLORS; i++) {
01074 const ColorLookup &cl = colorlookups[i];
01075
01076 if (cl.num == 0) continue;
01077
01078 cmdColorIndex.putdata(i, cmdList);
01079
01080 ResizeArray<float> verts;
01081
01082 for (int j=0; j<cl.num; j++) {
01083 const int id = cl.idlist[j];
01084 float *fp1 = framepos + 3*id;
01085 const MolAtom *a1 = mol->atom(id);
01086 int bondsdrawn = 0;
01087
01088
01089
01090
01091
01092
01093
01094 int n = cutoff > 0 ? nbonds[id] : a1->bonds;
01095 for (int k=0; k < n; k++) {
01096 int a2n = cutoff > 0 ? bondlists[MAXATOMBONDS*id + k] : a1->bondTo[k];
01097 if (atomSel->on[a2n]) {
01098 float *fp2 = framepos + 3*a2n;
01099 if (atomColor->color[a2n] == i) {
01100
01101
01102 if (a2n > id) {
01103 verts.append(fp1[0]);
01104 verts.append(fp1[1]);
01105 verts.append(fp1[2]);
01106 verts.append(fp2[0]);
01107 verts.append(fp2[1]);
01108 verts.append(fp2[2]);
01109 }
01110 } else {
01111 float mid[3];
01112 mid[0] = 0.5f * (fp1[0] + fp2[0]);
01113 mid[1] = 0.5f * (fp1[1] + fp2[1]);
01114 mid[2] = 0.5f * (fp1[2] + fp2[2]);
01115 verts.append(fp1[0]);
01116 verts.append(fp1[1]);
01117 verts.append(fp1[2]);
01118 verts.append(mid[0]);
01119 verts.append(mid[1]);
01120 verts.append(mid[2]);
01121 }
01122 bondsdrawn++;
01123 }
01124 }
01125
01126
01127 if (!bondsdrawn) {
01128 DispCmdPoint cmdPoint;
01129 cmdPoint.putdata(fp1, cmdList);
01130 }
01131 }
01132
01133 if (verts.num()) {
01134 float *v = &(verts[0]);
01135 DispCmdLineArray cmdLineArray;
01136 cmdLineArray.putdata(v, verts.num()/6, cmdList);
01137 }
01138 }
01139 if (cutoff > 0) {
01140 delete [] nbonds;
01141 delete [] bondlists;
01142 }
01143 }
01144
01145
01146
01147
01148
01149 void DrawMolItem::draw_solid_spheres(float * framepos, int res,
01150 float radscale, float fixrad) {
01151 int i;
01152
01153
01154 sprintf(commentBuffer,"MoleculeID: %d ReprID: %d Beginning VDW",
01155 mol->id(), repNumber);
01156 cmdCommentX.putdata(commentBuffer, cmdList);
01157 append(DMATERIALON);
01158 cmdSphres.putdata(res, cmdList);
01159 cmdSphtype.putdata(SOLIDSPHERE, cmdList);
01160
01161 const char *modulatefield = NULL;
01162 const float *modulatedata = NULL;
01163 int modulateoffs = 0;
01164 int modulatemult = 1;
01165
01166 #if 1
01167
01168 modulatefield = getenv("VMDMODULATERADIUS");
01169 #endif
01170 if (modulatefield != NULL) {
01171 if (!strcmp(modulatefield, "user")) {
01172 modulatedata = mol->current()->user;
01173
01174 } else if (!strcmp(modulatefield, "user2")) {
01175 modulatedata = mol->current()->user2;
01176
01177 } else if (!strcmp(modulatefield, "user3")) {
01178 modulatedata = mol->current()->user3;
01179
01180 } else if (!strcmp(modulatefield, "user4")) {
01181 modulatedata = mol->current()->user4;
01182
01183 } else if (!strcmp(modulatefield, "vx")) {
01184 modulatedata = mol->current()->vel;
01185
01186 modulateoffs = 0; modulatemult = 3;
01187 } else if (!strcmp(modulatefield, "vy")) {
01188 modulatedata = mol->current()->vel;
01189
01190 modulateoffs = 1; modulatemult = 3;
01191 } else if (!strcmp(modulatefield, "vz")) {
01192 modulatedata = mol->current()->vel;
01193
01194 modulateoffs = 2; modulatemult = 3;
01195 } else {
01196 modulatedata = mol->extraflt.data(modulatefield);
01197 }
01198 }
01199
01200
01201 if ((radscale + fixrad) > 0) {
01202 int ind = 0;
01203 ResizeArray<float> centers;
01204 ResizeArray<float> radii;
01205 ResizeArray<float> colors;
01206 const float *radius = mol->radius();
01207
01208 ind = atomSel->firstsel * 3;
01209 for (i=atomSel->firstsel; i <= atomSel->lastsel; i++) {
01210
01211 if (atomSel->on[i]) {
01212 float *fp = framepos + ind;
01213 const float *cp;
01214
01215 centers.append(fp[0]);
01216 centers.append(fp[1]);
01217 centers.append(fp[2]);
01218
01219 float my_rad = 1.0f;
01220 if (modulatedata != NULL) {
01221 my_rad = modulatedata[i*modulatemult + modulateoffs];
01222 if (my_rad <= 0.0f)
01223 my_rad = 1.0f;
01224 }
01225 radii.append(radius[i]*radscale*my_rad + fixrad);
01226
01227 cp = scene->color_value(atomColor->color[i]);
01228 colors.append(cp[0]);
01229 colors.append(cp[1]);
01230 colors.append(cp[2]);
01231 }
01232 ind += 3;
01233 }
01234
01235 if (radii.num() > 0) {
01236 cmdSphereArray.putdata((float *) ¢ers[0],
01237 (float *) &radii[0],
01238 (float *) &colors[0],
01239 radii.num(),
01240 res,
01241 cmdList);
01242 }
01243 }
01244 }
01245
01246
01247
01248
01249 void DrawMolItem::draw_residue_beads(float * framepos, int sres, float radscale) {
01250 int i, resid, numres;
01251
01252
01253 sprintf(commentBuffer,"MoleculeID: %d ReprID: %d Beginning beads",
01254 mol->id(), repNumber);
01255 cmdCommentX.putdata(commentBuffer, cmdList);
01256 append(DMATERIALON);
01257 cmdSphres.putdata(sres, cmdList);
01258 cmdSphtype.putdata(SOLIDSPHERE, cmdList);
01259
01260
01261 ResizeArray<float> centers;
01262 ResizeArray<float> radii;
01263 ResizeArray<float> colors;
01264
01265
01266 numres = mol->residueList.num();
01267 for (resid=0; resid<numres; resid++) {
01268 float com[3] = {0.0, 0.0, 0.0};
01269 const ResizeArray<int> &atoms = mol->residueList[resid]->atoms;
01270 int numatoms = atoms.num();
01271 int oncount = 0;
01272 int pickindex=-1;
01273
01274
01275 for (i=0; i<numatoms; i++) {
01276 int idx = atoms[i];
01277 if (atomSel->on[idx]) {
01278 oncount++;
01279 vec_add(com, com, framepos + 3*idx);
01280 }
01281 }
01282
01283 if (oncount < 1)
01284 continue;
01285
01286 vec_scale(com, 1.0f / (float) oncount, com);
01287
01288
01289 int atomcolorindex=0;
01290 float boundradsq = 0.0f;
01291 #ifdef BEADELLIPSOID
01292 float avdist = 0.0f;
01293 float majoraxis[3] = {0.0, 0.0, 0.0};
01294 #endif
01295 for (i=0; i<numatoms; i++) {
01296 int idx = atoms[i];
01297 if (atomSel->on[idx]) {
01298 float tmpdist[3];
01299 atomcolorindex = idx;
01300 vec_sub(tmpdist, com, framepos + 3*idx);
01301 float distsq = dot_prod(tmpdist, tmpdist);
01302 if (distsq > boundradsq) {
01303 #ifdef BEADELLIPSOID
01304
01305
01306
01307
01308
01309 vec_copy(majoraxis, tmpdist);
01310 avdist += sqrtf(distsq);
01311 #endif
01312 boundradsq = distsq;
01313 }
01314 }
01315 }
01316
01317 #ifdef BEADELLIPSOID
01318 avdist /= (float) oncount;
01319 float cep1[3], cep2[3];
01320 vec_copy(cep1, majoraxis);
01321 vec_scale(cep2, -1, majoraxis);
01322 vec_add(cep1, cep1, com);
01323 vec_add(cep2, cep2, com);
01324
01325 cmdColorIndex.putdata(atomColor->color[atomcolorindex], cmdList);
01326
01327
01328
01329 cmdCylinder.putdata(cep1, cep2, avdist, 8, 0, cmdList);
01330 #endif
01331
01332 centers.append(com[0]);
01333 centers.append(com[1]);
01334 centers.append(com[2]);
01335
01336 radii.append(radscale * (sqrtf(boundradsq) + 1.0f));
01337
01338 const float *cp = scene->color_value(atomColor->color[atomcolorindex]);
01339 colors.append(cp[0]);
01340 colors.append(cp[1]);
01341 colors.append(cp[2]);
01342
01343
01344
01345 if (pickindex < 0)
01346 pickindex = mol->find_atom_in_residue("CA", resid);
01347
01348
01349 if (pickindex < 0)
01350 pickindex = mol->find_atom_in_residue("C3'", resid);
01351 if (pickindex < 0)
01352 pickindex = mol->find_atom_in_residue("C3*", resid);
01353 if (pickindex < 0)
01354 pickindex = mol->find_atom_in_residue("P", resid);
01355
01356
01357 if (pickindex < 0)
01358 pickindex = atoms[0];
01359
01360 pickPoint.putdata(com, pickindex, cmdList);
01361 }
01362
01363 #if !defined(BEADELLIPSOID)
01364 if (radii.num() > 0) {
01365 cmdSphereArray.putdata((float *) ¢ers[0],
01366 (float *) &radii[0],
01367 (float *) &colors[0],
01368 radii.num(),
01369 sres,
01370 cmdList);
01371 }
01372 #endif
01373 }
01374
01375
01376
01377
01378 void DrawMolItem::draw_dotted_spheres(float * framepos, float srad, int sres) {
01379 float radscale;
01380 int i;
01381 const float *radius = mol->radius();
01382
01383
01384 sprintf(commentBuffer,"MoleculeID: %d ReprID: %d Beginning Dotted VDW",
01385 mol->id(), repNumber);
01386 cmdCommentX.putdata(commentBuffer, cmdList);
01387 append(DMATERIALOFF);
01388 cmdSphres.putdata(sres, cmdList);
01389 cmdSphtype.putdata(POINTSPHERE, cmdList);
01390
01391
01392
01393
01394 radscale = srad;
01395 if (radscale > 0) {
01396 int lastcolor = -1;
01397 for (i=atomSel->firstsel; i <= atomSel->lastsel; i++) {
01398
01399 if (atomSel->on[i]) {
01400 if (lastcolor != atomColor->color[i]) {
01401 lastcolor = atomColor->color[i];
01402 cmdColorIndex.putdata(lastcolor, cmdList);
01403 }
01404
01405 cmdSphere.putdata(framepos+3*i, radius[i]*radscale,cmdList);
01406 }
01407 }
01408 }
01409 }
01410
01411
01412
01413 void DrawMolItem::draw_points(float *framepos, float pointsize) {
01414 sprintf(commentBuffer, "MoleculeID: %d ReprID: %d Beginning Points",
01415 mol->id(), repNumber);
01416 cmdCommentX.putdata(commentBuffer, cmdList);
01417 append(DMATERIALOFF);
01418
01419 if (atomSel->selected > 0) {
01420
01421
01422 int selseglen = atomSel->lastsel-atomSel->firstsel+1;
01423
01424
01425 cmdPointArray.putdata(framepos + 3*atomSel->firstsel,
01426 atomColor->color + atomSel->firstsel,
01427 scene,
01428 pointsize,
01429 selseglen,
01430 atomSel->on + atomSel->firstsel,
01431 atomSel->selected,
01432 cmdList);
01433 }
01434
01435 }
01436
01437
01438 void DrawMolItem::draw_cpk_licorice(float *framepos, int cpk, float brad, int bres, float srad, int sres, int linethickness, float cutoff) {
01439 MolAtom *a1;
01440 int i, j, a2n;
01441 float radscale, fixrad;
01442 int lastcolor = -1;
01443 int use_bonds = TRUE;
01444
01445 if (cpk) {
01446 brad *= 0.25f;
01447 radscale = srad * 0.25f;
01448 fixrad = 0.0;
01449 } else {
01450 radscale = 0.0;
01451 fixrad = brad;
01452
01453
01454 if (brad == 0) {
01455 draw_lines(framepos, linethickness, cutoff);
01456 return;
01457 }
01458 }
01459
01460 if (bres <= 2 || brad < 0.01) {
01461 use_bonds = FALSE;
01462 }
01463
01464 int *nbonds = NULL;
01465 int *bondlists = NULL;
01466 if (cutoff > 0) {
01467 nbonds = new int[mol->nAtoms];
01468 memset(nbonds, 0, mol->nAtoms*sizeof(int));
01469 bondlists = new int[MAXATOMBONDS * mol->nAtoms];
01470 GridSearchPair *pairlist = vmd_gridsearch1(framepos, mol->nAtoms, atomSel->on,
01471 cutoff, 0, mol->nAtoms * 27);
01472 GridSearchPair *p, *tmp;
01473 for (p=pairlist; p != NULL; p=tmp) {
01474 MolAtom *atom1 = mol->atom(p->ind1);
01475 MolAtom *atom2 = mol->atom(p->ind2);
01476
01477
01478
01479 if ((atom1->altlocindex != atom2->altlocindex) &&
01480 ((mol->altlocNames.name(atom1->altlocindex)[0] != '\0') &&
01481 (mol->altlocNames.name(atom2->altlocindex)[0] != '\0'))) {
01482 tmp = p->next;
01483 free(p);
01484 continue;
01485 }
01486
01487
01488 if (atom1->atomType == ATOMHYDROGEN &&
01489 atom2->atomType == ATOMHYDROGEN) {
01490 tmp = p->next;
01491 free(p);
01492 continue;
01493 }
01494 bondlists[p->ind1 * MAXATOMBONDS + nbonds[p->ind1]] = p->ind2;
01495 bondlists[p->ind2 * MAXATOMBONDS + nbonds[p->ind2]] = p->ind1;
01496 nbonds[p->ind1]++;
01497 nbonds[p->ind2]++;
01498 tmp = p->next;
01499 free(p);
01500 continue;
01501 }
01502 }
01503 sprintf (commentBuffer,"MoleculeID: %d ReprID: %d Beginning CPK",
01504 mol->id(), repNumber);
01505 cmdCommentX.putdata(commentBuffer, cmdList);
01506
01507 append(DMATERIALON);
01508
01509
01510 if ((radscale + fixrad) > 0) {
01511 draw_solid_spheres(framepos, sres, radscale, fixrad);
01512 }
01513
01514 if (use_bonds) {
01515
01516 for (i=atomSel->firstsel; i <= atomSel->lastsel; i++) {
01517
01518 if (atomSel->on[i]) {
01519 float mid[3], *fp1, *fp2;
01520 fp1 = framepos + 3*i;
01521 a1 = mol->atom(i);
01522
01523 if (lastcolor != atomColor->color[i]) {
01524 lastcolor = atomColor->color[i];
01525 cmdColorIndex.putdata(lastcolor, cmdList);
01526 }
01527
01528
01529 int n = cutoff > 0 ? nbonds[i] : a1->bonds;
01530 for (j=0; j < n; j++) {
01531 a2n = cutoff > 0 ? bondlists[MAXATOMBONDS*i + j] : a1->bondTo[j];
01532 if (atomSel->on[a2n]) {
01533 fp2 = framepos + 3*a2n;
01534
01535 mid[0] = 0.5f * (fp1[0] + fp2[0]);
01536 mid[1] = 0.5f * (fp1[1] + fp2[1]);
01537 mid[2] = 0.5f * (fp1[2] + fp2[2]);
01538
01539 cmdCylinder.putdata(fp1, mid, brad, bres, 0, cmdList);
01540 }
01541 }
01542 }
01543 }
01544 }
01545 if (cutoff > 0) {
01546 delete [] nbonds;
01547 delete [] bondlists;
01548 }
01549 }
01550
01551
01552
01553
01554
01555
01556
01557
01558 void DrawMolItem::draw_bonds(float *framepos, float brad, int bres, float cutoff) {
01559 MolAtom *a1, *a2;
01560 int g=0, h=0, i=0, j=0, k=0, l=0, m=0;
01561 int lastcolor = -1;
01562 int use_cyl;
01563 const float *bondorders = mol->bondorders();
01564
01565 sprintf(commentBuffer,"MoleculeID: %d ReprID: %d Beginning Bonds",
01566 mol->id(), repNumber);
01567 cmdCommentX.putdata(commentBuffer, cmdList);
01568
01569 if (bres <= 2 || brad < 0.01 ) {
01570
01571 use_cyl = FALSE;
01572 append(DMATERIALOFF);
01573 cmdLineType.putdata(SOLIDLINE, cmdList);
01574 cmdLineWidth.putdata(2, cmdList);
01575 } else {
01576 use_cyl = TRUE;
01577
01578
01579 append(DMATERIALON);
01580 }
01581
01582 for (i=atomSel->firstsel; i <= atomSel->lastsel; i++) {
01583
01584 if (atomSel->on[i]) {
01585 float *p2 = framepos + 3*i;
01586 a1 = mol->atom(i);
01587 float idouble[3], kdouble[3];
01588 float itriple[3], ktriple[3];
01589 const float *bondorderi = bondorders + (i * MAXATOMBONDS);
01590
01591 for (j=0; j<a1->bonds; j++) {
01592 k = a1->bondTo[j];
01593 if (k > i && atomSel->on[k]) {
01594 float *p1, p3[3], *p4, *p5;
01595 a2 = mol->atom(k);
01596 p4 = framepos + 3*k;
01597
01598
01599 p3[0] = 0.5f * (p2[0] + p4[0]);
01600 p3[1] = 0.5f * (p2[1] + p4[1]);
01601 p3[2] = 0.5f * (p2[2] + p4[2]);
01602
01603
01604
01605 p5 = NULL;
01606 for (l=a2->bonds-1; l>=0; l--) {
01607 m = a2->bondTo[l];
01608 if (m != i && atomSel->on[m])
01609 p5 = framepos + 3*m;
01610 break;
01611 }
01612
01613
01614 p1 = NULL;
01615 for (h=a1->bonds-1; h>=0; h--) {
01616 g = a1->bondTo[h];
01617 if (g != k && atomSel->on[g])
01618 p1 = framepos + 3*g;
01619 break;
01620 }
01621
01622
01623 float order = 0;
01624 if (bondorders != NULL) {
01625 order = bondorderi[j];
01626 if (order > 1) {
01627 int lv;
01628 for (lv=0; lv<3; lv++) {
01629 idouble[lv] = p2[lv] + 0.333f * (p4[lv] - p2[lv]);
01630 kdouble[lv] = p2[lv] + 0.666f * (p4[lv] - p2[lv]);
01631 itriple[lv] = p2[lv] + 0.450f * (p4[lv] - p2[lv]);
01632 ktriple[lv] = p2[lv] + 0.550f * (p4[lv] - p2[lv]);
01633 }
01634 }
01635 }
01636
01637
01638 if (lastcolor != atomColor->color[i]) {
01639 lastcolor = atomColor->color[i];
01640 cmdColorIndex.putdata(lastcolor, cmdList);
01641 }
01642 make_connection(p1, p2, p3, p4, brad, bres, use_cyl);
01643 if (order > 1) {
01644 make_connection(NULL, idouble, p3, kdouble, brad * 1.5f, bres, use_cyl);
01645 if (order > 2)
01646 make_connection(NULL, itriple, p3, ktriple, brad * 2.0f, bres, use_cyl);
01647 }
01648
01649 if (lastcolor != atomColor->color[k]) {
01650 lastcolor = atomColor->color[k];
01651 cmdColorIndex.putdata(lastcolor, cmdList);
01652 }
01653 make_connection(p2, p3, p4, p5, brad, bres, use_cyl);
01654 if (order > 1) {
01655 make_connection(idouble, p3, kdouble, NULL, brad * 1.5f, bres, use_cyl);
01656 if (order > 2)
01657 make_connection(itriple, p3, ktriple, NULL, brad * 2.0f, bres, use_cyl);
01658 }
01659 }
01660 }
01661 }
01662 }
01663 }
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675 void DrawMolItem::make_connection(float *prev, float *start, float *end,
01676 float *next, float rad, int res, int use_cyl)
01677 {
01678 if (!start || !end) {
01679 msgErr << "Trying to make an extended cylinder with NULL end point(s)"
01680 << sendmsg;
01681 return;
01682 }
01683
01684 if (!use_cyl) {
01685 cmdLine.putdata(start, end, cmdList);
01686 return;
01687 }
01688
01689 float new_start[3], new_end[3];
01690 float cthis[3];
01691 float cnext[3];
01692 float cprev[3];
01693 float length;
01694 float costheta;
01695
01696 vec_sub(cthis, end, start);
01697 vec_normalize(cthis);
01698
01699 length = 0.0f;
01700 if (prev != NULL) {
01701 vec_sub(cprev, start, prev);
01702 vec_normalize(cprev);
01703
01704
01705 costheta = dot_prod(cprev, cthis);
01706
01707
01708 if ((costheta > 0.0f) && (costheta < 0.9999f))
01709 length = rad * sqrtf((1.0f-costheta) / (1.0f+costheta));
01710 }
01711 new_start[0] = start[0] - length * cthis[0];
01712 new_start[1] = start[1] - length * cthis[1];
01713 new_start[2] = start[2] - length * cthis[2];
01714
01715 length = 0.0f;
01716 if (next != NULL) {
01717 vec_sub(cnext, next, end);
01718 vec_normalize(cnext);
01719
01720
01721 costheta = dot_prod(cthis,cnext);
01722
01723
01724 if ((costheta > 0.0f) && (costheta < 0.9999f))
01725 length = rad * sqrtf((1.0f-costheta) / (1.0f+costheta));
01726 }
01727 new_end[0] = end[0] + length * cthis[0];
01728 new_end[1] = end[1] + length * cthis[1];
01729 new_end[2] = end[2] + length * cthis[2];
01730
01731 cmdCylinder.putdata(new_start, new_end, rad, res, 0, cmdList);
01732 }
01733
01734
01735
01736
01737
01738 void DrawMolItem::draw_spline_curve(int num, float *coords, int *idx,
01739 int use_cyl, float b_rad, int b_res) {
01740 float q[4][3];
01741 float prev[2][3];
01742 float final[7][3];
01743 int last_loop = -10;
01744 int loop;
01745
01746 ResizeArray<float> pickpointcoords;
01747 ResizeArray<int> pickpointindices;
01748
01749 const char *modulatefield = NULL;
01750 const float *modulatedata = NULL;
01751 float *modulate = NULL;
01752
01753 #if 1
01754
01755 modulatefield = getenv("VMDMODULATERIBBON");
01756 #endif
01757 if (modulatefield != NULL) {
01758 if (!strcmp(modulatefield, "user")) {
01759 modulatedata = mol->current()->user;
01760
01761 } else {
01762 modulatedata = mol->extraflt.data(modulatefield);
01763 }
01764
01765
01766
01767
01768
01769
01770 modulate = (float *) calloc(1, mol->nResidues * sizeof(float));
01771 }
01772
01773
01774 for (loop=-1; loop<num; loop++) {
01775
01776
01777 if ((idx[loop ] >=0 && atomSel->on[idx[loop ]]) ||
01778 (idx[loop+1] >=0 && atomSel->on[idx[loop+1]])) {
01779 make_spline_Q_matrix(q, spline_basis, coords+(loop-1)*3);
01780
01781
01782
01783 make_spline_interpolation(final[0], 0.0f/6.0f, q);
01784 make_spline_interpolation(final[1], 1.0f/6.0f, q);
01785 make_spline_interpolation(final[2], 2.0f/6.0f, q);
01786 make_spline_interpolation(final[3], 3.0f/6.0f, q);
01787 make_spline_interpolation(final[4], 4.0f/6.0f, q);
01788 make_spline_interpolation(final[5], 5.0f/6.0f, q);
01789 make_spline_interpolation(final[6], 6.0f/6.0f, q);
01790
01791
01792
01793
01794
01795
01796
01797
01798 if (idx[loop] >= 0 &&
01799 (atomSel->on[idx[loop ]] == 1 ||
01800 (atomSel->on[idx[loop ]] == 3 && idx[loop+1] >= 0 &&
01801 atomSel->on[idx[loop+1]]))) {
01802
01803
01804
01805
01806 if (last_loop != loop - 1) {
01807 cmdColorIndex.putdata(atomColor->color[idx[loop]], cmdList);
01808 make_connection(NULL, final[0], final[1], final[2],
01809 b_rad, b_res, use_cyl);
01810 } else {
01811
01812
01813
01814 make_connection(prev[0], prev[1], final[0], final[1],
01815 b_rad, b_res, use_cyl);
01816 make_connection(prev[1], final[0], final[1], final[2],
01817 b_rad, b_res, use_cyl);
01818 }
01819 make_connection(final[0], final[1], final[2], final[3],
01820 b_rad, b_res, use_cyl);
01821 make_connection(final[1], final[2], final[3], final[4],
01822 b_rad, b_res, use_cyl);
01823
01824
01825 int pidx = 3 * loop;
01826 pickpointcoords.append(coords[pidx ]);
01827 pickpointcoords.append(coords[pidx + 1]);
01828 pickpointcoords.append(coords[pidx + 2]);
01829 pickpointindices.append(idx[loop]);
01830 }
01831
01832
01833 if (idx[loop+1] >= 0 &&
01834 (atomSel->on[idx[loop+1]] == 1 ||
01835 (atomSel->on[idx[loop+1]] == 2 && idx[loop] >= 0 &&
01836 atomSel->on[idx[loop]]))) {
01837 cmdColorIndex.putdata(atomColor->color[idx[loop+1]], cmdList);
01838 make_connection(final[2], final[3], final[4], final[5],
01839 b_rad, b_res, use_cyl);
01840 make_connection(final[3], final[4], final[5], final[6],
01841 b_rad, b_res, use_cyl);
01842 last_loop = loop;
01843 }
01844 vec_copy(prev[0], final[4]);
01845 vec_copy(prev[1], final[5]);
01846 }
01847 }
01848
01849
01850 if (pickpointindices.num() > 0) {
01851 DispCmdPickPointArray pickPointArray;
01852 pickPointArray.putdata(pickpointindices.num(), &pickpointindices[0],
01853 &pickpointcoords[0], cmdList);
01854 }
01855 }
01856
01857
01858 void DrawMolItem::generate_tubearray() {
01859 if (tubearray) {
01860 for (int i=0; i<tubearray->num(); i++) delete (*tubearray)[i];
01861 delete tubearray;
01862 }
01863 tubearray = new ResizeArray<TubeIndexList *>;
01864
01865 int frag;
01866
01867 for (frag = 0; frag < mol->pfragList.num(); frag++) {
01868 int num = mol->pfragList[frag]->num();
01869 if (num < 2) continue;
01870 TubeIndexList *idx = new TubeIndexList;
01871
01872
01873 idx->append(-1);
01874 idx->append(-1);
01875 for (int loop = 0; loop < num; loop++) {
01876 int res = (*mol->pfragList[frag])[loop];
01877
01878
01879 int atomnum = mol->find_atom_in_residue("CA", res);
01880 if (atomnum < 0) {
01881 atomnum = mol->atom_residue(res)->atoms[0];
01882 }
01883 idx->append(atomnum);
01884 }
01885 idx->append(-1);
01886 idx->append(-1);
01887 tubearray->append(idx);
01888 }
01889
01890
01891
01892 if (mol->pfragList.num() == 0) {
01893 int num = mol->nAtoms;
01894 int ca_num = mol->atomNames.typecode("CA");
01895 int last_resid = -10000;
01896 int resid;
01897 MolAtom *atm = NULL;
01898
01899 TubeIndexList *idx = NULL;
01900 for (int i=0; i<=num; i++) {
01901 if (i != num) {
01902 atm = mol->atom(i);
01903 resid = atm->resid;
01904 } else {
01905 resid = -1000;
01906 }
01907
01908 if (atm->nameindex == ca_num && resid == last_resid + 1) {
01909 if (idx == NULL) {
01910 msgErr << "Internal error in draw_tube for CA atoms: last_resid = "
01911 << last_resid << " but no first atom was added." << sendmsg;
01912 msgErr << "Tubes may be incomplete." << sendmsg;
01913 return;
01914 }
01915 idx->append(i);
01916 } else {
01917 if (idx) {
01918 idx->append(-1);
01919 idx->append(-1);
01920 tubearray->append(idx);
01921 idx = NULL;
01922 }
01923 if (atm->nameindex == ca_num && i != num) {
01924 idx = new TubeIndexList;
01925 idx->append(-1);
01926 idx->append(-1);
01927 idx->append(i);
01928 }
01929 }
01930 last_resid = resid;
01931 }
01932 }
01933
01934
01935
01936
01937 for (frag = 0; frag < mol->nfragList.num(); frag++) {
01938 int num = mol->nfragList[frag]->num();
01939 if (num < 2) continue;
01940 TubeIndexList *idx = new TubeIndexList;
01941
01942
01943 idx->append(-1);
01944 idx->append(-1);
01945 for (int loop = 0; loop < num; loop++) {
01946 int res = (*mol->nfragList[frag])[loop];
01947
01948
01949
01950 int atomnum = mol->find_atom_in_residue("P", res);
01951 if (atomnum < 0) {
01952 atomnum = mol->find_atom_in_residue("C5'", res);
01953 if (atomnum < 0) {
01954 atomnum = mol->find_atom_in_residue("C5*", res);
01955 if (atomnum < 0) {
01956 atomnum = mol->atom_residue(res)->atoms[0];
01957 }
01958 }
01959 }
01960 idx->append(atomnum);
01961 }
01962 idx->append(-1);
01963 idx->append(-1);
01964 tubearray->append(idx);
01965 }
01966
01967
01968
01969
01970
01971
01972 if (mol->nfragList.num() == 0) {
01973 int num = mol->nAtoms;
01974 int ca_num = mol->atomNames.typecode("P");
01975 int last_resid = -10000;
01976 int resid;
01977 MolAtom *atm = NULL;
01978
01979 TubeIndexList *idx = NULL;
01980 for (int i=0; i<=num; i++) {
01981 if (i != num) {
01982 atm = mol->atom(i);
01983 resid = atm->resid;
01984 } else {
01985 resid = -1000;
01986 }
01987
01988 if (atm->nameindex == ca_num && resid == last_resid + 1) {
01989 if (idx == NULL) {
01990 msgErr << "Internal error in draw_tube for P atoms: last_resid = "
01991 << last_resid << " but no first atom was added." << sendmsg;
01992 msgErr << "Tubes may be incomplete." << sendmsg;
01993 return;
01994 }
01995 idx->append(i);
01996 } else {
01997 if (idx) {
01998 idx->append(-1);
01999 idx->append(-1);
02000 tubearray->append(idx);
02001 idx = NULL;
02002 }
02003 if (atm->nameindex == ca_num && i != num) {
02004 idx = new TubeIndexList;
02005 idx->append(-1);
02006 idx->append(-1);
02007 idx->append(i);
02008 }
02009 }
02010 last_resid = resid;
02011 }
02012 }
02013 }
02014
02015
02016
02017
02018 void DrawMolItem::draw_tube(float *framepos, float b_rad, int b_res) {
02019
02020
02021
02022 if (!tubearray) {
02023 generate_tubearray();
02024 }
02025
02026 sprintf (commentBuffer,"MoleculeID: %d ReprID: %d Beginning Tube",
02027 mol->id(), repNumber);
02028 cmdCommentX.putdata(commentBuffer, cmdList);
02029
02030
02031 int use_cyl = FALSE;
02032 if (b_res <= 2 || b_rad < 0.01) {
02033 append(DMATERIALOFF);
02034 cmdLineType.putdata(SOLIDLINE, cmdList);
02035 cmdLineWidth.putdata(2, cmdList);
02036 } else {
02037 use_cyl = TRUE;
02038 append(DMATERIALON);
02039 }
02040
02041 for (int i=0; i<tubearray->num(); i++) {
02042
02043 TubeIndexList &indxlist = *(*tubearray)[i];
02044 int num = indxlist.num();
02045 float *coords = new float[3*num];
02046
02047
02048 int firstind = indxlist[2];
02049 int lastind = indxlist[num-3];
02050 memcpy(coords, framepos+3*firstind, 3*sizeof(float));
02051 memcpy(coords+3, framepos+3*firstind, 3*sizeof(float));
02052 for (int i=2; i<num-2; i++) {
02053 memcpy(coords+3*i, framepos+3*indxlist[i], 3*sizeof(float));
02054 }
02055 memcpy(coords+3*(num-2), framepos+3*lastind, 3*sizeof(float));
02056 memcpy(coords+3*(num-1), framepos+3*lastind, 3*sizeof(float));
02057 draw_spline_curve(num-4, coords+6, &(indxlist[0])+2, use_cyl, b_rad, b_res);
02058 delete [] coords;
02059 }
02060 }
02061
02062
02063
02064
02065
02066
02067
02068 void DrawMolItem::draw_hbonds(float *framepos, float maxangle, int thickness, float maxdist) {
02069 int i, k;
02070 float donortoH[3],Htoacceptor[3];
02071 float cosmaxangle2 = cosf(maxangle); cosmaxangle2 *= cosmaxangle2;
02072 ResizeArray<float> pickpointcoords;
02073 ResizeArray<int> pickpointindices;
02074
02075
02076
02077 if (maxdist <= 0.1 || atomSel->selected == 0) {
02078 return;
02079 }
02080
02081 int *onlist = (int *) calloc(1, mol->nAtoms * sizeof(int));
02082 for (i=atomSel->firstsel; i <= atomSel->lastsel; i++) {
02083 if (atomSel->on[i] && mol->atom(i)->atomType != ATOMHYDROGEN)
02084 onlist[i] = 1;
02085 }
02086
02087 sprintf(commentBuffer,"MoleculeID: %d ReprID: %d Beginning Hbonds",
02088 mol->id(), repNumber);
02089 cmdCommentX.putdata(commentBuffer, cmdList);
02090
02091
02092 append(DMATERIALOFF);
02093 cmdLineType.putdata(DASHEDLINE, cmdList);
02094 cmdLineWidth.putdata(thickness, cmdList);
02095
02096
02097
02098
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116 GridSearchPair *pairlist = vmd_gridsearch1(framepos, mol->nAtoms, onlist, maxdist, 0, mol->nAtoms * 27);
02117 GridSearchPair *p, *tmp;
02118 for (p=pairlist; p != NULL; p=tmp) {
02119 MolAtom *a1 = mol->atom(p->ind1);
02120 MolAtom *a2 = mol->atom(p->ind2);
02121
02122
02123 if (!a2->bonded(p->ind1)) {
02124 int b1 = a1->bonds;
02125 int b2 = a2->bonds;
02126 float *coor1 = framepos + 3*p->ind1;
02127 float *coor2 = framepos + 3*p->ind2;
02128
02129 for (k=0; k < b2; k++) {
02130 if (mol->atom(a2->bondTo[k])->atomType == ATOMHYDROGEN) {
02131 float *hydrogen = framepos + 3*a2->bondTo[k];
02132 vec_sub(donortoH,hydrogen,coor2);
02133 vec_sub(Htoacceptor,coor1,hydrogen);
02134 if (angle(donortoH, Htoacceptor) < maxangle ) {
02135 cmdColorIndex.putdata(atomColor->color[p->ind2], cmdList);
02136 cmdLine.putdata(coor1,hydrogen, cmdList);
02137
02138
02139 int pidx = 3 * a2->bondTo[k];
02140 pickpointcoords.append(framepos[pidx ]);
02141 pickpointcoords.append(framepos[pidx + 1]);
02142 pickpointcoords.append(framepos[pidx + 2]);
02143
02144 pidx = 3 * p->ind1;
02145 pickpointcoords.append(framepos[pidx ]);
02146 pickpointcoords.append(framepos[pidx + 1]);
02147 pickpointcoords.append(framepos[pidx + 2]);
02148
02149 pickpointindices.append(a2->bondTo[k]);
02150 pickpointindices.append(p->ind1);
02151 }
02152 }
02153 }
02154 for (k=0; k < b1; k++){
02155 if (mol->atom(a1->bondTo[k])->atomType == ATOMHYDROGEN) {
02156 float *hydrogen = framepos + 3*a1->bondTo[k];
02157 vec_sub(donortoH,hydrogen,coor1);
02158 vec_sub(Htoacceptor,coor2,hydrogen);
02159 if (angle(donortoH, Htoacceptor) < maxangle ) {
02160 cmdColorIndex.putdata(atomColor->color[p->ind1], cmdList);
02161 cmdLine.putdata(hydrogen,coor2, cmdList);
02162
02163
02164 int pidx = 3 * a1->bondTo[k];
02165 pickpointcoords.append(framepos[pidx ]);
02166 pickpointcoords.append(framepos[pidx + 1]);
02167 pickpointcoords.append(framepos[pidx + 2]);
02168
02169 pidx = 3 * p->ind2;
02170 pickpointcoords.append(framepos[pidx ]);
02171 pickpointcoords.append(framepos[pidx + 1]);
02172 pickpointcoords.append(framepos[pidx + 2]);
02173
02174 pickpointindices.append(a1->bondTo[k]);
02175 pickpointindices.append(p->ind2);
02176 }
02177 }
02178 }
02179 }
02180 tmp = p->next;
02181 free(p);
02182 }
02183 free(onlist);
02184
02185
02186 if (pickpointindices.num() > 0) {
02187 DispCmdPickPointArray pickPointArray;
02188 pickPointArray.putdata(pickpointindices.num(), &pickpointindices[0],
02189 &pickpointcoords[0], cmdList);
02190 }
02191 }
02192
02193
02194 void DrawMolItem::draw_dynamic_bonds(float *framepos, float brad, int bres, float maxdist) {
02195 int lastcolor = -1;
02196 ResizeArray<float> pickpointcoords;
02197 ResizeArray<int> pickpointindices;
02198
02199
02200
02201 if (maxdist <= 0.1 || atomSel->selected == 0) {
02202 return;
02203 }
02204
02205 sprintf(commentBuffer,"MoleculeID: %d ReprID: %d Beginning dynamic bonds",
02206 mol->id(), repNumber);
02207 cmdCommentX.putdata(commentBuffer, cmdList);
02208
02209
02210 append(DMATERIALON);
02211
02212
02213
02214
02215 GridSearchPair *pairlist = vmd_gridsearch1(framepos, mol->nAtoms, atomSel->on, maxdist, 0, mol->nAtoms * 27);
02216 GridSearchPair *p, *tmp;
02217 for (p=pairlist; p != NULL; p=tmp) {
02218 MolAtom *atom1 = mol->atom(p->ind1);
02219 MolAtom *atom2 = mol->atom(p->ind2);
02220
02221
02222
02223 if ((atom1->altlocindex != atom2->altlocindex) &&
02224 ((mol->altlocNames.name(atom1->altlocindex)[0] != '\0') &&
02225 (mol->altlocNames.name(atom2->altlocindex)[0] != '\0'))) {
02226 tmp = p->next;
02227 free(p);
02228 continue;
02229 }
02230
02231
02232
02233 if (!(atom1->atomType == ATOMHYDROGEN) ||
02234 !(atom2->atomType == ATOMHYDROGEN)) {
02235 float *coor1 = framepos + 3*p->ind1;
02236 float *coor2 = framepos + 3*p->ind2;
02237 float mid[3];
02238 #if 0
02239 if (cutoff < 0) {
02240 float d2 = distance2(coor1, coor2);
02241 float r1 = atom1->extra[ATOMRAD];
02242 float r2 = atom2->extra[ATOMRAD];
02243 float cut = 0.6f * (r1 + r2);
02244 if (d2 < cut*cut)
02245
02246 } else
02247 #endif
02248
02249
02250
02251
02252 mid[0] = 0.5f * (coor1[0] + coor2[0]);
02253 mid[1] = 0.5f * (coor1[1] + coor2[1]);
02254 mid[2] = 0.5f * (coor1[2] + coor2[2]);
02255
02256 if (lastcolor != atomColor->color[p->ind1]) {
02257 lastcolor = atomColor->color[p->ind1];
02258 cmdColorIndex.putdata(lastcolor, cmdList);
02259 }
02260 cmdCylinder.putdata(coor1, mid, brad, bres, 0, cmdList);
02261
02262 if (lastcolor != atomColor->color[p->ind2]) {
02263 lastcolor = atomColor->color[p->ind2];
02264 cmdColorIndex.putdata(lastcolor, cmdList);
02265 }
02266 cmdCylinder.putdata(mid, coor2, brad, bres, 0, cmdList);
02267
02268
02269 int pidx = 3 * p->ind1;
02270 pickpointcoords.append(framepos[pidx ]);
02271 pickpointcoords.append(framepos[pidx + 1]);
02272 pickpointcoords.append(framepos[pidx + 2]);
02273
02274 pidx = 3 * p->ind2;
02275 pickpointcoords.append(framepos[pidx ]);
02276 pickpointcoords.append(framepos[pidx + 1]);
02277 pickpointcoords.append(framepos[pidx + 2]);
02278
02279 pickpointindices.append(p->ind1);
02280 pickpointindices.append(p->ind2);
02281 }
02282
02283 tmp = p->next;
02284 free(p);
02285 }
02286
02287
02288 if (pickpointindices.num() > 0) {
02289 DispCmdPickPointArray pickPointArray;
02290 pickPointArray.putdata(pickpointindices.num(), &pickpointindices[0],
02291 &pickpointcoords[0], cmdList);
02292 }
02293 }
02294
02295
02296 #ifdef VMDPOLYHEDRA
02297
02298 #define PLYMAXNB 16
02299 void DrawMolItem::draw_polyhedra(float *framepos, float maxdist) {
02300 int i;
02301 int lastcolor = -1;
02302
02303
02304
02305 if (maxdist <= 0.1) {
02306 return;
02307 }
02308
02309
02310 int natoms = mol->nAtoms;
02311 int *onlist = new int[natoms];
02312 for (i=0; i<natoms; i++)
02313 onlist[i] = 1;
02314
02315
02316 int *nblist = (int *) malloc(natoms * sizeof(int) * PLYMAXNB);
02317 if (nblist == NULL)
02318 return;
02319 memset(nblist, 0, natoms * sizeof(int) * PLYMAXNB);
02320
02321 sprintf(commentBuffer,"MoleculeID: %d ReprID: %d Beginning polyhedra",
02322 mol->id(), repNumber);
02323 cmdCommentX.putdata(commentBuffer, cmdList);
02324
02325
02326 append(DMATERIALON);
02327
02328
02329
02330
02331 GridSearchPair *pairlist = vmd_gridsearch1(framepos, natoms, onlist, maxdist, 0, natoms * (PLYMAXNB - 1));
02332 delete [] onlist;
02333
02334 GridSearchPair *p, *tmp;
02335
02336 for (p=pairlist; p != NULL; p=tmp) {
02337 MolAtom *atom1 = mol->atom(p->ind1);
02338 MolAtom *atom2 = mol->atom(p->ind2);
02339
02340
02341 if (!(atomSel->on[p->ind1] || atomSel->on[p->ind2])) {
02342 tmp = p->next;
02343 free(p);
02344 continue;
02345 }
02346
02347
02348
02349 if ((atom1->altlocindex != atom2->altlocindex) &&
02350 ((mol->altlocNames.name(atom1->altlocindex)[0] != '\0') &&
02351 (mol->altlocNames.name(atom2->altlocindex)[0] != '\0'))) {
02352 tmp = p->next;
02353 free(p);
02354 continue;
02355 }
02356
02357
02358
02359 int idx1 = p->ind1 * PLYMAXNB;
02360 int idx2 = p->ind2 * PLYMAXNB;
02361 if (nblist[idx1] < (PLYMAXNB-1) && nblist[idx2] < (PLYMAXNB-1)) {
02362
02363 nblist[idx1]++;
02364 nblist[idx2]++;
02365
02366
02367 nblist[idx1 + nblist[idx1]] = p->ind2;
02368 nblist[idx2 + nblist[idx2]] = p->ind1;
02369 }
02370
02371 tmp = p->next;
02372 free(p);
02373 continue;
02374 }
02375
02376
02377
02378
02379
02380
02381
02382
02383
02384
02385 for (i=0; i < natoms; i++) {
02386 int idx = i*PLYMAXNB;
02387
02388
02389
02390
02391 if (!atomSel->on[i] || nblist[idx] < 4)
02392 continue;
02393
02394
02395 if (lastcolor != atomColor->color[i]) {
02396 lastcolor = atomColor->color[i];
02397 cmdColorIndex.putdata(lastcolor, cmdList);
02398 }
02399
02400 int index=nblist[idx];
02401 for (int i1=1; i1 <= index - 2; i1++)
02402 for (int i2=i1; i2 <= index - 1; i2++)
02403 for (int i3=i2; i3 <= index; i3++)
02404 cmdTriangle.putdata(framepos + 3*nblist[idx+i1],
02405 framepos + 3*nblist[idx+i2],
02406 framepos + 3*nblist[idx+i3], cmdList);
02407 }
02408
02409 free(nblist);
02410 }
02411 #endif
02412
02413
02414
02415 static void least_squares(int n, const float *x, float *a, float *b) {
02416 float sum = 0;
02417 int i;
02418 for (i=0; i<n; i++) {
02419 sum += x[i];
02420 }
02421 float d = (float(n)-1.0f) / 2.0f;
02422 float t, sum_t2 = 0.0f;
02423 *a = 0.0f;
02424 for (i=0; i<n; i++) {
02425 t = (i - d);
02426 sum_t2 += t*t;
02427 *a += t*x[i];
02428 }
02429 *a /= sum_t2;
02430 *b = (sum/float(n) - d*(*a));
02431 }
02432
02433
02434
02435
02436
02437 void DrawMolItem::draw_alpha_helix_cylinders(ResizeArray<float> &x,
02438 ResizeArray<float> &y, ResizeArray<float> &z, ResizeArray<int> &atom_on,
02439 int *color, float bond_rad, int bond_res,
02440 float *start_coord, float *end_coord)
02441 {
02442
02443 float a[3], b[3];
02444 ResizeArray<float> pickpointcoords;
02445 ResizeArray<int> pickpointindices;
02446
02447 int num = x.num();
02448 least_squares(num, &(x[0]), a+0, b+0);
02449 least_squares(num, &(y[0]), a+1, b+1);
02450 least_squares(num, &(z[0]), a+2, b+2);
02451
02452
02453 float start[3], end[3];
02454
02455 start[0] = a[0] * (-0.5f) + b[0];
02456 start[1] = a[1] * (-0.5f) + b[1];
02457 start[2] = a[2] * (-0.5f) + b[2];
02458 vec_copy(start_coord, start);
02459 for (int i=0; i<x.num(); i++) {
02460 end[0] = a[0] * (float(i)+0.5f) + b[0];
02461 end[1] = a[1] * (float(i)+0.5f) + b[1];
02462 end[2] = a[2] * (float(i)+0.5f) + b[2];
02463 if (atom_on[i] >= 0) {
02464
02465 pickpointcoords.append(x[i]);
02466 pickpointcoords.append(y[i]);
02467 pickpointcoords.append(z[i]);
02468 pickpointindices.append(atom_on[i]);
02469 cmdColorIndex.putdata(color[atom_on[i]], cmdList);
02470 int caps = 0;
02471 if (i == 0 || (i>0 && atom_on[i-1] < 0))
02472 caps |= CYLINDER_TRAILINGCAP;
02473 if (i == x.num() - 1 || (i<x.num()-1 && atom_on[i+1] < 0))
02474 caps |= CYLINDER_LEADINGCAP;
02475 if (bond_res <= 2 || bond_rad < 0.01) {
02476
02477 cmdLine.putdata(start, end, cmdList);
02478 } else {
02479
02480 cmdCylinder.putdata(start, end, bond_rad, bond_res, caps, cmdList);
02481 }
02482 }
02483 memcpy(start, end, 3*sizeof(float));
02484 }
02485 vec_copy(end_coord, start);
02486
02487
02488 if (pickpointindices.num() > 0) {
02489 DispCmdPickPointArray pickPointArray;
02490 pickPointArray.putdata(pickpointindices.num(), &pickpointindices[0],
02491 &pickpointcoords[0], cmdList);
02492 }
02493
02494
02495 x.clear();
02496 y.clear();
02497 z.clear();
02498 atom_on.clear();
02499 }
02500
02501 #define SCALEADD(vec, offset, byscale) { \
02502 vec[0] += (*(offset ))*byscale; \
02503 vec[1] += (*(offset+1))*byscale; \
02504 vec[2] += (*(offset+2))*byscale; \
02505 }
02506 #define SCALESUM(vec, term1, term2, byscale) { \
02507 vec[0] = (*(term1 )) + (*(term2 ))*byscale; \
02508 vec[1] = (*(term1+1)) + (*(term2+1))*byscale; \
02509 vec[2] = (*(term1+2)) + (*(term2+2))*byscale; \
02510 }
02511 #define BETASCALE (0.2f * ribbon_width)
02512
02513
02514
02515
02516 void DrawMolItem::draw_beta_sheet(ResizeArray<float> &x,
02517 ResizeArray<float> &y, ResizeArray<float> &z, ResizeArray<int> &atom_on,
02518 int *color, float ribbon_width, float *start_coord, float *end_coord)
02519 {
02520 ResizeArray<float> pickpointcoords;
02521 ResizeArray<int> pickpointindices;
02522
02523
02524
02525
02526
02527 int num = x.num();
02528 int i;
02529 float *centers = new float[3*(num+1)];
02530 for (i=1; i<num; i++) {
02531 centers[3*i+0] = (x[i-1]+x[i])/2;
02532 centers[3*i+1] = (y[i-1]+y[i])/2;
02533 centers[3*i+2] = (z[i-1]+z[i])/2;
02534 }
02535
02536 centers[0] = 2*centers[3] - centers[6];
02537 centers[1] = 2*centers[4] - centers[7];
02538 centers[2] = 2*centers[5] - centers[8];
02539
02540 centers[3*num+0] = 2*centers[3*num-3] - centers[3*num-6];
02541 centers[3*num+1] = 2*centers[3*num-2] - centers[3*num-5];
02542 centers[3*num+2] = 2*centers[3*num-1] - centers[3*num-4];
02543
02544
02545 float *norms = new float[3*(num+1)];
02546 float *perps = new float[3*(num+1)];
02547 float d[2][3];
02548 d[0][0] = x[1]-x[0]; d[0][1] = y[1]-y[0]; d[0][2] = z[1]-z[0];
02549 for (i=1; i<num-1; i++) {
02550 d[1][0] = x[i+1]-x[i];
02551 d[1][1] = y[i+1]-y[i];
02552 d[1][2] = z[i+1]-z[i];
02553 cross_prod(norms+3*i, d[0], d[1]);
02554 vec_normalize(norms+3*i);
02555 if (i%2) {
02556 norms[3*i+0] = -norms[3*i+0];
02557 norms[3*i+1] = -norms[3*i+1];
02558 norms[3*i+2] = -norms[3*i+2];
02559 }
02560 vec_copy(d[0], d[1]);
02561 }
02562
02563 vec_copy(norms, norms+3);
02564 vec_copy(norms+3*num-3, norms+3*num-6);
02565 vec_copy(norms+3*num , norms+3*num-6);
02566
02567
02568 for (i=0; i<num; i++) {
02569 vec_sub(d[0], centers+3*i, centers+3*i+3);
02570 cross_prod(perps+3*i, d[0], norms+3*i);
02571 vec_normalize(perps+3*i);
02572 }
02573 vec_copy(perps+3*num, perps+3*num-3);
02574
02575
02576
02577 float ul[2][3], ur[2][3], ll[2][3], lr[2][3];
02578 SCALESUM(ul[0], centers, norms, ribbon_width);
02579 vec_copy (ll[0], ul[0]);
02580 SCALEADD(ul[0], perps, BETASCALE);
02581 SCALEADD(ll[0], perps, -BETASCALE);
02582
02583 SCALESUM(ur[0] , centers, norms, -ribbon_width);
02584 vec_copy (lr[0], ur[0]);
02585 SCALEADD(ur[0], perps, BETASCALE);
02586 SCALEADD(lr[0], perps, -BETASCALE);
02587
02588
02589 vec_copy(start_coord, centers);
02590 vec_copy(end_coord, centers+3*num);
02591
02592 int prev_on = 0;
02593 float dot=0.0f;
02594 for (i=0; i<num-1; i++) {
02595 dot = dot_prod(perps+3*i, perps+3*i+3);
02596
02597 if (dot < 0) {
02598
02599 perps[3*i+3] = -perps[3*i+3];
02600 perps[3*i+4] = -perps[3*i+4];
02601 perps[3*i+5] = -perps[3*i+5];
02602 norms[3*i+3] = -norms[3*i+3];
02603 norms[3*i+4] = -norms[3*i+4];
02604 norms[3*i+5] = -norms[3*i+5];
02605 }
02606
02607
02608 SCALESUM(ul[1], centers+3*i+3, norms+3*i+3, ribbon_width);
02609 vec_copy (ll[1], ul[1]);
02610 SCALEADD(ul[1], perps+3*i+3, BETASCALE);
02611 SCALEADD(ll[1], perps+3*i+3, -BETASCALE);
02612
02613 SCALESUM(ur[1] , centers+3*i+3, norms+3*i+3, -ribbon_width);
02614 vec_copy (lr[1], ur[1]);
02615 SCALEADD(ur[1], perps+3*i+3, BETASCALE);
02616 SCALEADD(lr[1], perps+3*i+3, -BETASCALE);
02617
02618
02619
02620 if (atom_on[i] >= 0) {
02621
02622 pickpointcoords.append(x[i]);
02623 pickpointcoords.append(y[i]);
02624 pickpointcoords.append(z[i]);
02625 pickpointindices.append(atom_on[i]);
02626
02627 cmdColorIndex.putdata(color[atom_on[i]], cmdList);
02628
02629 if (ribbon_width != 0) {
02630
02631 if (i == 0 || dot > .9 || dot < -.9) {
02632
02633
02634 cmdTriangle.putdata(ur[0], ul[0], ul[1],
02635 perps+3*i, perps+3*i, perps+3*i+3, cmdList);
02636 cmdTriangle.putdata(ur[0], ul[1], ur[1],
02637 perps+3*i, perps+3*i+3, perps+3*i+3, cmdList);
02638 cmdTriangle.putdata(lr[0], ll[0], ll[1],
02639 perps+3*i, perps+3*i, perps+3*i+3, cmdList);
02640 cmdTriangle.putdata(lr[0], ll[1], lr[1],
02641 perps+3*i, perps+3*i+3, perps+3*i+3, cmdList);
02642
02643
02644 cmdTriangle.putdata(ul[0], ll[0], ll[1],
02645 norms+3*i, norms+3*i, norms+3*i+3, cmdList);
02646 cmdTriangle.putdata(ul[0], ll[1], ul[1],
02647 norms+3*i, norms+3*i+3, norms+3*i+3, cmdList);
02648 cmdTriangle.putdata(ur[0], lr[0], lr[1],
02649 norms+3*i, norms+3*i, norms+3*i+3, cmdList);
02650 cmdTriangle.putdata(ur[0], lr[1], ur[1],
02651 norms+3*i, norms+3*i+3, norms+3*i+3, cmdList);
02652 } else {
02653
02654
02655
02656
02657 float centers_q[4][3];
02658 make_spline_Q_matrix(centers_q, spline_basis, centers + 3*i-3);
02659
02660
02661 float perps_q[4][3];
02662 make_spline_Q_matrix(perps_q, spline_basis, perps + 3*i-3);
02663 float norms_q[4][3];
02664 make_spline_Q_matrix(norms_q, spline_basis, norms + 3*i-3);
02665
02666
02667 float new_center[3];
02668 float new_perp[3];
02669 float new_norm[3];
02670 make_spline_interpolation(new_center, 0.5, centers_q);
02671 make_spline_interpolation(new_perp , 0.5, perps_q);
02672 vec_normalize(new_perp);
02673 make_spline_interpolation(new_norm , 0.5, norms_q);
02674 vec_normalize(new_norm);
02675
02676
02677 float ul2[3], ur2[3], ll2[3], lr2[3];
02678 SCALESUM(ul2 , new_center, new_norm, ribbon_width);
02679 vec_copy (ll2, ul2);
02680 SCALEADD(ul2, new_perp, BETASCALE);
02681 SCALEADD(ll2, new_perp, -BETASCALE);
02682
02683 SCALESUM(ur2 , new_center, new_norm, -ribbon_width);
02684 vec_copy (lr2, ur2);
02685 SCALEADD(ur2, new_perp, BETASCALE);
02686 SCALEADD(lr2, new_perp, -BETASCALE);
02687
02688
02689 cmdTriangle.putdata(ur[0], ul[0], ul2,
02690 perps+3*i, perps+3*i, new_perp, cmdList);
02691 cmdTriangle.putdata(ur[0], ul2, ur2,
02692 perps+3*i, new_perp, new_perp, cmdList);
02693 cmdTriangle.putdata(lr[0], ll[0], ll2,
02694 perps+3*i, perps+3*i, new_perp, cmdList);
02695 cmdTriangle.putdata(lr[0], ll2, lr2,
02696 perps+3*i, new_perp, new_perp, cmdList);
02697
02698
02699 cmdTriangle.putdata(ul[0], ll[0], ll2,
02700 norms+3*i, norms+3*i, new_norm, cmdList);
02701 cmdTriangle.putdata(ul[0], ll2, ul2,
02702 norms+3*i, new_norm, new_norm, cmdList);
02703 cmdTriangle.putdata(ur[0], lr[0], lr2,
02704 norms+3*i, norms+3*i, new_norm, cmdList);
02705 cmdTriangle.putdata(ur[0], lr2, ur2,
02706 norms+3*i, new_norm, new_norm, cmdList);
02707
02708
02709 cmdTriangle.putdata(ur2, ul2, ul[1],
02710 new_perp, new_perp, perps+3*i+3, cmdList);
02711 cmdTriangle.putdata(ur2, ul[1], ur[1],
02712 new_perp, perps+3*i+3, perps+3*i+3, cmdList);
02713 cmdTriangle.putdata(lr2, ll2, ll[1],
02714 new_perp, new_perp, perps+3*i+3, cmdList);
02715 cmdTriangle.putdata(lr2, ll[1], lr[1],
02716 new_perp, perps+3*i+3, perps+3*i+3, cmdList);
02717
02718
02719 cmdTriangle.putdata(ul2, ll2, ll[1],
02720 new_norm, new_norm, norms+3*i+3, cmdList);
02721 cmdTriangle.putdata(ul2, ll[1], ul[1],
02722 new_norm, norms+3*i+3, norms+3*i+3, cmdList);
02723 cmdTriangle.putdata(ur2, lr2, lr[1],
02724 new_norm, new_norm, norms+3*i+3, cmdList);
02725 cmdTriangle.putdata(ur2, lr[1], ur[1],
02726 new_norm, norms+3*i+3, norms+3*i+3, cmdList);
02727 }
02728
02729 if (!prev_on) {
02730
02731 cmdTriangle.putdata(ul[0], ll[0], ur[0], cmdList);
02732 cmdTriangle.putdata(ll[0], lr[0], ur[0], cmdList);
02733 prev_on = 1;
02734 }
02735 } else {
02736 cmdLine.putdata(centers+3*i, centers+3*i+3, cmdList);
02737 }
02738 } else {
02739
02740 if (prev_on && ribbon_width != 0) {
02741 cmdTriangle.putdata(ul[0], ll[0], ur[0], cmdList);
02742 cmdTriangle.putdata(ll[0], lr[0], ur[0], cmdList);
02743 prev_on = 0;
02744 }
02745 }
02746
02747 vec_copy(ur[0], ur[1]);
02748 vec_copy(ul[0], ul[1]);
02749 vec_copy(lr[0], lr[1]);
02750 vec_copy(ll[0], ll[1]);
02751 }
02752
02753
02754 if (prev_on && ribbon_width != 0) {
02755 cmdTriangle.putdata(ul[0], ll[0], ur[0], cmdList);
02756 cmdTriangle.putdata(ll[0], lr[0], ur[0], cmdList);
02757 }
02758
02759
02760 if (dot < 0) {
02761 perps[3*i+0] = -perps[3*i+0];
02762 perps[3*i+1] = -perps[3*i+1];
02763 perps[3*i+2] = -perps[3*i+2];
02764 norms[3*i+0] = -norms[3*i+0];
02765 norms[3*i+1] = -norms[3*i+1];
02766 norms[3*i+2] = -norms[3*i+2];
02767 }
02768
02769
02770 if (atom_on[num-1] >= 0) {
02771
02772 pickpointcoords.append(x[num-1]);
02773 pickpointcoords.append(y[num-1]);
02774 pickpointcoords.append(z[num-1]);
02775 pickpointindices.append(atom_on[num-1]);
02776
02777
02778
02779 norms[3*num-3] *= 1.5;
02780 norms[3*num-2] *= 1.5;
02781 norms[3*num-1] *= 1.5;
02782
02783 SCALESUM(ul[0], centers+3*num-3, norms+3*num-3, ribbon_width);
02784 vec_copy (ll[0], ul[0]);
02785 SCALEADD(ul[0], perps+3*num-3, BETASCALE);
02786 SCALEADD(ll[0], perps+3*num-3, -BETASCALE);
02787
02788 SCALESUM(ur[0], centers+3*num-3, norms+3*num-3, -ribbon_width);
02789 vec_copy (lr[0], ur[0]);
02790 SCALEADD(ur[0], perps+3*num-3, BETASCALE);
02791 SCALEADD(lr[0], perps+3*num-3, -BETASCALE);
02792
02793
02794 vec_copy (ur[1], centers+3*num);
02795 vec_copy (lr[1], ur[1]);
02796 SCALEADD(ur[1], perps+3*num, BETASCALE);
02797 SCALEADD(lr[1], perps+3*num, -BETASCALE);
02798
02799
02800 cmdColorIndex.putdata(color[atom_on[num-1]], cmdList);
02801
02802 if (ribbon_width > 0) {
02803
02804 cmdTriangle.putdata(ul[0], ur[1], ur[0], cmdList);
02805
02806 cmdTriangle.putdata(ll[0], lr[0], lr[1], cmdList);
02807
02808 cmdTriangle.putdata(ul[0], ll[0], lr[1], cmdList);
02809 cmdTriangle.putdata(ul[0], lr[1], ur[1], cmdList);
02810 cmdTriangle.putdata(ur[0], lr[0], lr[1], cmdList);
02811 cmdTriangle.putdata(ur[0], lr[1], ur[1], cmdList);
02812
02813 cmdTriangle.putdata(ul[0], ll[0], ur[0], cmdList);
02814 cmdTriangle.putdata(ll[0], lr[0], ur[0], cmdList);
02815 } else {
02816 cmdLine.putdata(centers+3*num-3, centers+3*num, cmdList);
02817 }
02818 }
02819 delete [] perps;
02820 delete [] norms;
02821 delete [] centers;
02822
02823
02824 if (pickpointindices.num() > 0) {
02825 DispCmdPickPointArray pickPointArray;
02826 pickPointArray.putdata(pickpointindices.num(), &pickpointindices[0],
02827 &pickpointcoords[0], cmdList);
02828 }
02829
02830
02831 x.clear();
02832 y.clear();
02833 z.clear();
02834 atom_on.clear();
02835 }
02836
02837
02838 void DrawMolItem::draw_structure(float *framepos, float brad, int bres, int linethickness) {
02839 sprintf (commentBuffer,"MoleculeID: %d ReprID: %d Beginning Cartoon",
02840 mol->id(), repNumber);
02841 cmdCommentX.putdata(commentBuffer, cmdList);
02842
02843
02844 mol->need_secondary_structure(1);
02845
02846 int h_start, b_start;
02847 int atom=0;
02848 int frag, res;
02849
02850 ResizeArray<float> resx;
02851 ResizeArray<float> resy;
02852 ResizeArray<float> resz;
02853 ResizeArray<int> CA_num;
02854 ResizeArray<int> extra_resid;
02855
02856 ResizeArray<float> x;
02857 ResizeArray<float> y;
02858 ResizeArray<float> z;
02859 ResizeArray<int> atom_on;
02860
02861
02862
02863
02864
02865 if (bres <= 2 || brad < 0.01) {
02866 cmdLineType.putdata(SOLIDLINE, cmdList);
02867 cmdLineWidth.putdata(2, cmdList);
02868 append(DMATERIALOFF);
02869 } else {
02870 append(DMATERIALON);
02871 }
02872
02873 h_start = -1;
02874 for (frag=0; frag<mol->pfragList.num(); frag++) {
02875 int num = mol->pfragList[frag]->num();
02876 for (int resindex=0; resindex < num; resindex++) {
02877 res = (*mol->pfragList[frag])[resindex];
02878 const int ss = mol->residue(res)->sstruct;
02879 int residue_is_helix =
02880 (ss == SS_HELIX_ALPHA || ss == SS_HELIX_3_10 ||
02881 ss == SS_HELIX_PI);
02882
02883 if (residue_is_helix) {
02884 atom = mol->find_atom_in_residue("CA", res);
02885 if (atom >= 0) {
02886 if (h_start == -1) {
02887 h_start = atom;
02888 }
02889
02890 x.append(framepos[3*atom+0]);
02891 y.append(framepos[3*atom+1]);
02892 z.append(framepos[3*atom+2]);
02893
02894 if (atomSel->on[atom]) {
02895 atom_on.append(atom);
02896 } else {
02897 atom_on.append(-1);
02898 }
02899 } else {
02900 msgErr << "Missing a CA in a protein residue!!" << sendmsg;
02901 }
02902 }
02903
02904
02905
02906 if (!residue_is_helix || resindex == num-1) {
02907 if (x.num() <= 1) {
02908
02909 if (x.num() == 1) {
02910 extra_resid.append(atom);
02911 }
02912 x.clear();
02913 y.clear();
02914 z.clear();
02915 } else {
02916 float ends[2][3];
02917 CA_num.append(h_start);
02918 CA_num.append(atom);
02919 draw_alpha_helix_cylinders(x, y, z, atom_on, atomColor->color,
02920 brad, bres, ends[0], ends[1]);
02921
02922 resx.append(ends[0][0]);
02923 resy.append(ends[0][1]);
02924 resz.append(ends[0][2]);
02925 resx.append(ends[1][0]);
02926 resy.append(ends[1][1]);
02927 resz.append(ends[1][2]);
02928 }
02929
02930 h_start = -1;
02931 }
02932 }
02933 }
02934
02935
02936
02937
02938 if (linethickness == 0) {
02939 cmdLineType.putdata(SOLIDLINE, cmdList);
02940 cmdLineWidth.putdata(2, cmdList);
02941 append(DMATERIALOFF);
02942 } else {
02943 append(DMATERIALON);
02944 }
02945
02946 b_start = -1;
02947 for (frag=0; frag<mol->pfragList.num(); frag++) {
02948 int num = mol->pfragList[frag]->num();
02949 for (int resindex=0; resindex < num; resindex++) {
02950 int res = (*mol->pfragList[frag])[resindex];
02951 const int ss = mol->residue(res)->sstruct;
02952 int is_beta = (ss == SS_BETA || ss == SS_BRIDGE);
02953 if (is_beta) {
02954 atom = mol->find_atom_in_residue("CA", res);
02955 if (atom >= 0) {
02956 if (b_start == -1) {
02957 b_start = atom;
02958 }
02959 x.append(framepos[3*atom+0]);
02960 y.append(framepos[3*atom+1]);
02961 z.append(framepos[3*atom+2]);
02962 if (atomSel->on[atom]) {
02963 atom_on.append(atom);
02964 } else {
02965 atom_on.append(-1);
02966 }
02967 } else {
02968 msgErr << "Missing a CA in a protein residue!!" << sendmsg;
02969 }
02970 }
02971
02972
02973
02974 if (b_start != -1 && (!is_beta || resindex == num-1)) {
02975 if (x.num() <= 2) {
02976
02977
02978
02979 extra_resid.append(b_start);
02980 if (x.num() == 2) {
02981 extra_resid.append(atom);
02982 }
02983 x.clear();
02984 y.clear();
02985 z.clear();
02986 atom_on.clear();
02987 } else {
02988 float ends[2][3];
02989 CA_num.append(b_start);
02990 CA_num.append(atom);
02991 draw_beta_sheet(x, y, z, atom_on, atomColor->color,
02992 linethickness / 5.0f,
02993 ends[0], ends[1]);
02994 resx.append(ends[0][0]);
02995 resy.append(ends[0][1]);
02996 resz.append(ends[0][2]);
02997 resx.append(ends[1][0]);
02998 resy.append(ends[1][1]);
02999 resz.append(ends[1][2]);
03000 }
03001
03002 b_start = -1;
03003 }
03004 }
03005 }
03006
03007
03008
03009
03010
03011
03012
03013
03014
03015 {
03016
03017
03018 int nres, i;
03019
03020
03021 int *on = new int[mol->nAtoms];
03022 memset(on, 0, mol->nAtoms*sizeof(int));
03023
03024
03025 nres=mol->residueList.num();
03026 for (i=0; i<nres; i++) {
03027 const Residue *res = mol->residueList[i];
03028 if (res->residueType == RESPROTEIN) {
03029 const int ss = res->sstruct;
03030 if (ss == SS_TURN || ss == SS_COIL) {
03031 int numatoms = res->atoms.num();
03032 for (int j=0; j<numatoms; j++) {
03033 on[res->atoms[j]] = 1;
03034 }
03035 }
03036 }
03037 }
03038
03039
03040
03041 nres=extra_resid.num();
03042 for (i=0; i<nres; i++) {
03043 int res = mol->atom(extra_resid[i])->uniq_resid;
03044 Residue *r = mol->residue(res);
03045 int numatoms = r->atoms.num();
03046 for (int j=0; j<numatoms; j++) {
03047 on[r->atoms[j]] = 1;
03048 }
03049 }
03050
03051
03052
03053
03054 float tmp_coords[3];
03055 int atom;
03056 int numcaatoms = CA_num.num();
03057 for (i=0; i<numcaatoms; i++) {
03058 atom = 3*CA_num[i];
03059 vec_copy(tmp_coords, framepos+atom);
03060 framepos[atom+0] = resx[i];
03061 framepos[atom+1] = resy[i];
03062 framepos[atom+2] = resz[i];
03063 resx[i] = tmp_coords[0];
03064 resy[i] = tmp_coords[1];
03065 resz[i] = tmp_coords[2];
03066
03067 on[CA_num[i]] = 2+i%2;
03068
03069
03070 }
03071
03072
03073 for (i=0; i<mol->nAtoms; i++) {
03074 if (!atomSel->on[i]) {
03075 on[i] = 0;
03076 }
03077 }
03078 int *temp_on = atomSel->on;
03079 atomSel->on = on;
03080
03081
03082 draw_tube(framepos,
03083 brad / 7.0f,
03084 int(float(bres) * 2.0f/3.0f + 0.5f));
03085
03086
03087 atomSel->on = temp_on;
03088 for (i=0; i<numcaatoms; i++) {
03089 atom = 3*CA_num[i];
03090 framepos[atom+0] = resx[i];
03091 framepos[atom+1] = resy[i];
03092 framepos[atom+2] = resz[i];
03093 }
03094
03095 delete [] on;
03096 }
03097
03098 append(DMATERIALOFF);
03099 }
03100
03101 int DrawMolItem::pickable_on() {
03102 return displayed() && mol && mol->displayed();
03103 }
03104