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 "DrawMolecule.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 #include "WKFUtils.h"
00041
00042 #define RIBBON_ERR_NOTENOUGH 1
00043 #define RIBBON_ERR_PROTEIN_MESS 2
00044 #define RIBBON_ERR_MISSING_PHOSPHATE 4
00045 #define RIBBON_ERR_MISSING_O1P_O2P 8
00046 #define RIBBON_ERR_BADNUCLEIC 16
00047 #define RIBBON_ERR_BADPYRIMIDINE 32
00048 #define RIBBON_ERR_BADPURINE 64
00049
00050 #if 0
00051 #define RIBBON_ERR_NOTENOUGH_STR "Cannot draw a ribbon for a nucleic acid with only one element"
00052 #define RIBBON_ERR_PROTEIN_MESS_STR "Someone's been messing around with the definition of a protein!\nThings are going to look messy"
00053 #define RIBBON_ERR_MISSING_PHOSPHATE_STR "Cannot find first phosphate of a nucleic acid, so it won't be drawn"
00054 #define RIBBON_ERR_MISSING_O1P_O2P_STR "Cannot find both O1P and O2P of a nucleic acid, so it won't be drawn"
00055 #define RIBBON_ERR_BADNUCLEIC_STR "Someone has redefined the nucleic acid atom names!"
00056 #define RIBBON_ERR_BADPYRIMIDINE_STR "Tried to draw a nucleic acid residue I thought was a pyrimidine, but it doesn't have the right atom names."
00057 #define RIBBON_ERR_BADPURINE_STR "Tried to draw a nucleic acid residue I thought was a purine, but it doesn't have the right atom names."
00058 #endif
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 void DrawMolItem::draw_spline_ribbon(int num, float *coords,
00071 float *offset, int *idx, int use_cyl, float b_rad, int b_res) {
00072 ResizeArray<float> pickpointcoords;
00073 ResizeArray<int> pickpointindices;
00074 float q[4][3];
00075
00076
00077
00078 float pts[2][9][3];
00079
00080
00081
00082 float norms[2][8][3];
00083
00084
00085
00086
00087
00088 float tri_norm[2][7][3];
00089
00090 int last_loop = -10;
00091 int loop, i, j;
00092 float *tmp_ptr = (float *) malloc(2L*(num+4L) * sizeof(float) * 3L);
00093 if (tmp_ptr == NULL) {
00094 msgErr << "Cannot make a ribbon; not enough memory!" << sendmsg;
00095 return;
00096 }
00097 float *edge[2];
00098
00099
00100
00101 edge[0] = tmp_ptr + 2*3L;
00102 memcpy(edge[0]-2*3L, coords-2*3L, (num+4L)*sizeof(float)*3L);
00103 edge[1] = edge[0] + (num+4)*3;
00104 memcpy(edge[1]-2*3L, coords-2*3L, (num+4L)*sizeof(float)*3L);
00105 for (j=-2*3; j<(num+2)*3L-1; j++) {
00106 edge[0][j] += offset[j];
00107 edge[1][j] -= offset[j];
00108 }
00109
00110
00111 for (loop=-1; loop<num; loop++) {
00112 int j;
00113
00114
00115 if ((idx[loop] >= 0 && atomSel->on[idx[loop]]) ||
00116 (idx[loop+1] >= 0 && atomSel->on[idx[loop+1]])) {
00117
00118
00119
00120
00121 for (i=0; i<=1; i++) {
00122 make_spline_Q_matrix(q, spline_basis, edge[i]+(loop-1)*3);
00123 make_spline_interpolation(pts[i][2], 0.0f/6.0f, q);
00124 make_spline_interpolation(pts[i][3], 1.0f/6.0f, q);
00125 make_spline_interpolation(pts[i][4], 2.0f/6.0f, q);
00126 make_spline_interpolation(pts[i][5], 3.0f/6.0f, q);
00127 make_spline_interpolation(pts[i][6], 4.0f/6.0f, q);
00128 make_spline_interpolation(pts[i][7], 5.0f/6.0f, q);
00129 make_spline_interpolation(pts[i][8], 6.0f/6.0f, q);
00130 }
00131
00132
00133 for (i=2; i<8; i++) {
00134 float diff1[3], diff2[3];
00135 vec_sub(diff1, pts[1][i+1], pts[1][i+0]);
00136 vec_sub(diff2, pts[1][i+1], pts[0][i+0]);
00137 cross_prod(norms[1][i], diff1, diff2);
00138 vec_sub(diff1, pts[0][i+1], pts[0][i+0]);
00139 cross_prod(norms[0][i], diff1, diff2);
00140 }
00141
00142
00143
00144 if (last_loop != loop-1) {
00145 vec_copy(norms[0][0], norms[0][2]);
00146 vec_copy(norms[1][0], norms[1][2]);
00147 vec_copy(norms[0][1], norms[0][2]);
00148 vec_copy(norms[1][1], norms[1][2]);
00149 }
00150
00151
00152
00153 for (j=0; j<=1; j++) {
00154 for (i=0; i<8-1; i++) {
00155 vec_add(tri_norm[j][i], norms[j][i+1],
00156 norms[1-j][i+1]);
00157 vec_add(tri_norm[j][i], tri_norm[j][i],
00158 norms[j][i]);
00159 }
00160 }
00161
00162
00163
00164
00165 for (j=0; j<=1; j++) {
00166 for (i=0; i<8-1; i++) {
00167 vec_normalize(tri_norm[j][i]);
00168 }
00169 }
00170
00171
00172 if (idx[loop] >= 0 &&
00173 atomSel->on[idx[loop]]) {
00174
00175 if (last_loop != loop - 1) {
00176
00177
00178 cmdColorIndex.putdata(atomColor->color[idx[loop]], cmdList);
00179 }
00180
00181
00182
00183
00184 if (use_cyl) {
00185
00186
00187
00188 if (last_loop != loop-1) {
00189 int ii;
00190 for (ii=0; ii<=1; ii++) {
00191 make_connection(NULL, pts[ii][2], pts[ii][3],
00192 pts[ii][4], b_rad, b_res, use_cyl);
00193 }
00194 } else {
00195 for (i=0; i<=1; i++) {
00196 make_connection(pts[i][0], pts[i][1], pts[i][2], pts[i][3],
00197 b_rad, b_res, use_cyl);
00198 make_connection(pts[i][1], pts[i][2], pts[i][3], pts[i][4],
00199 b_rad, b_res, use_cyl);
00200 }
00201 }
00202
00203
00204 for (i=0; i<=1; i++) {
00205 make_connection(pts[i][2], pts[i][3], pts[i][4], pts[i][5],
00206 b_rad, b_res, use_cyl);
00207 make_connection(pts[i][3], pts[i][4], pts[i][5], pts[i][6],
00208 b_rad, b_res, use_cyl);
00209 }
00210 }
00211
00212
00213
00214
00215
00216 for (i= (last_loop == loop-1 ? 1: 2); i<5; i++) {
00217 cmdTriangle.putdata(pts[1][1+i], pts[1][0+i], pts[0][0+i],
00218 tri_norm[1][0+i], tri_norm[1][-1+i],
00219 tri_norm[0][-1+i], cmdList);
00220 cmdTriangle.putdata(pts[0][1+i], pts[1][1+i], pts[0][0+i],
00221 tri_norm[0][0+i], tri_norm[1][0+i],
00222 tri_norm[0][-1+i], cmdList);
00223
00224
00225
00226
00227 int pidx = loop * 3;
00228 pickpointcoords.append3(&coords[pidx]);
00229 pickpointindices.append(idx[loop]);
00230 }
00231 }
00232
00233
00234 if (idx[loop+1] >= 0 && atomSel->on[idx[loop+1]]) {
00235
00236
00237
00238 cmdColorIndex.putdata(atomColor->color[idx[loop+1]], cmdList);
00239
00240
00241
00242
00243 if (use_cyl) {
00244 for (i=0; i<=1; i++) {
00245 make_connection(pts[i][4], pts[i][5], pts[i][6], pts[i][7],
00246 b_rad, b_res, use_cyl);
00247 make_connection(pts[i][5], pts[i][6], pts[i][7], pts[i][8],
00248 b_rad, b_res, use_cyl);
00249 }
00250 }
00251
00252
00253
00254 for (i= 5; i<8-1; i++) {
00255
00256
00257
00258
00259
00260
00261
00262
00263 cmdTriangle.putdata(pts[1][1+i], pts[1][0+i], pts[0][0+i],
00264 tri_norm[1][0+i], tri_norm[1][-1+i],
00265 tri_norm[0][-1+i], cmdList);
00266 cmdTriangle.putdata(pts[0][1+i], pts[1][1+i], pts[0][0+i],
00267 tri_norm[0][0+i], tri_norm[1][0+i],
00268 tri_norm[0][-1+i], cmdList);
00269 }
00270 last_loop = loop;
00271 }
00272
00273
00274 for (i=0; i<=1; i++) {
00275 vec_copy(pts[i][0], pts[i][6]);
00276 vec_copy(pts[i][1], pts[i][7]);
00277 vec_copy(norms[i][0], norms[i][6]);
00278 vec_copy(norms[i][1], norms[i][7]);
00279 }
00280 }
00281 }
00282
00283 free(tmp_ptr);
00284
00285
00286 if (pickpointindices.num() > 0) {
00287 DispCmdPickPointArray pickPointArray;
00288 pickPointArray.putdata(pickpointindices.num(), &pickpointindices[0],
00289 &pickpointcoords[0], cmdList);
00290 }
00291 }
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 void DrawMolItem::draw_ribbons(float *framepos, float brad, int bres, float thickness) {
00306 sprintf(commentBuffer,"Mol[%d] Rep[%d] Ribbons", mol->id(), repNumber);
00307 cmdCommentX.putdata(commentBuffer, cmdList);
00308
00309
00310 int use_cyl = TRUE;
00311 int rc = 0;
00312
00313 if (bres <= 2 || brad < 0.01f) {
00314 use_cyl = FALSE;
00315 }
00316
00317 append(DMATERIALON);
00318
00319 float ribbon_width = thickness;
00320 if (ribbon_width < 1.0)
00321 ribbon_width = 1.0;
00322 ribbon_width /= 7.0;
00323
00324 rc |= draw_protein_ribbons_old(framepos, bres, brad, ribbon_width, use_cyl);
00325 rc |= draw_nucleic_ribbons(framepos, bres, brad, ribbon_width, use_cyl, 0, 0);
00326 rc |= draw_base_sugar_rings(framepos, bres, brad, ribbon_width, use_cyl);
00327
00328
00329
00330 if (rc != 0) {
00331 if (emitstructwarning())
00332 msgErr << "Warning: ribbons code encountered an unusual structure, geometry may not look as expected." << sendmsg;
00333 }
00334 }
00335
00336
00337
00338
00339 int DrawMolItem::draw_protein_ribbons_old(float *framepos, int b_res, float b_rad,
00340 float ribbon_width, int use_cyl) {
00341 float *real_coords = NULL, *coords;
00342 float *real_perps = NULL, *perps;
00343 int *real_idx = NULL, *idx;
00344 float *capos, *last_capos;
00345 float *opos, *last_opos;
00346 int onum, canum, res, frag, num;
00347 int rc=0;
00348
00349
00350 float a[3], b[3], c[3], d[3], e[3], g[3];
00351
00352
00353
00354
00355 for (frag=0; frag<mol->pfragList.num(); frag++) {
00356 int loop;
00357
00358 num = mol->pfragList[frag]->num();
00359 if (num < 2) {
00360 rc |= RIBBON_ERR_NOTENOUGH;
00361 continue;
00362 }
00363
00364
00365 res = (*mol->pfragList[frag])[0];
00366 canum = mol->find_atom_in_residue("CA", res);
00367 onum = mol->find_atom_in_residue("O", res);
00368
00369 if (canum < 0 || onum < 0) {
00370 continue;
00371 }
00372
00373 if (real_coords) {
00374 free(real_coords);
00375 free(real_idx);
00376 free(real_perps);
00377 real_coords = NULL;
00378 real_idx = NULL;
00379 real_perps = NULL;
00380 }
00381
00382
00383
00384
00385 real_coords = (float *) malloc((num+4) * sizeof(float)*3);
00386 real_idx = (int *) malloc((num+4) * sizeof(int));
00387 real_perps = (float *) malloc((num+4) * sizeof(float)*3);
00388
00389 coords = real_coords + 2*3L;
00390 idx = real_idx + 2L;
00391 perps = real_perps + 2*3L;
00392
00393
00394 capos = framepos + 3L*canum;
00395 last_capos = capos;
00396 opos = framepos + 3L*onum;
00397 last_opos = opos;
00398
00399
00400 vec_copy(coords-6, capos);
00401 vec_copy(coords-3, capos);
00402 idx[-2] = idx[-1] = -1;
00403
00404
00405 e[0] = e[1] = e[2] = 0.0;
00406 vec_copy(g, e);
00407 for (loop=0; loop<num; loop++) {
00408 res = (*mol->pfragList[frag])[loop];
00409 canum = mol->find_atom_in_residue("CA", res);
00410 if (canum >= 0) {
00411 capos = framepos + 3L*canum;
00412 }
00413 onum = mol->find_atom_in_residue("O", res);
00414 if (onum < 0) {
00415 onum = mol->find_atom_in_residue("OT1", res);
00416 }
00417
00418 if (onum >= 0) {
00419 opos = framepos + 3L*onum;
00420 } else {
00421 rc |= RIBBON_ERR_PROTEIN_MESS;
00422 opos = last_opos;
00423 }
00424
00425 vec_copy(coords+loop*3, capos);
00426 idx[loop] = canum;
00427
00428
00429 vec_sub(a, capos, last_capos);
00430 vec_sub(b, last_opos, last_capos);
00431 cross_prod(c, a, b);
00432 cross_prod(d, c, a);
00433
00434 if (dot_prod(d, g) < 0) {
00435 vec_negate(b, d);
00436 } else {
00437 vec_copy(b, d);
00438 }
00439 vec_add(e, g, b);
00440 vec_normalize(e);
00441 vec_scale(&perps[3L*loop], ribbon_width, e);
00442 vec_copy(g, e);
00443 last_capos = capos;
00444 last_opos = opos;
00445 }
00446
00447
00448 vec_copy(coords+3L*num, capos);
00449 vec_copy(coords+3L*(num+1), capos);
00450 idx[num] = idx[num+1] = -1;
00451
00452
00453
00454 vec_copy(perps, perps+3);
00455
00456
00457 vec_copy(perps-3, perps);
00458 vec_copy(perps-6, perps);
00459 vec_copy(perps+3L*num, perps+3L*num-3);
00460 vec_copy(perps+3L*num+3, perps+3L*num);
00461
00462 draw_spline_ribbon(num, coords, perps, idx, use_cyl, b_rad, b_res);
00463
00464 if (real_coords) {
00465 free(real_coords);
00466 free(real_idx);
00467 free(real_perps);
00468 real_coords = NULL;
00469 real_idx = NULL;
00470 real_perps = NULL;
00471 }
00472 }
00473
00474 return rc;
00475 }
00476
00477
00478 int DrawMolItem::draw_protein_ribbons_new(float *framepos, int b_res, float b_rad,
00479 float ribbon_width, int use_cyl) {
00480 float *coords = NULL;
00481 float *perps = NULL;
00482 int *idx = NULL;
00483 float *capos, *last_capos, *opos, *last_opos;
00484 int onum, canum, frag, num, res;
00485 const char *modulatefield = NULL;
00486 const float *modulatedata = NULL;
00487 float *modulate = NULL;
00488 int rc=0;
00489
00490
00491 float a[3], b[3], c[3], d[3], e[3], g[3];
00492
00493
00494
00495
00496 int CAtypecode = mol->atomNames.typecode("CA");
00497 int Otypecode = mol->atomNames.typecode("O");
00498 int OT1typecode = mol->atomNames.typecode("OT1");
00499
00500 if (CAtypecode < 0 || ((Otypecode < 0) && (OT1typecode < 0))) {
00501 return rc;
00502 }
00503
00504
00505
00506 coords = (float *) malloc((mol->nResidues) * sizeof(float)*3);
00507 idx = (int *) malloc((mol->nResidues) * sizeof(int));
00508 perps = (float *) malloc((mol->nResidues) * sizeof(float)*3);
00509
00510 #if 1
00511
00512 modulatefield = getenv("VMDMODULATERIBBON");
00513 #endif
00514 if (modulatefield != NULL) {
00515 if (!strcmp(modulatefield, "user")) {
00516 modulatedata = mol->current()->user;
00517
00518 } else {
00519 modulatedata = mol->extraflt.data(modulatefield);
00520 }
00521
00522
00523
00524
00525
00526
00527 modulate = (float *) calloc(1, mol->nResidues * sizeof(float));
00528 }
00529
00530
00531
00532 int numpfrag = mol->pfragList.num();
00533 for (frag=0; frag<numpfrag; frag++) {
00534 int cyclic=mol->pfragCyclic[frag];
00535 num = mol->pfragList[frag]->num();
00536 if (num < 2) {
00537 rc |= RIBBON_ERR_NOTENOUGH;
00538 continue;
00539 }
00540
00541
00542 res = (*mol->pfragList[frag])[0];
00543 canum = mol->find_atom_in_residue(CAtypecode, res);
00544 onum = mol->find_atom_in_residue(Otypecode, res);
00545
00546 if (canum < 0 || onum < 0) {
00547 continue;
00548 }
00549
00550
00551 capos = framepos + 3L*canum;
00552 last_capos = capos;
00553 opos = framepos + 3L*onum;
00554 last_opos = opos;
00555
00556
00557 e[0] = e[1] = e[2] = g[0] = g[1] = g[2] = 0.0;
00558
00559
00560
00561 if (cyclic) {
00562 int lastres = (*mol->pfragList[frag])[num-1];
00563 int lastcanum = mol->find_atom_in_residue(CAtypecode, lastres);
00564 last_capos = framepos + 3L*lastcanum;
00565
00566 int lastonum = mol->find_atom_in_residue(Otypecode, lastres);
00567 if (lastonum < 0 && OT1typecode >= 0) {
00568 lastonum = mol->find_atom_in_residue(OT1typecode, lastres);
00569 }
00570 last_opos = framepos + 3L*lastonum;
00571
00572
00573 vec_sub(a, capos, last_capos);
00574 vec_sub(b, last_opos, last_capos);
00575 cross_prod(c, a, b);
00576 cross_prod(d, c, a);
00577
00578 if (dot_prod(d, g) < 0) {
00579 vec_negate(b, d);
00580 } else {
00581 vec_copy(b, d);
00582 }
00583 vec_add(e, g, b);
00584 vec_normalize(e);
00585 vec_copy(g, e);
00586 }
00587
00588 int loop;
00589 for (loop=0; loop<num; loop++) {
00590 res = (*mol->pfragList[frag])[loop];
00591
00592 canum = mol->find_atom_in_residue(CAtypecode, res);
00593 if (canum >= 0) {
00594 capos = framepos + 3L*canum;
00595 }
00596
00597 onum = mol->find_atom_in_residue(Otypecode, res);
00598 if (onum < 0 && OT1typecode >= 0) {
00599 onum = mol->find_atom_in_residue(OT1typecode, res);
00600 }
00601 if (onum >= 0) {
00602 opos = framepos + 3L*onum;
00603 } else {
00604 rc |= RIBBON_ERR_PROTEIN_MESS;
00605 opos = last_opos;
00606 }
00607
00608
00609 vec_copy(coords+loop*3L, capos);
00610
00611
00612 if (modulatedata != NULL)
00613 modulate[loop] = modulatedata[canum];
00614
00615 idx[loop] = canum;
00616
00617
00618 vec_sub(a, capos, last_capos);
00619 vec_sub(b, last_opos, last_capos);
00620 cross_prod(c, a, b);
00621 cross_prod(d, c, a);
00622
00623 if (dot_prod(d, g) < 0) {
00624 vec_negate(b, d);
00625 } else {
00626 vec_copy(b, d);
00627 }
00628 vec_add(e, g, b);
00629 vec_normalize(e);
00630 vec_copy(&perps[3L*loop], e);
00631 vec_copy(g, e);
00632 last_capos = capos;
00633 last_opos = opos;
00634 }
00635
00636 if (!cyclic) {
00637
00638
00639 vec_copy(perps, perps+3);
00640 }
00641
00642 if (modulate != NULL) {
00643
00644 float *widths = (float *) malloc(num * sizeof(float));
00645 float *heights = (float *) malloc(num * sizeof(float));
00646 float m_fac;
00647 int i;
00648 for (i=0; i<num; i++) {
00649 #if 1
00650
00651 m_fac = modulate[i];
00652 if (m_fac <= 0.0f)
00653 m_fac = 1.0f;
00654
00655
00656 widths[i] = 7.0f * ribbon_width * b_rad * m_fac;
00657 heights[i] = b_rad*m_fac;
00658 #else
00659
00660 widths[i] = 7.0f * ribbon_width * b_rad + m_fac;
00661 heights[i] = b_rad;
00662 #endif
00663 }
00664 draw_spline_new(num, coords, perps, idx, widths, heights, num, b_res, cyclic);
00665 free(widths);
00666 free(heights);
00667 } else {
00668
00669 float widths = 7.0f * ribbon_width * b_rad;
00670 float heights = b_rad;
00671 draw_spline_new(num, coords, perps, idx, &widths, &heights, 1, b_res, cyclic);
00672 }
00673 }
00674
00675 if (coords) {
00676 free(coords);
00677 free(idx);
00678 free(perps);
00679 }
00680
00681 if (modulate) {
00682 free(modulate);
00683 }
00684
00685 return rc;
00686 }
00687
00688
00689
00690 int DrawMolItem::draw_nucleic_ribbons(float *framepos, int b_res, float b_rad,
00691 float ribbon_width, int use_cyl, int use_new,
00692 int use_carb) {
00694 float *real_coords = NULL, *coords;
00695 float *real_perps = NULL, *perps;
00696 int *real_idx = NULL, *idx;
00697 float *ppos, *last_ppos;
00698 float opos[3], last_opos[3];
00699 int cpnum;
00700 int o1num, o2num;
00701 int frag, num;
00702 int rc=0;
00703
00704
00705 float a[3], b[3], c[3], d[3], e[3], g[3];
00706
00707
00708
00709
00710 for (frag=0; frag<mol->nfragList.num(); frag++) {
00711 int loop;
00712
00713 num = mol->nfragList[frag]->num();
00714 if (num < 2) {
00715 rc |= RIBBON_ERR_NOTENOUGH;
00716 continue;
00717 }
00718 if (real_coords) {
00719 free(real_coords);
00720 free(real_idx);
00721 free(real_perps);
00722 real_coords = NULL;
00723 real_idx = NULL;
00724 real_perps = NULL;
00725 }
00726 real_coords = (float *) malloc((num+4)*sizeof(float)*3);
00727 real_idx = (int *) malloc((num+4) * sizeof(int));
00728 real_perps = (float *) malloc((num+4) * sizeof(float)*3);
00729 coords = real_coords + 2*3L;
00730 idx = real_idx + 2L;
00731 perps = real_perps + 2*3L;
00732
00733
00734
00735 int res = (*mol->nfragList[frag])[0];
00736
00737
00738 if (use_carb) {
00739
00740 cpnum = mol->find_atom_in_residue("C3'", res);
00741 if (cpnum < 0)
00742 cpnum = mol->find_atom_in_residue("C3*", res);
00743
00744 if (cpnum < 0)
00745 cpnum = mol->find_atom_in_residue("P", res);
00746 } else {
00747
00748 cpnum = mol->find_atom_in_residue("P", res);
00749 }
00750
00751
00752 if (cpnum < 0) {
00753 cpnum = mol->find_atom_in_residue("H5T", res);
00754 }
00755 if (cpnum < 0) {
00756 cpnum = mol->find_atom_in_residue("H3T", res);
00757 }
00758
00759 if (cpnum < 0) {
00760 rc |= RIBBON_ERR_MISSING_PHOSPHATE;
00761 continue;
00762 }
00763
00764 o1num = mol->find_atom_in_residue("O1P", res);
00765 if (o1num < 0)
00766 o1num = mol->find_atom_in_residue("OP1", res);
00767
00768 o2num = mol->find_atom_in_residue("O2P", res);
00769 if (o2num < 0)
00770 o2num = mol->find_atom_in_residue("OP2", res);
00771
00772
00773 if (o1num < 0 || o2num < 0) {
00774 int nextres = (*mol->nfragList[frag])[1];
00775 o1num = mol->find_atom_in_residue("O1P", nextres);
00776 if (o1num < 0)
00777 o1num = mol->find_atom_in_residue("OP1", nextres);
00778
00779 o2num = mol->find_atom_in_residue("O2P", nextres);
00780 if (o2num < 0)
00781 o2num = mol->find_atom_in_residue("OP2", nextres);
00782
00783 if (o1num < 0 || o2num < 0) {
00784 rc |= RIBBON_ERR_MISSING_O1P_O2P;
00785 continue;
00786 }
00787 }
00788
00789 ppos = framepos + 3L*cpnum;
00790 vec_add(opos, framepos + 3L*o1num, framepos + 3L*o2num);
00791 vec_copy(last_opos, opos);
00792 last_ppos = ppos;
00793
00794 vec_copy(coords-6, ppos);
00795 vec_copy(coords-3, ppos);
00796 idx[-2] = idx[-1] = -1;
00797
00798
00799 e[0] = e[1] = e[2] = 0.0;
00800 vec_copy(g, e);
00801 int abortfrag=0;
00802 for (loop=0; (loop<num && abortfrag==0); loop++) {
00803 res = (*mol->nfragList[frag])[loop];
00804
00805
00806 if (use_carb) {
00807
00808 cpnum = mol->find_atom_in_residue("C3'", res);
00809 if (cpnum < 0)
00810 cpnum = mol->find_atom_in_residue("C3*", res);
00811
00812 if (cpnum < 0)
00813 cpnum = mol->find_atom_in_residue("P", res);
00814 } else {
00815
00816 cpnum = mol->find_atom_in_residue("P", res);
00817 }
00818
00819
00820 if (cpnum < 0) {
00821 cpnum = mol->find_atom_in_residue("H5T", res);
00822 }
00823 if (cpnum < 0) {
00824 cpnum = mol->find_atom_in_residue("H3T", res);
00825 }
00826
00827
00828 if (cpnum >= 0) {
00829 ppos = framepos + 3L*cpnum;
00830 idx[loop] = cpnum;
00831 } else {
00832 rc |= RIBBON_ERR_MISSING_PHOSPHATE;
00833 abortfrag = 1;
00834 break;
00835 }
00836
00837 o1num = mol->find_atom_in_residue("O1P", res);
00838 if (o1num < 0)
00839 o1num = mol->find_atom_in_residue("OP1", res);
00840
00841 o2num = mol->find_atom_in_residue("O2P", res);
00842 if (o2num < 0)
00843 o2num = mol->find_atom_in_residue("OP2", res);
00844
00845 if (o1num < 0 || o2num < 0) {
00846 rc |= RIBBON_ERR_PROTEIN_MESS;
00847 vec_copy(opos, last_opos);
00848 } else {
00849 float tmp[3];
00850 vec_sub(tmp, framepos + 3L*o1num, ppos);
00851 vec_sub(opos, framepos + 3L*o2num, ppos);
00852 vec_add(opos, tmp, opos);
00853 }
00854 vec_copy(coords+loop*3, ppos);
00855
00856
00857 vec_sub(a, ppos, last_ppos);
00858
00859
00860 vec_copy(c, opos);
00861 cross_prod(d, c, a);
00862
00863
00864 if (dot_prod(d, g) < 0) {
00865 vec_negate(b, d);
00866 } else {
00867 vec_copy(b, d);
00868 }
00869 vec_add(e, g, b);
00870 vec_normalize(e);
00871 vec_scale(&perps[3L*loop], ribbon_width, e);
00872 vec_copy(g, e);
00873 last_ppos = ppos;
00874 vec_copy(last_opos, opos);
00875 }
00876
00877
00878 if (abortfrag)
00879 continue;
00880
00881
00882 vec_copy(coords+3L*num, ppos);
00883 vec_copy(coords+3L*(num+1), ppos);
00884 idx[num] = idx[num+1] = -1;
00885
00886
00887
00888 vec_copy(perps, perps+3);
00889
00890
00891 vec_copy(perps-3, perps);
00892 vec_copy(perps-6, perps);
00893 vec_copy(perps+3L*num, perps+3L*num-3);
00894 vec_copy(perps+3L*num+3, perps+3L*num);
00895
00896
00897 if (use_new) {
00898 float widths = 7.0f * ribbon_width * b_rad;
00899 float heights = b_rad;
00900 draw_spline_new(num, coords, perps, idx, &widths, &heights, 1, b_res, 0);
00901 } else {
00902 draw_spline_ribbon(num, coords, perps, idx, use_cyl, b_rad, b_res);
00903 }
00904 }
00905
00906 if (real_coords) {
00907 free(real_coords);
00908 free(real_idx);
00909 free(real_perps);
00910 real_coords = NULL;
00911 real_idx = NULL;
00912 real_perps = NULL;
00913 }
00914
00915 return rc;
00916 }
00917
00918
00919
00920
00921 int DrawMolItem::draw_base_sugar_rings(float *framepos, int b_res, float b_rad,
00922 float ribbon_width, int use_cyl) {
00923 float *real_coords = NULL;
00924 int frag, num;
00925 int rc=0;
00926
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940 float *o4ppos=NULL, *c1ppos=NULL, *c2ppos=NULL;
00941 float *c3ppos=NULL, *c4ppos=NULL;
00942 int o4pnum, c1pnum, c2pnum, c3pnum, c4pnum;
00943 float *n1pos,*c2pos,*n3pos,*c4pos,*c5pos,*c6pos,*n7pos,*c8pos,*n9pos;
00944 int n1num,c2num,n3num,c4num,c5num,c6num,n7num,c8num,n9num;
00945 float rescentra[3], rescentrb[3];
00946 float midptc1pc4p[3];
00947
00948 for (frag=0; frag<mol->nfragList.num(); frag++) {
00949 int loop;
00950
00951 num = mol->nfragList[frag]->num();
00952 if (real_coords) {
00953 free(real_coords);
00954 real_coords = NULL;
00955 }
00956
00957
00958
00959 real_coords = (float *) malloc( 14L * num * sizeof(float)*3L);
00960
00961
00962 for (loop=0; loop<num; loop++) {
00963
00964 int res = (*mol->nfragList[frag])[loop];
00965
00966 c1pnum = mol->find_atom_in_residue("C1'", res);
00967 if (c1pnum < 0) {
00968 c1pnum = mol->find_atom_in_residue("C1*", res);
00969 if (c1pnum < 0) {
00970 rc |= RIBBON_ERR_BADNUCLEIC;
00971 continue;
00972 }
00973 }
00974 c1ppos = framepos + 3L*c1pnum;
00975
00976 if (atomSel->on[c1pnum]) {
00977 o4pnum = mol->find_atom_in_residue("O4'", res);
00978 if (o4pnum < 0) {
00979 o4pnum = mol->find_atom_in_residue("O4*", res);
00980 }
00981 c2pnum = mol->find_atom_in_residue("C2'", res);
00982 if (c2pnum < 0) {
00983 c2pnum = mol->find_atom_in_residue("C2*", res);
00984 }
00985 c3pnum = mol->find_atom_in_residue("C3'", res);
00986 if (c3pnum < 0) {
00987 c3pnum = mol->find_atom_in_residue("C3*", res);
00988 }
00989 c4pnum = mol->find_atom_in_residue("C4'", res);
00990 if (c4pnum < 0) {
00991 c4pnum = mol->find_atom_in_residue("C4*", res);
00992 }
00993
00994 if (o4pnum < 0 || c2pnum < 0 || c3pnum < 0 || c4pnum < 0) {
00995 rc |= RIBBON_ERR_BADNUCLEIC;
00996 continue;
00997 }
00998
00999 o4ppos = framepos + 3L*o4pnum;
01000 c2ppos = framepos + 3L*c2pnum;
01001 c3ppos = framepos + 3L*c3pnum;
01002 c4ppos = framepos + 3L*c4pnum;
01003
01004 midpoint(midptc1pc4p, c1ppos, c4ppos);
01005
01006
01007 cmdColorIndex.putdata(atomColor->color[c1pnum], cmdList);
01008
01009 cmdTriangle.putdata(c4ppos,c1ppos,o4ppos,cmdList);
01010 cmdTriangle.putdata(c3ppos,midptc1pc4p,c4ppos,cmdList);
01011 cmdTriangle.putdata(c2ppos,midptc1pc4p,c3ppos,cmdList);
01012 cmdTriangle.putdata(c1ppos,midptc1pc4p,c2ppos,cmdList);
01013 }
01014
01015
01016 rescentra[0]=rescentra[1]=rescentra[2]=0.0;
01017 rescentrb[0]=rescentrb[1]=rescentrb[2]=0.0;
01018
01019
01020 n9num = mol->find_atom_in_residue("N9", res);
01021 n1num = mol->find_atom_in_residue("N1", res);
01022
01023
01024 if ((n9num >= 0) && (atomSel->on[n9num])) {
01025 c8num = mol->find_atom_in_residue("C8", res);
01026 n7num = mol->find_atom_in_residue("N7", res);
01027 c6num = mol->find_atom_in_residue("C6", res);
01028 c5num = mol->find_atom_in_residue("C5", res);
01029 c4num = mol->find_atom_in_residue("C4", res);
01030 n3num = mol->find_atom_in_residue("N3", res);
01031 c2num = mol->find_atom_in_residue("C2", res);
01032 n1num = mol->find_atom_in_residue("N1", res);
01033
01034 if (c8num < 0 || n7num < 0 || c6num < 0 || c5num < 0 ||
01035 c4num < 0 || n3num < 0 || c2num < 0 || n1num < 0) {
01036 rc |= RIBBON_ERR_BADPYRIMIDINE;
01037 continue;
01038 }
01039
01040 n9pos = framepos + 3L*n9num;
01041 vec_add(rescentra,rescentra,n9pos);
01042 c8pos = framepos + 3L*c8num;
01043 vec_add(rescentra,rescentra,c8pos);
01044 n7pos = framepos + 3L*n7num;
01045 vec_add(rescentra,rescentra,n7pos);
01046
01047 c5pos = framepos + 3L*c5num;
01048 vec_add(rescentra,rescentra,c5pos);
01049 vec_add(rescentrb,rescentrb,c5pos);
01050 c4pos = framepos + 3L*c4num;
01051 vec_add(rescentra,rescentra,c5pos);
01052 vec_add(rescentrb,rescentrb,c5pos);
01053
01054 c6pos = framepos + 3L*c6num;
01055 vec_add(rescentrb,rescentrb,c6pos);
01056 n3pos = framepos + 3L*n3num;
01057 vec_add(rescentrb,rescentrb,n3pos);
01058 c2pos = framepos + 3L*c2num;
01059 vec_add(rescentrb,rescentrb,c2pos);
01060 n1pos = framepos + 3L*n1num;
01061 vec_add(rescentrb,rescentrb,n1pos);
01062
01063 rescentrb[0] = rescentrb[0]/6.0f;
01064 rescentrb[1] = rescentrb[1]/6.0f;
01065 rescentrb[2] = rescentrb[2]/6.0f;
01066
01067 rescentra[0] = rescentra[0]/5.0f;
01068 rescentra[1] = rescentra[1]/5.0f;
01069 rescentra[2] = rescentra[2]/5.0f;
01070
01071
01072 cmdCylinder.putdata(c1ppos, n9pos, b_rad, b_res, 0, cmdList);
01073
01074 cmdColorIndex.putdata(atomColor->color[n9num], cmdList);
01075
01076 cmdTriangle.putdata(n1pos,rescentrb,c2pos,cmdList);
01077 cmdTriangle.putdata(c2pos,rescentrb,n3pos,cmdList);
01078 cmdTriangle.putdata(n3pos,rescentrb,c4pos,cmdList);
01079 cmdTriangle.putdata(c4pos,rescentrb,c5pos,cmdList);
01080 cmdTriangle.putdata(c5pos,rescentrb,c6pos,cmdList);
01081 cmdTriangle.putdata(c6pos,rescentrb,n1pos,cmdList);
01082
01083 cmdTriangle.putdata(n9pos,rescentra,c8pos,cmdList);
01084 cmdTriangle.putdata(c8pos,rescentra,n7pos,cmdList);
01085 cmdTriangle.putdata(n7pos,rescentra,c5pos,cmdList);
01086 cmdTriangle.putdata(c5pos,rescentra,c4pos,cmdList);
01087 cmdTriangle.putdata(c5pos,rescentra,c4pos,cmdList);
01088 cmdTriangle.putdata(c4pos,rescentra,n9pos,cmdList);
01089 }
01090 else if (( n1num >= 0) && (atomSel->on[n1num])){
01091
01092 c6num = mol->find_atom_in_residue("C6", res);
01093 c5num = mol->find_atom_in_residue("C5", res);
01094 c4num = mol->find_atom_in_residue("C4", res);
01095 n3num = mol->find_atom_in_residue("N3", res);
01096 c2num = mol->find_atom_in_residue("C2", res);
01097
01098 if (c6num < 0 || c5num < 0 || c4num < 0 || n3num < 0 || c2num < 0) {
01099 rc |= RIBBON_ERR_BADPURINE;
01100 continue;
01101 }
01102
01103 c6pos = framepos + 3L*c6num;
01104 vec_add(rescentrb,rescentrb,c6pos);
01105 c5pos = framepos + 3L*c5num;
01106 vec_add(rescentrb,rescentrb,c5pos);
01107 c4pos = framepos + 3L*c4num;
01108 vec_add(rescentrb,rescentrb,c5pos);
01109 n3pos = framepos + 3L*n3num;
01110 vec_add(rescentrb,rescentrb,n3pos);
01111 c2pos = framepos + 3L*c2num;
01112 vec_add(rescentrb,rescentrb,c2pos);
01113 n1pos = framepos + 3L*n1num;
01114 vec_add(rescentrb,rescentrb,n1pos);
01115
01116 rescentrb[0] = rescentrb[0]/6.0f;
01117 rescentrb[1] = rescentrb[1]/6.0f;
01118 rescentrb[2] = rescentrb[2]/6.0f;
01119
01120
01121 cmdCylinder.putdata(c1ppos, n1pos, b_rad, b_res, 0, cmdList);
01122 cmdColorIndex.putdata(atomColor->color[n1num], cmdList);
01123
01124 cmdTriangle.putdata(n1pos,rescentrb,c2pos,cmdList);
01125 cmdTriangle.putdata(c2pos,rescentrb,n3pos,cmdList);
01126 cmdTriangle.putdata(n3pos,rescentrb,c4pos,cmdList);
01127 cmdTriangle.putdata(c4pos,rescentrb,c5pos,cmdList);
01128 cmdTriangle.putdata(c5pos,rescentrb,c6pos,cmdList);
01129 cmdTriangle.putdata(c6pos,rescentrb,n1pos,cmdList);
01130 }
01131 }
01132 }
01133
01134 return rc;
01135 }
01136
01137 int DrawMolItem::draw_nucleotide_cylinders(float *framepos, int b_res, float b_rad, float ribbon_width, int use_cyl) {
01138 int frag, num;
01139 int rc=0;
01140 int lastcolor = -1;
01141
01142 b_rad *= 1.5;
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161 int nuctypes[10];
01162 nuctypes[0] = mol->resNames.typecode((char *) "A");
01163 nuctypes[1] = mol->resNames.typecode((char *) "ADE");
01164 nuctypes[2] = mol->resNames.typecode((char *) "C");
01165 nuctypes[3] = mol->resNames.typecode((char *) "CYT");
01166 nuctypes[4] = mol->resNames.typecode((char *) "G");
01167 nuctypes[5] = mol->resNames.typecode((char *) "GUA");
01168 nuctypes[6] = mol->resNames.typecode((char *) "T");
01169 nuctypes[7] = mol->resNames.typecode((char *) "THY");
01170 nuctypes[8] = mol->resNames.typecode((char *) "U");
01171 nuctypes[9] = mol->resNames.typecode((char *) "URA");
01172
01173
01174
01175
01176
01177
01178
01179 int ambernuctypes[4L*2*3];
01180 const char *dnarnastr = "DR";
01181 const char *nucstr = "ACGTU";
01182 const char *nuctermstr = "35";
01183
01184 int amberind=0;
01185 int foundambertypes=0;
01186 for (int nucind=0; nucind<5; nucind++) {
01187 char resstr[32];
01188 const char nuc = nucstr[nucind];
01189 resstr[1] = nuc;
01190
01191 for (int dnarna=0; dnarna<=1; dnarna++) {
01192 char dr = dnarnastr[dnarna];
01193 resstr[0] = dr;
01194
01195 if (nucind == 3 && dnarna == 1)
01196 continue;
01197 if (nucind == 4 && dnarna == 0)
01198 continue;
01199
01200 for (int termind=0; termind<3; termind++) {
01201 if (termind < 2)
01202 resstr[2] = nuctermstr[termind];
01203 else
01204 resstr[2] = '\0';
01205 resstr[3] = '\0';
01206
01207 int resnameind = mol->resNames.typecode(resstr);
01208 ambernuctypes[amberind] = resnameind;
01209 if (resnameind >= 0) {
01210 foundambertypes++;
01211 }
01212 amberind++;
01213 }
01214 }
01215 }
01216
01217 ResizeArray<float> centers;
01218 ResizeArray<float> radii;
01219 ResizeArray<float> colors;
01220 ResizeArray<float> pickpointcoords;
01221 ResizeArray<int> pickpointindices;
01222
01223
01224 for (frag=0; frag<mol->nfragList.num(); frag++) {
01225 int loop;
01226
01227 num = mol->nfragList[frag]->num();
01228
01229
01230 for (loop=0; loop<num; loop++) {
01231 int istart = -1;
01232 int iend = -1;
01233 int res = (*mol->nfragList[frag])[loop];
01234 int myatom = mol->residueList[res]->atoms[0];
01235 int resnameindex = mol->atom(myatom)->resnameindex;
01236
01237 if (istart < 0)
01238 istart = mol->find_atom_in_residue("C3'", res);
01239 if (istart < 0)
01240 istart = mol->find_atom_in_residue("C3*", res);
01241 if (istart < 0)
01242 istart = mol->find_atom_in_residue("C1'", res);
01243 if (istart < 0)
01244 istart = mol->find_atom_in_residue("C1*", res);
01245
01246
01247 if (istart < 0)
01248 istart = mol->find_atom_in_residue("P", res);
01249
01250
01251 if (istart < 0)
01252 continue;
01253
01254
01255
01256
01257
01258 #if 0
01259
01260 if (!(atomSel->on[istart]))
01261 continue;
01262 #endif
01263
01264
01265
01266
01267 if (iend < 0) {
01268
01269 if (resnameindex == nuctypes[0] || resnameindex == nuctypes[1]) {
01270
01271 int n1num = mol->find_atom_in_residue("N1", res);
01272 if (n1num < 0 || !(atomSel->on[n1num]))
01273 continue;
01274 iend = n1num;
01275 } else if (resnameindex == nuctypes[2] || resnameindex == nuctypes[3]) {
01276
01277 int n3num = mol->find_atom_in_residue("N3", res);
01278 if (n3num < 0 || !(atomSel->on[n3num]))
01279 continue;
01280 iend = n3num;
01281 } else if (resnameindex == nuctypes[4] || resnameindex == nuctypes[5]) {
01282
01283 int n1num = mol->find_atom_in_residue("N1", res);
01284 if (n1num < 0 || !(atomSel->on[n1num]))
01285 continue;
01286 iend = n1num;
01287 } else if (resnameindex == nuctypes[6] || resnameindex == nuctypes[7] ||
01288 resnameindex == nuctypes[8] || resnameindex == nuctypes[9]) {
01289
01290 int o4num = mol->find_atom_in_residue("O4", res);
01291 if (o4num < 0 || !(atomSel->on[o4num]))
01292 continue;
01293 iend = o4num;
01294 }
01295 }
01296
01297
01298
01299
01300 if (iend < 0 && foundambertypes) {
01301
01302 if (resnameindex == ambernuctypes[0] ||
01303 resnameindex == ambernuctypes[1] ||
01304 resnameindex == ambernuctypes[2] ||
01305 resnameindex == ambernuctypes[3] ||
01306 resnameindex == ambernuctypes[4] ||
01307 resnameindex == ambernuctypes[5]) {
01308
01309 int n1num = mol->find_atom_in_residue("N1", res);
01310 if (n1num < 0 || !(atomSel->on[n1num]))
01311 continue;
01312 iend = n1num;
01313 } else if (resnameindex == ambernuctypes[6] ||
01314 resnameindex == ambernuctypes[7] ||
01315 resnameindex == ambernuctypes[8] ||
01316 resnameindex == ambernuctypes[9] ||
01317 resnameindex == ambernuctypes[10] ||
01318 resnameindex == ambernuctypes[11]) {
01319
01320 int n3num = mol->find_atom_in_residue("N3", res);
01321 if (n3num < 0 || !(atomSel->on[n3num]))
01322 continue;
01323 iend = n3num;
01324 } else if (resnameindex == ambernuctypes[12] ||
01325 resnameindex == ambernuctypes[13] ||
01326 resnameindex == ambernuctypes[14] ||
01327 resnameindex == ambernuctypes[15] ||
01328 resnameindex == ambernuctypes[16] ||
01329 resnameindex == ambernuctypes[17]) {
01330
01331 int n1num = mol->find_atom_in_residue("N1", res);
01332 if (n1num < 0 || !(atomSel->on[n1num]))
01333 continue;
01334 iend = n1num;
01335 } else if (resnameindex == ambernuctypes[18] ||
01336 resnameindex == ambernuctypes[19] ||
01337 resnameindex == ambernuctypes[20] ||
01338 resnameindex == ambernuctypes[21] ||
01339 resnameindex == ambernuctypes[22] ||
01340 resnameindex == ambernuctypes[23]) {
01341
01342 int o4num = mol->find_atom_in_residue("O4", res);
01343 if (o4num < 0 || !(atomSel->on[o4num]))
01344 continue;
01345 iend = o4num;
01346 }
01347 }
01348
01349
01350
01351
01352
01353
01354
01355 if (iend < 0) {
01356 int o4num = mol->find_atom_in_residue("O4", res);
01357 if (o4num < 0 || !(atomSel->on[o4num]))
01358 continue;
01359 iend = o4num;
01360 }
01361
01362
01363 int pidx = 3L * istart;
01364 pickpointcoords.append3(&framepos[pidx]);
01365
01366 pidx = 3L * iend;
01367 pickpointcoords.append3(&framepos[pidx]);
01368
01369 pickpointindices.append(istart);
01370 pickpointindices.append(iend);
01371
01372
01373 if (lastcolor != atomColor->color[istart]) {
01374 lastcolor = atomColor->color[istart];
01375 cmdColorIndex.putdata(lastcolor, cmdList);
01376 }
01377
01378
01379 float *cstart = framepos + 3L*istart;
01380 float *cend = framepos + 3L*iend;
01381
01382
01383 cmdCylinder.putdata(cstart, cend, b_rad, b_res, 0, cmdList);
01384
01385
01386 const float *cp = scene->color_value(lastcolor);
01387
01388 #if 0
01389
01390
01391
01392 if (!(atomSel->on[istart])) {
01393 centers.append3(&cstart[0]);
01394
01395 radii.append(b_rad);
01396
01397 colors.append3(&cp[0]);
01398 }
01399 #endif
01400
01401 centers.append3(&cend[0]);
01402 radii.append(b_rad);
01403 colors.append3(&cp[0]);
01404 }
01405 }
01406
01407
01408 if (radii.num() > 0) {
01409 cmdSphereArray.putdata((float *) ¢ers[0],
01410 (float *) &radii[0],
01411 (float *) &colors[0],
01412 radii.num(),
01413 b_res,
01414 cmdList);
01415 }
01416
01417
01418 if (pickpointindices.num() > 0) {
01419 DispCmdPickPointArray pickPointArray;
01420 pickPointArray.putdata(pickpointindices.num(), &pickpointindices[0],
01421 &pickpointcoords[0], cmdList);
01422 }
01423
01424 return rc;
01425 }
01426
01427
01428
01429 void DrawMolItem::draw_ribbons_new(float *framepos, float brad, int bres, int use_bspline, float thickness) {
01430 sprintf(commentBuffer,"Mol[%d] Rep[%d] NewRibbons", mol->id(), repNumber);
01431 cmdCommentX.putdata(commentBuffer, cmdList);
01432
01433
01434 int use_cyl = TRUE;
01435 int rc = 0;
01436
01437 if (bres <= 2 || brad < 0.01f) {
01438 use_cyl = FALSE;
01439 }
01440
01441 if (use_bspline) {
01442 create_Bspline_basis(spline_basis);
01443 }
01444
01445 append(DMATERIALON);
01446
01447 float ribbon_width = thickness;
01448 if (ribbon_width < 1.0)
01449 ribbon_width = 1.0;
01450 ribbon_width /= 7.0;
01451
01452 rc |= draw_protein_ribbons_new(framepos, bres, brad, ribbon_width, use_cyl);
01453 rc |= draw_nucleic_ribbons(framepos, bres, brad, ribbon_width, use_cyl, 1, 1);
01454 rc |= draw_base_sugar_rings(framepos, bres, brad, ribbon_width, use_cyl);
01455
01456 if (rc != 0) {
01457 if (emitstructwarning())
01458 msgErr << "Warning: ribbons code encountered an unusual structure, geometry may not look as expected." << sendmsg;
01459 }
01460
01461
01462
01463
01464 if (use_bspline) {
01465 create_modified_CR_spline_basis(spline_basis, 1.25f);
01466 }
01467 }
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478 void DrawMolItem::draw_spline_new(int num, const float *coords,
01479 const float *offset, const int *idx,
01480 const float *cpwidths, const float *cpheights,
01481 int cpscalefactors, int b_res, int cyclic) {
01482 float q[4][3] = { {0, 0, 0},
01483 {0, 0, 0},
01484 {0, 0, 0},
01485 {0, 0, 0},
01486 };
01487 float *pts = NULL;
01488 float *prps = NULL;
01489 int *cols = NULL;
01490 float *interpwidths = NULL;
01491 float *interpheights = NULL;
01492 const float *widths = NULL;
01493 const float *heights = NULL;
01494 int i, j;
01495 int state, spanlen, numscalefactors;
01496 ResizeArray<float> pickpointcoords;
01497 ResizeArray<int> pickpointindices;
01498
01499
01500 int splinedivs = b_res + 2;
01501 float invsplinedivs = 1.0f / ((float) splinedivs);
01502 int hdivs = splinedivs / 2;
01503
01504
01505
01506
01507 pts = (float *) malloc(sizeof(float) * splinedivs * 3L * (num + 1L));
01508 prps = (float *) malloc(sizeof(float) * splinedivs * 3L * (num + 1L));
01509 cols = (int *) malloc(sizeof(int) * splinedivs * (num + 1L));
01510
01511
01512 if (cpscalefactors == num) {
01513 numscalefactors = splinedivs * (num + 1);
01514 interpwidths = (float *) malloc(sizeof(float) * numscalefactors);
01515 interpheights = (float *) malloc(sizeof(float) * numscalefactors);
01516 widths = interpwidths;
01517 heights = interpheights;
01518 } else if (cpscalefactors == 1) {
01519 numscalefactors = 1;
01520 widths = cpwidths;
01521 heights = cpheights;
01522 } else {
01523 return;
01524 }
01525
01526 if ((pts != NULL) && (prps != NULL) && (cols != NULL)) {
01527
01528 for (i=0; i<num; i++) {
01529 if (atomSel->on[idx[i]]) {
01530 pickpointcoords.append3(&coords[3L * i]);
01531 pickpointindices.append(idx[i]);
01532 }
01533 }
01534
01535
01536 state=0;
01537 spanlen = 0;
01538 for (i=0; i<num; i++) {
01539 if (atomSel->on[idx[i]]) {
01540 int cindex;
01541 int iminus1min, iminus2min, iplus1max;
01542 if (!cyclic) {
01543
01544 iminus1min = ((i - 1) >= 0) ? (i - 1) : 0;
01545 iminus2min = ((i - 2) >= 0) ? (i - 2) : 0;
01546 iplus1max = (i + 1 < num) ? (i + 1) : (num-1);
01547 } else {
01548
01549 iminus1min = (num + i - 1) % num;
01550 iminus2min = (num + i - 2) % num;
01551 iplus1max = (num + i + 1) % num;
01552 }
01553
01554
01555 if (state == 0) {
01556 state = 1;
01557 spanlen = 0;
01558 }
01559
01560
01561
01562
01563 make_spline_Q_matrix_noncontig(q, spline_basis,
01564 &coords[iminus2min * 3],
01565 &coords[iminus1min * 3],
01566 &coords[i * 3],
01567 &coords[iplus1max * 3]);
01568
01569
01570 for (j=0; j<splinedivs; j++) {
01571 make_spline_interpolation(&pts[(spanlen + j) * 3],
01572 j * invsplinedivs, q);
01573 }
01574
01575
01576 int cpind = iminus1min * 3;
01577
01578
01579 for (j=0; j<splinedivs; j++) {
01580 int ind = (spanlen + j)*3;
01581 float v = j * invsplinedivs;
01582 float vv = (1.0f - v);
01583 prps[ind ] = vv * offset[cpind ] + v * offset[cpind + 3];
01584 prps[ind + 1] = vv * offset[cpind + 1] + v * offset[cpind + 4];
01585 prps[ind + 2] = vv * offset[cpind + 2] + v * offset[cpind + 5];
01586 vec_normalize(&prps[ind]);
01587 }
01588
01589
01590 if (cpscalefactors == num) {
01591 float wminus1 = cpwidths[iminus1min];
01592 float w = cpwidths[i];
01593 float hminus1 = cpheights[iminus1min];
01594 float h = cpheights[i];
01595
01596 if (w >= 0 && wminus1 >= 0) {
01597
01598
01599
01600 for (j=0; j<splinedivs; j++) {
01601 int ind = spanlen + j;
01602 float v = j * invsplinedivs;
01603 float vv = (1.0f - v);
01604 interpwidths[ind] = vv * wminus1 + v * w;
01605 interpheights[ind] = vv * hminus1 + v * h;
01606 }
01607 } else {
01608 float wplus1 = cpwidths[iplus1max];
01609 if (wplus1 < 0)
01610 wplus1 = -wplus1;
01611
01612 if (w < 0) {
01613 w = -w;
01614
01615 for (j=0; j<hdivs; j++) {
01616 int ind = spanlen + j;
01617 float v = j * invsplinedivs;
01618 interpwidths[ind] = wminus1;
01619 interpheights[ind] = (1.0f - v) * hminus1 + v * h;
01620 }
01621 for (j=hdivs; j<splinedivs; j++) {
01622 int ind = spanlen + j;
01623 float v = j * invsplinedivs;
01624 float nv = (j-hdivs) * invsplinedivs;
01625 interpwidths[ind] = (1.0f - nv) * w + nv * wplus1;
01626 interpheights[ind] = (1.0f - v) * hminus1 + v * h;
01627 }
01628 } else {
01629 wminus1 = -wminus1;
01630
01631 for (j=0; j<hdivs; j++) {
01632 int ind = spanlen + j;
01633 float v = j * invsplinedivs;
01634 float nv = (j + (splinedivs - hdivs)) * invsplinedivs;
01635 interpwidths[ind] = (1.0f - nv) * wminus1 + nv * w;
01636 interpheights[ind] = (1.0f - v) * hminus1 + v * h;
01637 }
01638 for (j=hdivs; j<splinedivs; j++) {
01639 int ind = spanlen + j;
01640 float v = j * invsplinedivs;
01641 interpwidths[ind] = w;
01642 interpheights[ind] = (1.0f - v) * hminus1 + v * h;
01643 }
01644 }
01645 }
01646 }
01647
01648
01649 cindex = atomColor->color[idx[iminus1min]];
01650 for (j=0; j<hdivs; j++) {
01651 cols[spanlen + j] = cindex;
01652 }
01653
01654 cindex = atomColor->color[idx[i]];
01655 for (j=hdivs; j<splinedivs; j++) {
01656 cols[spanlen + j] = cindex;
01657 }
01658
01659 spanlen += splinedivs;
01660 } else {
01661
01662 if (state == 1) {
01663 state = 0;
01664
01665
01666 int iminus1min, iminus2min, iplus1max;
01667 if (!cyclic) {
01668
01669 iminus1min = ((i - 1) >= 0) ? (i - 1) : 0;
01670 iminus2min = ((i - 2) >= 0) ? (i - 2) : 0;
01671 iplus1max = (i + 1 < num) ? (i + 1) : (num-1);
01672 } else {
01673
01674 iminus1min = (num + i - 1) % num;
01675 iminus2min = (num + i - 2) % num;
01676 iplus1max = (num + i + 1) % num;
01677 }
01678
01679 int ind = spanlen * 3;
01680 make_spline_interpolation(&pts[ind], 1.0, q);
01681 int cpind = iminus2min * 3;
01682 prps[ind ] = offset[cpind + 3];
01683 prps[ind + 1] = offset[cpind + 4];
01684 prps[ind + 2] = offset[cpind + 5];
01685 vec_normalize(&prps[ind]);
01686
01687 if (cpscalefactors == num) {
01688 float w = cpwidths[i];
01689 float wminus1 = cpwidths[iminus1min];
01690
01691 float hminus1 = cpheights[iminus1min];
01692
01693 if (w >= 0 && wminus1 >= 0) {
01694 interpwidths[spanlen] = wminus1;
01695 interpheights[spanlen] = hminus1;
01696 } else {
01697 float wplus1 = cpwidths[iplus1max];
01698 if (wplus1 < 0)
01699 wplus1 = -wplus1;
01700
01701 if (w < 0) {
01702 w = -w;
01703
01704 float nv = (splinedivs - hdivs) * invsplinedivs;
01705 interpwidths[spanlen] = (1.0f - nv) * w + nv * wplus1;
01706 interpheights[spanlen] = wminus1;
01707 } else {
01708 if (w < 0)
01709 w = -w;
01710 wminus1 = -wminus1;
01711 interpwidths[spanlen] = w;
01712 interpheights[spanlen] = hminus1;
01713 }
01714 }
01715 }
01716
01717 cols[spanlen] = atomColor->color[idx[iminus1min]];
01718 spanlen++;
01719
01720
01721 int scalenum = (cpscalefactors == num) ? spanlen : 1;
01722 draw_ribbon_from_points(spanlen, pts, prps, cols,
01723 b_res, widths, heights, scalenum);
01724 }
01725 }
01726 }
01727
01728 if (state == 1) {
01729
01730 int iminus1min, iminus2min, iplus1max;
01731 if (!cyclic) {
01732
01733 iminus1min = ((i - 1) >= 0) ? (i - 1) : 0;
01734 iminus2min = ((i - 2) >= 0) ? (i - 2) : 0;
01735 iplus1max = (i + 1 < num) ? (i + 1) : (num-1);
01736 } else {
01737
01738 iminus1min = (num + i - 1) % num;
01739 iminus2min = (num + i - 2) % num;
01740 iplus1max = (num + i + 1) % num;
01741 }
01742
01743 int ind = spanlen * 3;
01744 make_spline_interpolation(&pts[ind], 1.0, q);
01745 int cpind = iminus2min * 3;
01746 prps[ind ] = offset[cpind + 3];
01747 prps[ind + 1] = offset[cpind + 4];
01748 prps[ind + 2] = offset[cpind + 5];
01749 vec_normalize(&prps[ind]);
01750
01751 if (cpscalefactors == num) {
01752 float w = cpwidths[iminus1min];
01753 float wminus1 = cpwidths[iminus1min];
01754
01755 float hminus1 = cpheights[iminus1min];
01756
01757 if (w >= 0 && wminus1 >= 0) {
01758 interpwidths[spanlen] = wminus1;
01759 interpheights[spanlen] = hminus1;
01760 } else {
01761 float wplus1 = cpwidths[iplus1max];
01762 if (wplus1 < 0)
01763 wplus1 = -wplus1;
01764
01765 if (w < 0) {
01766 w = -w;
01767
01768 float nv = (splinedivs - hdivs) * invsplinedivs;
01769 float nvv = (1.0f - nv);
01770 interpwidths[spanlen] = nvv * w + nv * wplus1;
01771 interpheights[spanlen] = wminus1;
01772 } else {
01773 if (w < 0)
01774 w = -w;
01775 wminus1 = -wminus1;
01776 interpwidths[spanlen] = w;
01777 interpheights[spanlen] = hminus1;
01778 }
01779 }
01780 }
01781
01782 cols[spanlen] = atomColor->color[idx[iminus1min]];
01783 spanlen++;
01784
01785
01786 int scalenum = (cpscalefactors == num) ? spanlen : 1;
01787 draw_ribbon_from_points(spanlen, pts, prps, cols,
01788 b_res, widths, heights, scalenum);
01789 }
01790 }
01791
01792 if (pts != NULL)
01793 free(pts);
01794
01795 if (prps != NULL)
01796 free(prps);
01797
01798 if (cols != NULL)
01799 free(cols);
01800
01801
01802 if (interpwidths != NULL)
01803 free(interpwidths);
01804
01805 if (interpheights != NULL)
01806 free(interpheights);
01807
01808
01809 if (pickpointindices.num() > 0) {
01810 DispCmdPickPointArray pickPointArray;
01811 pickPointArray.putdata(pickpointindices.num(), &pickpointindices[0],
01812 &pickpointcoords[0], cmdList);
01813 }
01814 }
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824 void DrawMolItem::draw_ribbon_from_points(int numpoints, const float *points,
01825 const float *perps, const int *cols, int numpanels,
01826 const float *widths, const float *heights,
01827 int numscalefactors) {
01828 int numverts, numsections;
01829 int point, section, panel, panelindex;
01830 int index;
01831 float *vertexarray, *normalarray, *colorarray;
01832 float *panelshape, *panelverts, *panelnorms;
01833 float curdir[3], perpdir[3], updir[3];
01834 float width, height, lastwidth, lastheight;
01835
01836
01837 if (numpoints < 2 || numpanels < 2)
01838 return;
01839
01840 numsections = numpoints - 1;
01841 numverts = numpoints * numpanels;
01842
01843
01844 vertexarray = (float *) malloc(numverts * 3L * sizeof(float));
01845 normalarray = (float *) malloc(numverts * 3L * sizeof(float));
01846 colorarray = (float *) malloc(numverts * 3L * sizeof(float));
01847
01848
01849 panelverts = (float *) malloc(numpanels * 2L * sizeof(float));
01850 panelnorms = (float *) malloc(numpanels * 2L * sizeof(float));
01851 panelshape = (float *) malloc(numpanels * 2L * sizeof(float));
01852
01853
01854 if (!vertexarray || !normalarray || !colorarray ||
01855 !panelverts || !panelnorms || !panelshape) {
01856 if (vertexarray) free(vertexarray);
01857 if (normalarray) free(normalarray);
01858 if (colorarray) free(colorarray);
01859 if (panelverts) free(panelverts);
01860 if (panelnorms) free(panelnorms);
01861 if (panelshape) free(panelshape);
01862 return;
01863 }
01864
01865
01866
01867
01868 float fracangle = ((float) VMD_TWOPI) / ((float) numpanels);
01869 for (panel=0; panel<numpanels; panel++) {
01870 int pidx = panel * 2;
01871 float radangle = panel * fracangle;
01872 sincosf(radangle, &panelshape[pidx], &panelshape[pidx + 1]);
01873 }
01874
01875
01876
01877 lastwidth = -999;
01878 lastheight = -999;
01879
01880
01881 width = widths[0];
01882 height = heights[0];
01883
01884
01885
01886
01887 for (point=0, index=0; point<numpoints; point++, index+=3) {
01888
01889
01890
01891
01892
01893 if (numscalefactors == numpoints) {
01894 width = widths[point];
01895 height = heights[point];
01896 }
01897
01898
01899
01900
01901
01902
01903 if (width != lastwidth || height != lastheight) {
01904 float invwidth, invheight;
01905
01906 lastwidth = width;
01907 lastheight = width;
01908
01909
01910 invwidth = 1.0f / width;
01911 invheight = 1.0f / height;
01912
01913 #if 1
01914
01915
01916
01917 for (panel=0; panel<numpanels; panel++) {
01918 int pidx = panel * 2;
01919 int pidy = pidx + 1;
01920 float xn, yn, invlen;
01921
01922
01923 panelverts[pidx] = width * panelshape[pidx];
01924 panelverts[pidy] = height * panelshape[pidy];
01925
01926
01927 xn = invwidth * panelshape[pidx];
01928 yn = invheight * panelshape[pidy];
01929 invlen = 1.0f / sqrtf(xn*xn + yn*yn);
01930 panelnorms[pidx] = xn * invlen;
01931 panelnorms[pidy] = yn * invlen;
01932 }
01933 #else
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943 for (panel=0; panel<(numpanels/2); panel++) {
01944 int pidx = panel * 2;
01945 int pidy = pidx + 1;
01946
01947
01948 panelverts[pidx] = (width / 2.0f) + panelshape[pidx];
01949 panelverts[pidy] = height * panelshape[pidy];
01950 }
01951
01952
01953 for (panel=(numpanels/2); panel<numpanels; panel++) {
01954 int pidx = panel * 2;
01955 int pidy = pidx + 1;
01956
01957
01958 panelverts[pidx] = (-width / 2.0f) + panelshape[pidx];
01959 panelverts[pidy] = height * panelshape[pidy];
01960 }
01961
01962
01963 for (panel=0; panel<numpanels; panel++) {
01964 int pidx = panel * 2;
01965 int pidy = pidx + 1;
01966 float xn, yn, invlen;
01967
01968
01969 xn = invwidth * panelshape[pidx];
01970 yn = invheight * panelshape[pidy];
01971 invlen = 1.0f / sqrtf(xn*xn + yn*yn);
01972 panelnorms[pidx] = xn * invlen;
01973 panelnorms[pidy] = yn * invlen;
01974 }
01975 #endif
01976 }
01977
01978
01979
01980
01981 if (point != (numpoints - 1)) {
01982 vec_sub(curdir, &points[index], &points[index + 3]);
01983 } else {
01984
01985
01986 vec_sub(curdir, &points[index-3], &points[index]);
01987 }
01988 vec_normalize(curdir);
01989
01990
01991 vec_copy(perpdir, &perps[index]);
01992 cross_prod(updir, curdir, perpdir);
01993 vec_normalize(updir);
01994
01995
01996 for (panel=0; panel<numpanels; panel++) {
01997 panelindex = (point * numpanels + panel) * 3;
01998 int pidx = panel * 2;
01999 float xv = panelverts[pidx ];
02000 float yv = panelverts[pidx + 1];
02001
02002
02003
02004 vertexarray[panelindex ] =
02005 (xv * perpdir[0]) + (yv * updir[0]) + points[index ];
02006 vertexarray[panelindex + 1] =
02007 (xv * perpdir[1]) + (yv * updir[1]) + points[index + 1];
02008 vertexarray[panelindex + 2] =
02009 (xv * perpdir[2]) + (yv * updir[2]) + points[index + 2];
02010 }
02011
02012
02013 for (panel=0; panel<numpanels; panel++) {
02014 panelindex = (point * numpanels + panel) * 3;
02015 int pidx = panel * 2;
02016 float xn = panelnorms[pidx ];
02017 float yn = panelnorms[pidx + 1];
02018
02019
02020
02021 normalarray[panelindex ] = (xn * perpdir[0]) + (yn * updir[0]);
02022 normalarray[panelindex + 1] = (xn * perpdir[1]) + (yn * updir[1]);
02023 normalarray[panelindex + 2] = (xn * perpdir[2]) + (yn * updir[2]);
02024 }
02025
02026
02027 const float *fp = scene->color_value(cols[point]);
02028 for (panel=0; panel<numpanels; panel++) {
02029 panelindex = ((point * numpanels) + panel) * 3;
02030 colorarray[panelindex ] = fp[0];
02031 colorarray[panelindex + 1] = fp[1];
02032 colorarray[panelindex + 2] = fp[2];
02033 }
02034 }
02035
02036
02037
02038 int numstripverts = numsections * ((numpanels * 2) + 2);
02039 unsigned int * faces = new unsigned int[numstripverts];
02040 int * vertsperstrip = new int[numsections];
02041 int numstrips = numsections;
02042
02043 int l=0;
02044 for (section=0; section<numsections; section++) {
02045 vertsperstrip[section] = (numpanels * 2) + 2;
02046
02047 int panel;
02048 for (panel=0; panel<numpanels; panel++) {
02049
02050 int index = ((section * numpanels) + panel);
02051 faces[l ] = index + numpanels;
02052 faces[l + 1] = index;
02053 l+=2;
02054 }
02055
02056
02057 int index = section * numpanels;
02058 faces[l ] = index + numpanels;
02059 faces[l + 1] = index;
02060
02061 l+=2;
02062 }
02063
02064
02065 append(DMATERIALON);
02066
02067
02068 DispCmdTriStrips cmdTriStrips;
02069 cmdTriStrips.putdata(vertexarray, normalarray, colorarray, numverts,
02070 vertsperstrip, numstrips, faces, numstripverts,
02071 0, cmdList);
02072
02073 delete [] faces;
02074 delete [] vertsperstrip;
02075
02076 free(vertexarray);
02077 free(normalarray);
02078 free(colorarray);
02079 free(panelshape);
02080 free(panelverts);
02081 free(panelnorms);
02082 }
02083
02084 int DrawMolItem::draw_cartoon_ribbons(float *framepos, int b_res, float b_rad,
02085 float ribbon_width, int use_cyl, int use_bspline) {
02086 float *coords = NULL;
02087 float *perps = NULL;
02088 int *idx = NULL;
02089 float *capos, *last_capos, *opos, *last_opos;
02090 int onum, canum, frag, num, res;
02091 float *widths, *heights;
02092 const char *modulatefield = NULL;
02093 const float *modulatedata = NULL;
02094 float *modulate = NULL;
02095 int rc=0;
02096
02097 sprintf (commentBuffer,"Mol[%d] Rep[%d] NewCartoon", mol->id(), repNumber);
02098 cmdCommentX.putdata(commentBuffer, cmdList);
02099
02100 #if defined(VMDFASTRIBBONS)
02101 wkf_timerhandle tm = wkf_timer_create();
02102 wkf_timerhandle tm2 = wkf_timer_create();
02103 wkf_timerhandle tm3 = wkf_timer_create();
02104 wkf_timerhandle tm4 = wkf_timer_create();
02105 wkf_timer_start(tm);
02106 wkf_timer_start(tm3);
02107 double foo=0.0;
02108 #endif
02109
02110
02111 float a[3], b[3], c[3], d[3], e[3], g[3];
02112
02113 if (use_bspline) {
02114 create_Bspline_basis(spline_basis);
02115 }
02116
02117
02118 rc |= draw_nucleic_ribbons(framepos, b_res, b_rad, ribbon_width / 7.0f, use_cyl, 1, 1);
02119 rc |= draw_nucleotide_cylinders(framepos, b_res, b_rad, ribbon_width / 7.0f, use_cyl);
02120
02121
02122
02123
02124 int CAtypecode = mol->atomNames.typecode("CA");
02125 int Otypecode = mol->atomNames.typecode("O");
02126 int OT1typecode = mol->atomNames.typecode("OT1");
02127
02128 if (CAtypecode < 0 || ((Otypecode < 0) && (OT1typecode < 0))) {
02129 return rc;
02130 }
02131 #if defined(VMDFASTRIBBONS)
02132 wkf_timer_stop(tm3);
02133 msgInfo << "Cartoon nucleotide time: " << wkf_timer_time(tm3) << sendmsg;
02134 #endif
02135
02136
02137 mol->need_secondary_structure(1);
02138
02139 #if defined(VMDFASTRIBBONS)
02140 wkf_timer_start(tm2);
02141 #endif
02142
02143
02144
02145 coords = (float *) malloc((mol->nResidues) * sizeof(float)*3);
02146 idx = (int *) malloc((mol->nResidues) * sizeof(int));
02147 perps = (float *) malloc((mol->nResidues) * sizeof(float)*3);
02148
02149
02150 widths = (float *) malloc(mol->nResidues * sizeof(float));
02151 heights = (float *) malloc(mol->nResidues * sizeof(float));
02152
02153 #if 1
02154
02155 modulatefield = getenv("VMDMODULATENEWCARTOON");
02156 #endif
02157 if (modulatefield != NULL) {
02158 if (!strcmp(modulatefield, "user")) {
02159 modulatedata = mol->current()->user;
02160
02161 } else {
02162 modulatedata = mol->extraflt.data(modulatefield);
02163 }
02164
02165
02166
02167
02168
02169
02170 modulate = (float *) calloc(1, mol->nResidues * sizeof(float));
02171 }
02172
02173
02174
02175 int numpfrag = mol->pfragList.num();
02176 for (frag=0; frag<numpfrag; frag++) {
02177 int cyclic=mol->pfragCyclic[frag];
02178 num = mol->pfragList[frag]->num();
02179 if (num < 2) {
02180 rc |= RIBBON_ERR_NOTENOUGH;
02181 continue;
02182 }
02183
02184
02185 res = (*mol->pfragList[frag])[0];
02186 canum = mol->find_atom_in_residue(CAtypecode, res);
02187 onum = mol->find_atom_in_residue(Otypecode, res);
02188
02189 if (canum < 0 || onum < 0) {
02190 continue;
02191 }
02192
02193
02194 int ca2, ca3, ca4;
02195 ca2=ca3=ca4=canum;
02196
02197 int starthelix=-1;
02198 int endhelix=-1;
02199 float starthelixperp[3];
02200
02201
02202 capos = framepos + 3L*canum;
02203 last_capos = capos;
02204 opos = framepos + 3L*onum;
02205 last_opos = opos;
02206
02207
02208 e[0] = e[1] = e[2] = 0.0;
02209 vec_copy(g, e);
02210
02211
02212
02213 if (cyclic) {
02214 int lastres = (*mol->pfragList[frag])[num-1];
02215 int lastcanum = mol->find_atom_in_residue(CAtypecode, lastres);
02216 last_capos = framepos + 3L*lastcanum;
02217
02218 int lastonum = mol->find_atom_in_residue(Otypecode, lastres);
02219 if (lastonum < 0 && OT1typecode >= 0) {
02220 lastonum = mol->find_atom_in_residue(OT1typecode, lastres);
02221 }
02222 last_opos = framepos + 3L*lastonum;
02223
02224
02225 vec_sub(a, capos, last_capos);
02226 vec_sub(b, last_opos, last_capos);
02227 cross_prod(c, a, b);
02228 cross_prod(d, c, a);
02229
02230 if (dot_prod(d, g) < 0) {
02231 vec_negate(b, d);
02232 } else {
02233 vec_copy(b, d);
02234 }
02235 vec_add(e, g, b);
02236 vec_normalize(e);
02237 vec_copy(g, e);
02238 }
02239
02240 int loop;
02241 for (loop=0; loop<num; loop++) {
02242 res = (*mol->pfragList[frag])[loop];
02243 const int ss = mol->residue(res)->sstruct;
02244 float helixpos[3];
02245
02246 int newcanum = mol->find_atom_in_residue(CAtypecode, res);
02247 if (newcanum >= 0) {
02248 ca4 = ca3;
02249 ca3 = ca2;
02250 ca2 = canum;
02251 canum = newcanum;
02252 capos = framepos + 3L*canum;
02253 }
02254
02255 onum = mol->find_atom_in_residue(Otypecode, res);
02256 if (onum < 0 && OT1typecode >= 0) {
02257 onum = mol->find_atom_in_residue(OT1typecode, res);
02258 }
02259 if (onum >= 0) {
02260 opos = framepos + 3L*onum;
02261 } else {
02262 rc |= RIBBON_ERR_PROTEIN_MESS;
02263 opos = last_opos;
02264 }
02265
02266
02267 float m_fac = 1.0f;
02268 if (modulatedata != NULL) {
02269 modulate[loop] = modulatedata[canum];
02270
02271
02272 m_fac = modulate[loop];
02273 if (m_fac <= 0.0f)
02274 m_fac = 1.0f;
02275 }
02276
02277 idx[loop] = canum;
02278
02279
02280 int drawhelixwithrods = 0;
02281 int drawbetawithribbons = 0;
02282 #if 0
02283 drawhelixwithrods = (getenv("VMDHELIXRODS") != NULL);
02284 drawbetawithribbons = (getenv("VMDBETARIBBONS") != NULL);
02285 #endif
02286
02287 switch (ss) {
02288 case SS_HELIX_ALPHA:
02289 case SS_HELIX_3_10:
02290 case SS_HELIX_PI:
02291 if (drawhelixwithrods) {
02292
02293
02294 if (starthelix == -1) {
02295 int helind;
02296 starthelix = loop;
02297 for (helind=loop; helind<num; helind++) {
02298 int hres = (*mol->pfragList[frag])[helind];
02299 const int hss = mol->residue(hres)->sstruct;
02300 if (hss == SS_HELIX_ALPHA ||
02301 hss == SS_HELIX_3_10 ||
02302 hss == SS_HELIX_PI) {
02303 endhelix = helind;
02304 } else {
02305 break;
02306 }
02307 }
02308
02309
02310 }
02311
02312 widths[loop] = 4 * b_rad * m_fac;
02313 heights[loop] = 4 * b_rad * m_fac;
02314 vec_copy(helixpos, framepos + 3L * canum);
02315 vec_add(helixpos, helixpos, framepos + 3L * ca2);
02316 vec_add(helixpos, helixpos, framepos + 3L * ca3);
02317 vec_add(helixpos, helixpos, framepos + 3L * ca4);
02318 vec_scale(helixpos, 0.25, helixpos);
02319
02320
02321 vec_copy(coords+loop*3, helixpos);
02322 capos = helixpos;
02323 } else {
02324 widths[loop] = ribbon_width * b_rad * m_fac;
02325 heights[loop] = b_rad * m_fac;
02326
02327 vec_copy(coords+loop*3, capos);
02328 }
02329 break;
02330
02331 case SS_TURN:
02332 case SS_COIL:
02333 case SS_BRIDGE:
02334 default:
02335 widths[loop] = b_rad * m_fac;
02336 heights[loop] = b_rad * m_fac;
02337
02338 vec_copy(coords+loop*3, capos);
02339 break;
02340
02341 case SS_BETA:
02342 widths[loop] = ribbon_width * b_rad * m_fac;
02343 heights[loop] = b_rad * m_fac;
02344
02345 if (drawbetawithribbons) {
02346
02347 vec_copy(coords+loop*3, capos);
02348 } else {
02349 float betapos[3];
02350 int drawarrowhead = 0;
02351
02352
02353
02354
02355
02356 int caplus1 = -1;
02357
02358 if ((loop+1) < num) {
02359 int nextres = (*mol->pfragList[frag])[loop+1];
02360 caplus1 = mol->find_atom_in_residue(CAtypecode, nextres);
02361
02362
02363 if (mol->residue(nextres)->sstruct != SS_BETA)
02364 drawarrowhead = 1;
02365 } else {
02366
02367 drawarrowhead = 1;
02368 }
02369
02370
02371
02372
02373 if (drawarrowhead)
02374 widths[loop] = -ribbon_width * b_rad * 1.75f;
02375
02376 if (caplus1 < 0)
02377 caplus1 = canum;
02378
02379 vec_copy(betapos, framepos + 3L * canum);
02380 vec_scale(betapos, 2.0f, betapos);
02381 vec_add(betapos, betapos, framepos + 3L * caplus1);
02382 vec_add(betapos, betapos, framepos + 3L * ca2);
02383 vec_scale(betapos, 0.25f, betapos);
02384
02385
02386 vec_copy(coords+loop*3, betapos);
02387
02388
02389 }
02390 break;
02391 }
02392
02393
02394
02395 vec_sub(a, capos, last_capos);
02396 vec_sub(b, last_opos, last_capos);
02397 cross_prod(c, a, b);
02398 cross_prod(d, c, a);
02399
02400
02401 if (dot_prod(d, g) < 0) {
02402 vec_negate(b, d);
02403 } else {
02404 vec_copy(b, d);
02405 }
02406 vec_add(e, g, b);
02407 vec_normalize(e);
02408 vec_copy(&perps[3L*loop], e);
02409 vec_copy(g, e);
02410 last_capos = capos;
02411 last_opos = opos;
02412
02413 if (drawhelixwithrods) {
02414 if (loop == starthelix) {
02415
02416 vec_copy(starthelixperp, e);
02417 } else if (loop > starthelix && loop < endhelix) {
02418
02419 vec_copy(&perps[3L*loop], starthelixperp);
02420 } else if (loop == endhelix) {
02421
02422 starthelix = -1;
02423 endhelix = -1;
02424 }
02425 }
02426
02427 }
02428
02429 if (!cyclic) {
02430
02431
02432 vec_copy(perps, perps+3);
02433 }
02434
02435 #if defined(VMDFASTRIBBONS)
02436 wkf_timer_start(tm4);
02437 #endif
02438
02439 draw_spline_new(num, coords, perps, idx, widths, heights, num, b_res, cyclic);
02440 #if defined(VMDFASTRIBBONS)
02441 wkf_timer_stop(tm4);
02442 foo+=wkf_timer_time(tm4);
02443 #endif
02444 }
02445
02446 if (coords) {
02447 free(coords);
02448 free(idx);
02449 free(perps);
02450 free(widths);
02451 free(heights);
02452 }
02453
02454 if (modulate) {
02455 free(modulate);
02456 }
02457
02458
02459
02460
02461 if (use_bspline) {
02462 create_modified_CR_spline_basis(spline_basis, 1.25f);
02463 }
02464
02465 #if defined(VMDFASTRIBBONS)
02466 wkf_timer_stop(tm2);
02467 msgInfo << "Cartoon spline time: " << wkf_timer_time(tm2) << sendmsg;
02468 msgInfo << " subspline time: " << foo << sendmsg;
02469 #endif
02470 #if defined(VMDFASTRIBBONS)
02471 wkf_timer_stop(tm);
02472 msgInfo << "Cartoon regen time: " << wkf_timer_time(tm) << sendmsg;
02473 wkf_timer_destroy(tm);
02474 wkf_timer_destroy(tm2);
02475 wkf_timer_destroy(tm3);
02476 #endif
02477
02478 return rc;
02479 }
02480