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