00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <math.h>
00024 #include <stdlib.h>
00025 #include <stdio.h>
00026
00027 #include "DrawMolItem.h"
00028 #include "DrawMolecule.h"
00029 #include "BaseMolecule.h"
00030 #include "Inform.h"
00031 #include "Isosurface.h"
00032 #include "MoleculeList.h"
00033 #include "Scene.h"
00034 #include "VolumetricData.h"
00035 #include "VMDApp.h"
00036 #include "WKFUtils.h"
00037
00038 #define MYSGN(a) (((a) > 0) ? 1 : -1)
00039
00040 int DrawMolItem::draw_volume_get_colorid(void) {
00041 int colorid = 0;
00042 int catindex;
00043
00044 switch (atomColor->method()) {
00045 case AtomColor::MOLECULE:
00046 case AtomColor::COLORID:
00047 colorid = atomColor->color_index();
00048 break;
00049
00050 default:
00051 catindex = scene->category_index("Display");
00052 colorid = scene->category_item_value(catindex, "Foreground");
00053 break;
00054 }
00055
00056 return colorid;
00057 }
00058
00059
00060 void DrawMolItem::draw_volume_box_solid(VolumetricData * v) {
00061 float v0[3], v1[3], v2[3];
00062 float vorigin[3], vxaxis[3], vyaxis[3], vzaxis[3];
00063 int usecolor;
00064
00065 int i;
00066 for (i=0; i<3; i++) {
00067 vorigin[i] = float(v->origin[i]);
00068 vxaxis[i] = float(v->xaxis[i]);
00069 vyaxis[i] = float(v->yaxis[i]);
00070 vzaxis[i] = float(v->zaxis[i]);
00071 }
00072
00073 append(DMATERIALON);
00074 usecolor=draw_volume_get_colorid();
00075 cmdColorIndex.putdata(usecolor, cmdList);
00076
00077
00078 v0[0] = vorigin[0];
00079 v0[1] = vorigin[1];
00080 v0[2] = vorigin[2];
00081
00082 v1[0] = v0[0] + vxaxis[0];
00083 v1[1] = v0[1] + vxaxis[1];
00084 v1[2] = v0[2] + vxaxis[2];
00085
00086 v2[0] = v1[0] + vyaxis[0];
00087 v2[1] = v1[1] + vyaxis[1];
00088 v2[2] = v1[2] + vyaxis[2];
00089 cmdSquare.putdata(v2, v1, v0, cmdList);
00090
00091
00092 v2[0] = v1[0] + vzaxis[0];
00093 v2[1] = v1[1] + vzaxis[1];
00094 v2[2] = v1[2] + vzaxis[2];
00095 cmdSquare.putdata(v0, v1, v2, cmdList);
00096
00097
00098 v1[0] = v0[0] + vyaxis[0];
00099 v1[1] = v0[1] + vyaxis[1];
00100 v1[2] = v0[2] + vyaxis[2];
00101
00102 v2[0] = v1[0] + vzaxis[0];
00103 v2[1] = v1[1] + vzaxis[1];
00104 v2[2] = v1[2] + vzaxis[2];
00105 cmdSquare.putdata(v2, v1, v0, cmdList);
00106
00107
00108 v0[0] = vorigin[0] + vzaxis[0];
00109 v0[1] = vorigin[1] + vzaxis[1];
00110 v0[2] = vorigin[2] + vzaxis[2];
00111
00112 v1[0] = v0[0] + vxaxis[0];
00113 v1[1] = v0[1] + vxaxis[1];
00114 v1[2] = v0[2] + vxaxis[2];
00115
00116 v2[0] = v1[0] + vyaxis[0];
00117 v2[1] = v1[1] + vyaxis[1];
00118 v2[2] = v1[2] + vyaxis[2];
00119 cmdSquare.putdata(v0, v1, v2, cmdList);
00120
00121
00122 v0[0] = vorigin[0] + vyaxis[0];
00123 v0[1] = vorigin[1] + vyaxis[1];
00124 v0[2] = vorigin[2] + vyaxis[2];
00125
00126 v1[0] = v0[0] + vxaxis[0];
00127 v1[1] = v0[1] + vxaxis[1];
00128 v1[2] = v0[2] + vxaxis[2];
00129
00130 v2[0] = v1[0] + vzaxis[0];
00131 v2[1] = v1[1] + vzaxis[1];
00132 v2[2] = v1[2] + vzaxis[2];
00133 cmdSquare.putdata(v2, v1, v0, cmdList);
00134
00135
00136 v0[0] = vorigin[0] + vxaxis[0];
00137 v0[1] = vorigin[1] + vxaxis[1];
00138 v0[2] = vorigin[2] + vxaxis[2];
00139
00140 v1[0] = v0[0] + vyaxis[0];
00141 v1[1] = v0[1] + vyaxis[1];
00142 v1[2] = v0[2] + vyaxis[2];
00143
00144 v2[0] = v1[0] + vzaxis[0];
00145 v2[1] = v1[1] + vzaxis[1];
00146 v2[2] = v1[2] + vzaxis[2];
00147 cmdSquare.putdata(v0, v1, v2, cmdList);
00148
00149 draw_volume_box_lines(v);
00150 }
00151
00152 void DrawMolItem::draw_volume_box_lines(VolumetricData * v) {
00153 float start[3], end[3];
00154 int xaxiscolor, yaxiscolor, zaxiscolor, axiscolor;
00155 int catindex;
00156 float vorigin[3], vxaxis[3], vyaxis[3], vzaxis[3];
00157
00158 int i;
00159 for (i=0; i<3; i++) {
00160 vorigin[i] = float(v->origin[i]);
00161 vxaxis[i] = float(v->xaxis[i]);
00162 vyaxis[i] = float(v->yaxis[i]);
00163 vzaxis[i] = float(v->zaxis[i]);
00164 }
00165
00166
00167 catindex = scene->category_index("Axes");
00168 xaxiscolor = scene->category_item_value(catindex, "X");
00169 yaxiscolor = scene->category_item_value(catindex, "Y");
00170 zaxiscolor = scene->category_item_value(catindex, "Z");
00171
00172 catindex = scene->category_index("Display");
00173 axiscolor = scene->category_item_value(catindex, "Foreground");
00174
00175 append(DMATERIALOFF);
00176 cmdLineType.putdata(SOLIDLINE, cmdList);
00177 cmdLineWidth.putdata(3, cmdList);
00178
00179 start[0] = vorigin[0];
00180 start[1] = vorigin[1];
00181 start[2] = vorigin[2];
00182
00183
00184 cmdColorIndex.putdata(xaxiscolor, cmdList);
00185 end[0] = start[0] + vxaxis[0];
00186 end[1] = start[1] + vxaxis[1];
00187 end[2] = start[2] + vxaxis[2];
00188 cmdLine.putdata(start, end, cmdList);
00189
00190
00191 cmdColorIndex.putdata(yaxiscolor, cmdList);
00192 end[0] = start[0] + vyaxis[0];
00193 end[1] = start[1] + vyaxis[1];
00194 end[2] = start[2] + vyaxis[2];
00195 cmdLine.putdata(start, end, cmdList);
00196
00197
00198 cmdColorIndex.putdata(zaxiscolor, cmdList);
00199 end[0] = start[0] + vzaxis[0];
00200 end[1] = start[1] + vzaxis[1];
00201 end[2] = start[2] + vzaxis[2];
00202 cmdLine.putdata(start, end, cmdList);
00203
00204
00205 cmdLineWidth.putdata(1, cmdList);
00206 cmdColorIndex.putdata(axiscolor, cmdList);
00207
00208 start[0] = vorigin[0] + vxaxis[0];
00209 start[1] = vorigin[1] + vxaxis[1];
00210 start[2] = vorigin[2] + vxaxis[2];
00211
00212 end[0] = start[0] + vyaxis[0];
00213 end[1] = start[1] + vyaxis[1];
00214 end[2] = start[2] + vyaxis[2];
00215 cmdLine.putdata(start, end, cmdList);
00216
00217 end[0] = start[0] + vzaxis[0];
00218 end[1] = start[1] + vzaxis[1];
00219 end[2] = start[2] + vzaxis[2];
00220 cmdLine.putdata(start, end, cmdList);
00221
00222 start[0] = vorigin[0] + vyaxis[0];
00223 start[1] = vorigin[1] + vyaxis[1];
00224 start[2] = vorigin[2] + vyaxis[2];
00225
00226 end[0] = start[0] + vxaxis[0];
00227 end[1] = start[1] + vxaxis[1];
00228 end[2] = start[2] + vxaxis[2];
00229 cmdLine.putdata(start, end, cmdList);
00230
00231 end[0] = start[0] + vzaxis[0];
00232 end[1] = start[1] + vzaxis[1];
00233 end[2] = start[2] + vzaxis[2];
00234 cmdLine.putdata(start, end, cmdList);
00235
00236
00237 start[0] = vorigin[0] + vzaxis[0];
00238 start[1] = vorigin[1] + vzaxis[1];
00239 start[2] = vorigin[2] + vzaxis[2];
00240
00241 end[0] = start[0] + vxaxis[0];
00242 end[1] = start[1] + vxaxis[1];
00243 end[2] = start[2] + vxaxis[2];
00244 cmdLine.putdata(start, end, cmdList);
00245
00246 end[0] = start[0] + vyaxis[0];
00247 end[1] = start[1] + vyaxis[1];
00248 end[2] = start[2] + vyaxis[2];
00249 cmdLine.putdata(start, end, cmdList);
00250
00251
00252 start[0] = vorigin[0] + vxaxis[0] + vyaxis[0] + vzaxis[0];
00253 start[1] = vorigin[1] + vxaxis[1] + vyaxis[1] + vzaxis[1];
00254 start[2] = vorigin[2] + vxaxis[2] + vyaxis[2] + vzaxis[2];
00255
00256 end[0] = start[0] - vxaxis[0];
00257 end[1] = start[1] - vxaxis[1];
00258 end[2] = start[2] - vxaxis[2];
00259 cmdLine.putdata(start, end, cmdList);
00260
00261 end[0] = start[0] - vyaxis[0];
00262 end[1] = start[1] - vyaxis[1];
00263 end[2] = start[2] - vyaxis[2];
00264 cmdLine.putdata(start, end, cmdList);
00265
00266 end[0] = start[0] - vzaxis[0];
00267 end[1] = start[1] - vzaxis[1];
00268 end[2] = start[2] - vzaxis[2];
00269 cmdLine.putdata(start, end, cmdList);
00270 }
00271
00272
00273 void DrawMolItem::draw_volume_isosurface_points(const VolumetricData * v,
00274 float isovalue, int stepsize, int thickness) {
00275 int x,y,z;
00276 float xax[3], yax[3], zax[3];
00277 int usecolor;
00278 ResizeArray<float> centers;
00279 ResizeArray<float> colors;
00280
00281 int i;
00282 float vorigin[3];
00283 for (i=0; i<3; i++) {
00284 vorigin[i] = float(v->origin[i]);
00285 }
00286
00287
00288 v->cell_axes(xax, yax, zax);
00289 ptrdiff_t zplanesz = v->xsize * v->ysize;
00290
00291 append(DMATERIALOFF);
00292 usecolor = draw_volume_get_colorid();
00293 const float *cp = scene->color_value(usecolor);
00294 cmdColorIndex.putdata(usecolor, cmdList);
00295
00296 int pointcount = 0;
00297 for (z=0; z<v->zsize; z+=stepsize) {
00298
00299
00300
00301
00302
00303
00304
00305 ptrdiff_t newsz = (pointcount + zplanesz) * 3L;
00306 if (newsz >= centers.num()) {
00307 colors.extend(newsz);
00308 centers.extend(newsz);
00309 }
00310
00311
00312 int idx = pointcount * 3;
00313 float *pos=¢ers[0];
00314 float *cols=&colors[0];
00315 for (y=0; y<v->ysize; y+=stepsize) {
00316 ptrdiff_t rowidx = z*zplanesz + y*v->xsize;
00317 const float *rowaddr = &(v->data[rowidx]);
00318
00319
00320 float rowx = vorigin[0] + y * yax[0] + z * zax[0];
00321 float rowy = vorigin[1] + y * yax[1] + z * zax[1];
00322 float rowz = vorigin[2] + y * yax[2] + z * zax[2];
00323
00324
00325 int lastgrid = v->xsize - 1;
00326 for (x=0; x<lastgrid; x+=stepsize) {
00327
00328
00329
00330
00331 if (!((rowaddr[x] <= isovalue) ^ (isovalue < rowaddr[x+1]))) {
00332
00333 pos[idx ] = rowx + x * xax[0];
00334 pos[idx+1] = rowy + x * xax[1];
00335 pos[idx+2] = rowz + x * xax[2];
00336
00337
00338
00339 cols[idx ] = cp[0];
00340 cols[idx+1] = cp[1];
00341 cols[idx+2] = cp[2];
00342
00343 idx+=3;
00344 pointcount++;
00345 }
00346 }
00347 }
00348
00349
00350 centers.set_size(idx);
00351 colors.set_size(idx);
00352
00353
00354
00355 if (pointcount > 10000000) {
00356 cmdPointArray.putdata((float *) ¢ers[0],
00357 (float *) &colors[0],
00358 (float) thickness,
00359 pointcount,
00360 cmdList);
00361
00362
00363 centers.clear();
00364 colors.clear();
00365 pointcount=0;
00366 }
00367 }
00368
00369 if (pointcount > 0) {
00370 cmdPointArray.putdata((float *) ¢ers[0],
00371 (float *) &colors[0],
00372 (float) thickness,
00373 pointcount,
00374 cmdList);
00375 }
00376 }
00377
00378
00379 void DrawMolItem::draw_volume_isosurface_lit_points(VolumetricData * v,
00380 float isovalue, int stepsize, int thickness) {
00381 int x,y,z;
00382 float xax[3], yax[3], zax[3];
00383 ResizeArray<float> centers;
00384 ResizeArray<float> normals;
00385 ResizeArray<float> colors;
00386
00387 int i;
00388 float vorigin[3];
00389 for (i=0; i<3; i++) {
00390 vorigin[i] = float(v->origin[i]);
00391 }
00392
00393
00394 v->cell_axes(xax, yax, zax);
00395 ptrdiff_t zplanesz = v->xsize * v->ysize;
00396
00397
00398
00399 const float *volgradient = v->access_volume_gradient();
00400
00401 append(DMATERIALON);
00402 int usecolor = draw_volume_get_colorid();
00403 const float *cp = scene->color_value(usecolor);
00404 cmdColorIndex.putdata(usecolor, cmdList);
00405
00406 int pointcount = 0;
00407 for (z=0; z<v->zsize; z+=stepsize) {
00408
00409
00410
00411
00412
00413
00414
00415 ptrdiff_t newsz = (pointcount + zplanesz) * 3L;
00416 if ((pointcount + zplanesz)*3L >= centers.num()) {
00417 colors.extend(newsz);
00418 normals.extend(newsz);
00419 centers.extend(newsz);
00420 }
00421
00422
00423 int idx = pointcount * 3;
00424 float *pos=¢ers[0];
00425 float *cols=&colors[0];
00426 float *norms=&normals[0];
00427 for (y=0; y<v->ysize; y+=stepsize) {
00428 ptrdiff_t rowidx = z*zplanesz + y*v->xsize;
00429 float *rowaddr = &(v->data[rowidx]);
00430
00431
00432 float rowx = vorigin[0] + y * yax[0] + z * zax[0];
00433 float rowy = vorigin[1] + y * yax[1] + z * zax[1];
00434 float rowz = vorigin[2] + y * yax[2] + z * zax[2];
00435
00436
00437 int lastgrid = v->xsize - 1;
00438 for (x=0; x<lastgrid; x+=stepsize) {
00439
00440
00441
00442
00443 if (!((rowaddr[x] <= isovalue) ^ (isovalue < rowaddr[x+1]))) {
00444
00445 pos[idx ] = rowx + x * xax[0];
00446 pos[idx+1] = rowy + x * xax[1];
00447 pos[idx+2] = rowz + x * xax[2];
00448
00449 ptrdiff_t volgradidx = (rowidx + x) * 3L;
00450 norms[idx ] = volgradient[volgradidx ];
00451 norms[idx+1] = volgradient[volgradidx + 1];
00452 norms[idx+2] = volgradient[volgradidx + 2];
00453
00454
00455
00456 cols[idx ] = cp[0];
00457 cols[idx+1] = cp[1];
00458 cols[idx+2] = cp[2];
00459
00460 idx+=3;
00461 pointcount++;
00462 }
00463 }
00464 }
00465
00466
00467 centers.set_size(idx);
00468 normals.set_size(idx);
00469 colors.set_size(idx);
00470
00471
00472
00473 if (pointcount > 10000000) {
00474 DispCmdLitPointArray cmdLitPointArray;
00475 cmdLitPointArray.putdata((float *) ¢ers[0],
00476 (float *) &normals[0],
00477 (float *) &colors[0],
00478 (float) thickness,
00479 pointcount,
00480 cmdList);
00481
00482
00483 centers.clear();
00484 normals.clear();
00485 colors.clear();
00486 pointcount=0;
00487 }
00488 }
00489
00490 if (pointcount > 0) {
00491 DispCmdLitPointArray cmdLitPointArray;
00492 cmdLitPointArray.putdata((float *) ¢ers[0],
00493 (float *) &normals[0],
00494 (float *) &colors[0],
00495 (float) thickness,
00496 pointcount,
00497 cmdList);
00498 }
00499 }
00500
00501
00502 void DrawMolItem::draw_volume_isosurface_lines(VolumetricData * v,
00503 float isovalue, int stepsize, int thickness) {
00504 IsoSurface *s = new IsoSurface;
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517 s->clear();
00518 s->compute(v, isovalue, stepsize);
00519
00520 if (s->numtriangles > 0) {
00521 append(DMATERIALOFF);
00522 cmdLineType.putdata(SOLIDLINE, cmdList);
00523 cmdLineWidth.putdata(thickness, cmdList);
00524
00525 int usecolor = draw_volume_get_colorid();
00526 cmdColorIndex.putdata(usecolor, cmdList);
00527
00528
00529 ptrdiff_t i;
00530 for (i=0; i<s->numtriangles; i++) {
00531 float *addr;
00532 addr = &(s->v[i * 9]);
00533 cmdLine.putdata(&addr[0], &addr[3], cmdList);
00534 cmdLine.putdata(&addr[3], &addr[6], cmdList);
00535 cmdLine.putdata(&addr[6], &addr[0], cmdList);
00536 }
00537 }
00538
00539 delete s;
00540 }
00541
00542
00543
00544 void DrawMolItem::draw_volume_isosurface_trimesh(VolumetricData * v,
00545 float isovalue, int stepsize,
00546 const float *voltex) {
00547 IsoSurface s;
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560 s.clear();
00561 s.compute(v, isovalue, stepsize);
00562 s.vertexfusion(36, 36);
00563 s.normalize();
00564
00565 #if 1
00566 if (s.numtriangles > 0) {
00567 append(DMATERIALON);
00568 int usecolor = draw_volume_get_colorid();
00569 cmdColorIndex.putdata(usecolor, cmdList);
00570
00571 if (voltex != NULL) {
00572
00573 s.set_color_voltex_rgb3fv(voltex);
00574 } else {
00575
00576 s.set_color_rgb3fv(scene->color_value(usecolor));
00577 }
00578
00579
00580
00581
00582
00583
00584 cmdTriMesh.putdata(&s.v[0], &s.n[0], &s.c[0], s.v.num() / 3,
00585 &s.f[0], s.numtriangles, 0, cmdList);
00586 }
00587 #else
00588 if (s.numtriangles > 0) {
00589 append(DMATERIALON);
00590 int usecolor = draw_volume_get_colorid();
00591 cmdColorIndex.putdata(usecolor, cmdList);
00592
00593
00594 float *c = new float[s.numtriangles * 9L];
00595 const float *fp = scene->color_value(usecolor);
00596 ptrdiff_t i;
00597 for (i=0; i<s.numtriangles; i++) {
00598 int ind = i * 9;
00599
00600 c[ind ] = fp[0];
00601 c[ind + 1] = fp[1];
00602 c[ind + 2] = fp[2];
00603
00604 ind+=3;
00605 c[ind ] = fp[0];
00606 c[ind + 1] = fp[1];
00607 c[ind + 2] = fp[2];
00608
00609 ind+=3;
00610 c[ind ] = fp[0];
00611 c[ind + 1] = fp[1];
00612 c[ind + 2] = fp[2];
00613 }
00614
00615
00616
00617
00618
00619
00620 cmdTriMesh.putdata(&s.v[0], &s.n[0], c, s.v.num() / 3,
00621 &s.f[0], s.numtriangles, 0, cmdList);
00622
00623 delete [] c;
00624 }
00625 #endif
00626 }
00627
00628
00629
00630
00631
00632 static void prepare_texture_coordinates(const VolumetricData *v,
00633 float loc, int axis, float *sliceNormal, float *sliceTextureCoords,
00634 float *sliceVertexes) {
00635
00636 float t0[3], t1[3], t2[3], t3[3];
00637 float v0[3], v1[3], v2[3], v3[3];
00638 float normal[3];
00639
00640 float vorigin[3], vxaxis[3], vyaxis[3], vzaxis[3];
00641 int i;
00642 for (i=0; i<3; i++) {
00643 vorigin[i] = float(v->origin[i]);
00644 vxaxis[i] = float(v->xaxis[i]);
00645 vyaxis[i] = float(v->yaxis[i]);
00646 vzaxis[i] = float(v->zaxis[i]);
00647 }
00648
00649
00650 if (loc < 0.0f)
00651 loc = 0.0f;
00652
00653 if (loc > 1.0f)
00654 loc = 1.0f;
00655
00656 switch (axis) {
00657
00658 case 0:
00659 default:
00660 t0[0] = loc;
00661 t0[1] = 0.0f;
00662 t0[2] = 0.0f;
00663
00664 t1[0] = loc;
00665 t1[1] = 0.0f;
00666 t1[2] = 1.0f;
00667
00668 t2[0] = loc;
00669 t2[1] = 1.0f;
00670 t2[2] = 1.0f;
00671
00672 t3[0] = loc;
00673 t3[1] = 1.0f;
00674 t3[2] = 0.0f;
00675
00676 v0[0] = vorigin[0] + (vxaxis[0] * loc);
00677 v0[1] = vorigin[1] + (vxaxis[1] * loc);
00678 v0[2] = vorigin[2] + (vxaxis[2] * loc);
00679
00680 v1[0] = v0[0] + vzaxis[0];
00681 v1[1] = v0[1] + vzaxis[1];
00682 v1[2] = v0[2] + vzaxis[2];
00683
00684 v2[0] = v0[0] + vzaxis[0] + vyaxis[0];
00685 v2[1] = v0[1] + vzaxis[1] + vyaxis[1];
00686 v2[2] = v0[2] + vzaxis[2] + vyaxis[2];
00687
00688 v3[0] = v0[0] + vyaxis[0];
00689 v3[1] = v0[1] + vyaxis[1];
00690 v3[2] = v0[2] + vyaxis[2];
00691
00692 normal[0] = vxaxis[0];
00693 normal[1] = vxaxis[1];
00694 normal[2] = vxaxis[2];
00695 vec_normalize(&normal[0]);
00696 break;
00697
00698
00699 case 1:
00700 t0[0] = 0.0f;
00701 t0[1] = loc;
00702 t0[2] = 0.0f;
00703
00704 t1[0] = 1.0f;
00705 t1[1] = loc;
00706 t1[2] = 0.0f;
00707
00708 t2[0] = 1.0f;
00709 t2[1] = loc;
00710 t2[2] = 1.0f;
00711
00712 t3[0] = 0.0f;
00713 t3[1] = loc;
00714 t3[2] = 1.0f;
00715
00716 v0[0] = vorigin[0] + (vyaxis[0] * loc);
00717 v0[1] = vorigin[1] + (vyaxis[1] * loc);
00718 v0[2] = vorigin[2] + (vyaxis[2] * loc);
00719
00720 v1[0] = v0[0] + vxaxis[0];
00721 v1[1] = v0[1] + vxaxis[1];
00722 v1[2] = v0[2] + vxaxis[2];
00723
00724 v2[0] = v0[0] + vxaxis[0] + vzaxis[0];
00725 v2[1] = v0[1] + vxaxis[1] + vzaxis[1];
00726 v2[2] = v0[2] + vxaxis[2] + vzaxis[2];
00727
00728 v3[0] = v0[0] + vzaxis[0];
00729 v3[1] = v0[1] + vzaxis[1];
00730 v3[2] = v0[2] + vzaxis[2];
00731
00732 normal[0] = vyaxis[0];
00733 normal[1] = vyaxis[1];
00734 normal[2] = vyaxis[2];
00735 vec_normalize(&normal[0]);
00736 break;
00737
00738
00739 case 2:
00740 t0[0] = 0.0f;
00741 t0[1] = 0.0f;
00742 t0[2] = loc;
00743
00744 t1[0] = 1.0f;
00745 t1[1] = 0.0f;
00746 t1[2] = loc;
00747
00748 t2[0] = 1.0f;
00749 t2[1] = 1.0f;
00750 t2[2] = loc;
00751
00752 t3[0] = 0.0f;
00753 t3[1] = 1.0f;
00754 t3[2] = loc;
00755
00756 v0[0] = vorigin[0] + (vzaxis[0] * loc);
00757 v0[1] = vorigin[1] + (vzaxis[1] * loc);
00758 v0[2] = vorigin[2] + (vzaxis[2] * loc);
00759
00760 v1[0] = v0[0] + vxaxis[0];
00761 v1[1] = v0[1] + vxaxis[1];
00762 v1[2] = v0[2] + vxaxis[2];
00763
00764 v2[0] = v0[0] + vxaxis[0] + vyaxis[0];
00765 v2[1] = v0[1] + vxaxis[1] + vyaxis[1];
00766 v2[2] = v0[2] + vxaxis[2] + vyaxis[2];
00767
00768 v3[0] = v0[0] + vyaxis[0];
00769 v3[1] = v0[1] + vyaxis[1];
00770 v3[2] = v0[2] + vyaxis[2];
00771
00772 normal[0] = vzaxis[0];
00773 normal[1] = vzaxis[1];
00774 normal[2] = vzaxis[2];
00775 vec_normalize(&normal[0]);
00776 break;
00777 }
00778
00779 vec_copy(sliceTextureCoords , t0);
00780 vec_copy(sliceTextureCoords+3, t1);
00781 vec_copy(sliceTextureCoords+6, t2);
00782 vec_copy(sliceTextureCoords+9, t3);
00783 vec_copy(sliceVertexes , v0);
00784 vec_copy(sliceVertexes+3, v1);
00785 vec_copy(sliceVertexes+6, v2);
00786 vec_copy(sliceVertexes+9, v3);
00787 vec_copy(sliceNormal, normal);
00788 }
00789
00790 void DrawMolItem::updateVolumeTexture() {
00791 float vmin, vmax;
00792 int volid = atomColor->volume_index();
00793 if (atomRep->method()==AtomRep::VOLSLICE) {
00794
00795 volid = (int)atomRep->get_data(AtomRep::SPHERERES);
00796 }
00797
00798 VolumetricData *v = mol->modify_volume_data(volid);
00799 if (v == NULL) {
00800 msgInfo << "No volume data loaded at index " << volid << sendmsg;
00801 return;
00802 }
00803
00804
00805
00806
00807
00808 atomColor->get_colorscale_minmax(&vmin, &vmax);
00809 if (!vmin && !vmax) {
00810 v->datarange(vmin, vmax);
00811 }
00812
00813 if (volumeTexture.getTextureMap() && !(needRegenerate & COL_REGEN) &&
00814 volid == voltexVolid && atomColor->method() == voltexColorMethod &&
00815 voltexDataMin == vmin && voltexDataMax == vmax) {
00816
00817 return;
00818 }
00819
00820 voltexColorMethod = atomColor->method();
00821 voltexVolid = volid;
00822 voltexDataMin = vmin;
00823 voltexDataMax = vmax;
00824
00825 volumeTexture.setGridData(v);
00826
00827
00828 switch (atomColor->method()) {
00829 case AtomColor::POS:
00830 case AtomColor::POSX:
00831 case AtomColor::POSY:
00832 case AtomColor::POSZ:
00833 volumeTexture.generatePosTexture();
00834 break;
00835
00836 case AtomColor::INDEX:
00837 volumeTexture.generateIndexTexture();
00838 break;
00839
00840 case AtomColor::CHARGE:
00841 volumeTexture.generateChargeTexture(vmin, vmax);
00842 break;
00843
00844 case AtomColor::VOLUME:
00845 volumeTexture.generateColorScaleTexture(vmin, vmax, scene);
00846 break;
00847
00848 #if 0
00849 case AtomColor::STRUCTURE:
00850
00851 volumeTexture.generateContourLineTexture(0.5, 0.5);
00852 break;
00853 #endif
00854
00855 case AtomColor::NAME:
00856 default:
00857
00858 volumeTexture.generateHSVTexture(vmin, vmax);
00859 break;
00860 }
00861 }
00862
00863
00864 void DrawMolItem::draw_volslice(int volid, float slice, int axis, int texmode) {
00865 const VolumetricData *v = mol->modify_volume_data(volid);
00866 float sliceNormal[3];
00867 float sliceTextureCoords[12];
00868 float sliceVertexes[12];
00869 if (!volumeTexture.getTextureMap()) {
00870 msgErr << "draw_volslice: no texture map has been generated!" << sendmsg;
00871 return;
00872 }
00873
00874 sprintf(commentBuffer, "Mol[%d] Rep[%d] VolSlice", mol->id(), repNumber);
00875 cmdCommentX.putdata(commentBuffer, cmdList);
00876
00877 prepare_texture_coordinates(v, slice, axis, sliceNormal, sliceTextureCoords,
00878 sliceVertexes);
00879
00880
00881
00882
00883
00884
00885 float tscale[3] = { float(v->xsize), float(v->ysize), float(v->zsize) };
00886 const int *size = volumeTexture.getTextureSize();
00887 for (int i=0; i<3; i++) {
00888 float rescale = (tscale[i] / (float)size[i]) * 0.99999f;
00889 sliceTextureCoords[i ] *= rescale;
00890 sliceTextureCoords[i+3] *= rescale;
00891 sliceTextureCoords[i+6] *= rescale;
00892 sliceTextureCoords[i+9] *= rescale;
00893 }
00894
00895 append(DMATERIALON);
00896
00897
00898 cmdVolSlice.putdata(texmode, sliceNormal, sliceVertexes, sliceTextureCoords, cmdList);
00899 }
00900
00901
00902 void DrawMolItem::draw_isosurface(int volid, float isovalue, int drawbox, int style, int stepsize, int thickness) {
00903 VolumetricData * v = NULL;
00904
00905 v = mol->modify_volume_data(volid);
00906 if (v == NULL) {
00907 msgInfo << "No volume data loaded at index " << volid << sendmsg;
00908 return;
00909 }
00910
00911 sprintf(commentBuffer, "Mol[%d] Rep[%d] Isosurface", mol->id(), repNumber);
00912 cmdCommentX.putdata(commentBuffer, cmdList);
00913
00914
00915 if (stepsize >= v->xsize)
00916 stepsize = (v->xsize - 1);
00917 if (stepsize >= v->ysize)
00918 stepsize = (v->ysize - 1);
00919 if (stepsize >= v->zsize)
00920 stepsize = (v->zsize - 1);
00921 if (stepsize < 2)
00922 stepsize = 1;
00923
00924 if (drawbox > 0) {
00925
00926 if (atomColor->method() == AtomColor::VOLUME) {
00927 append(DVOLTEXOFF);
00928 }
00929
00930 if (style > 0 || drawbox == 2) {
00931 draw_volume_box_lines(v);
00932 } else {
00933 draw_volume_box_solid(v);
00934 }
00935 if (atomColor->method() == AtomColor::VOLUME) {
00936 append(DVOLTEXON);
00937 }
00938 }
00939
00940 if ((drawbox == 2) || (drawbox == 0)) {
00941 switch (style) {
00942 case 3:
00943
00944 draw_volume_isosurface_lit_points(v, isovalue, stepsize, thickness);
00945 break;
00946
00947 case 2:
00948
00949 draw_volume_isosurface_points(v, isovalue, stepsize, thickness);
00950 break;
00951
00952 case 1:
00953
00954 draw_volume_isosurface_lines(v, isovalue, stepsize, thickness);
00955 break;
00956
00957 case 0:
00958 default:
00959
00960
00961
00962
00963 draw_volume_isosurface_trimesh(v, isovalue, stepsize);
00964 break;
00965 }
00966 }
00967 }
00968
00969
00970 #if 0
00971
00972 void DrawMolItem::draw_volslice_contour_lines(int volid, float slice, int axis) {
00973 const VolumetricData * v = NULL;
00974
00975 v = mol->get_volume_data(volid);
00976
00977 if (v == NULL) {
00978 msgInfo << "No volume data loaded at index " << volid << sendmsg;
00979 return;
00980 }
00981
00982 msgInfo << "Placeholder for contour slice not implemented yet..."
00983 }
00984 #endif
00985
00986
00987
00988 int DrawMolItem::calcseeds_grid(VolumetricData * v, ResizeArray<float> *seeds, int maxseedcount) {
00989 int i;
00990 float vorigin[3];
00991 for (i=0; i<3; i++) {
00992 vorigin[i] = float(v->origin[i]);
00993 }
00994
00995
00996 float xax[3], yax[3], zax[3];
00997 v->cell_axes(xax, yax, zax);
00998
00999 int seedcount = maxseedcount+1;
01000 int stepsize = 1;
01001
01002
01003
01004 const float *volgradient = v->access_volume_gradient();
01005
01006
01007 while (seedcount > maxseedcount) {
01008 seedcount=0;
01009 seeds->clear();
01010
01011 int x,y,z;
01012 float pos[3];
01013 ptrdiff_t zplanesz = v->xsize*v->ysize;
01014 for (z=0; z<v->zsize && seedcount < maxseedcount; z+=stepsize) {
01015 for (y=0; y<v->ysize; y+=stepsize) {
01016 ptrdiff_t rowidx = z*zplanesz + y*v->xsize;
01017
01018
01019 float rowx = vorigin[0] + y * yax[0] + z * zax[0];
01020 float rowy = vorigin[1] + y * yax[1] + z * zax[1];
01021 float rowz = vorigin[2] + y * yax[2] + z * zax[2];
01022
01023 for (x=0; x<v->xsize; x+=stepsize) {
01024 float grad[3];
01025 vec_copy(grad, &volgradient[(rowidx + x) * 3L]);
01026
01027 pos[0] = rowx + x * xax[0];
01028 pos[1] = rowy + x * xax[1];
01029 pos[2] = rowz + x * xax[2];
01030
01031 seedcount++;
01032 seeds->append3(&pos[0]);
01033 }
01034 }
01035 }
01036 stepsize++;
01037 }
01038
01039 return seedcount;
01040 }
01041
01042
01043
01044 int DrawMolItem::calcseeds_gradient_magnitude(VolumetricData * v, ResizeArray<float> *seeds, float seedmin, float seedmax, int maxseedcount) {
01045 float seedmin2 = seedmin*seedmin;
01046 float seedmax2 = seedmax*seedmax;
01047
01048 int i;
01049 float vorigin[3];
01050 for (i=0; i<3; i++) {
01051 vorigin[i] = float(v->origin[i]);
01052 }
01053
01054
01055 float xax[3], yax[3], zax[3];
01056 v->cell_axes(xax, yax, zax);
01057
01058 int seedcount = maxseedcount+1;
01059 int stepsize = 1;
01060
01061
01062
01063 const float *volgradient = v->access_volume_gradient();
01064
01065
01066 while (seedcount > maxseedcount) {
01067 seedcount=0;
01068 seeds->clear();
01069
01070 int x,y,z;
01071 float pos[3];
01072 ptrdiff_t zplanesz = v->xsize*v->ysize;
01073 for (z=0; z<v->zsize && seedcount < maxseedcount; z+=stepsize) {
01074 for (y=0; y<v->ysize; y+=stepsize) {
01075 ptrdiff_t rowidx = z*zplanesz + y*v->xsize;
01076
01077
01078 float rowx = vorigin[0] + y * yax[0] + z * zax[0];
01079 float rowy = vorigin[1] + y * yax[1] + z * zax[1];
01080 float rowz = vorigin[2] + y * yax[2] + z * zax[2];
01081
01082 for (x=0; x<v->xsize; x+=stepsize) {
01083 float grad[3];
01084 float gradmag2;
01085 vec_copy(grad, &volgradient[(rowidx + x) * 3L]);
01086 gradmag2 = dot_prod(grad, grad);
01087
01088 if ((gradmag2 <= seedmax2) &&
01089 (gradmag2 >= seedmin2)) {
01090 pos[0] = rowx + x * xax[0];
01091 pos[1] = rowy + x * xax[1];
01092 pos[2] = rowz + x * xax[2];
01093
01094 seedcount++;
01095 seeds->append3(&pos[0]);
01096 }
01097 }
01098 }
01099 }
01100 stepsize++;
01101 }
01102
01103 return seedcount;
01104 }
01105
01106
01107
01108 void DrawMolItem::draw_volume_field_lines(int volid, int seedusegrid, int maxseeds,
01109 float seedval, float deltacell,
01110 float minlen, float maxlen,
01111 int drawstyle, int tuberes, float thickness) {
01112 VolumetricData * v = NULL;
01113 v = mol->modify_volume_data(volid);
01114 int printdonemesg=0;
01115
01116 if (v == NULL) {
01117 msgInfo << "No volume data loaded at index " << volid << sendmsg;
01118 return;
01119 }
01120
01121 int seedcount = 0;
01122 int pointcount = 0;
01123 int totalpointcount = 0;
01124 int usecolor;
01125 ResizeArray<float> seeds;
01126
01127 sprintf(commentBuffer,"Mol[%d] Rep[%d] FieldLines", mol->id(), repNumber);
01128 cmdCommentX.putdata(commentBuffer, cmdList);
01129
01130
01131 DispCmdSphereRes cmdSphereRes;
01132 if (drawstyle != 0) {
01133 cmdSphereRes.putdata(tuberes, cmdList);
01134 append(DMATERIALON);
01135 thickness *= 0.05f;
01136 } else {
01137 append(DMATERIALOFF);
01138 }
01139
01140 usecolor = draw_volume_get_colorid();
01141 cmdColorIndex.putdata(usecolor, cmdList);
01142
01143 if (seedusegrid)
01144 seedcount = calcseeds_grid(v, &seeds, maxseeds);
01145 else
01146 seedcount = calcseeds_gradient_magnitude(v, &seeds, seedval*0.5f, seedval*1.5f, maxseeds);
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159 float lx, ly, lz;
01160 v->cell_lengths(&lx, &ly, &lz);
01161 float mincelllen=lx;
01162 mincelllen = (mincelllen < ly) ? mincelllen : ly;
01163 mincelllen = (mincelllen < lz) ? mincelllen : lz;
01164 float delta=mincelllen * deltacell;
01165
01166
01167
01168 float mingmag = 0.0001f;
01169
01170
01171 float maxgmag = 5;
01172
01173 ResizeArray<float> points;
01174
01175
01176
01177 v->access_volume_gradient();
01178
01179
01180
01181
01182 wkfmsgtimer *msgt = wkf_msg_timer_create(1);
01183 int seed;
01184 for (seed=0; seed < seedcount; seed++) {
01185
01186 if (!(seed & 7) && wkf_msg_timer_timeout(msgt)) {
01187 char tmpbuf[128] = { 0 };
01188 sprintf(tmpbuf, "%6.2f %% complete", (100.0f * seed) / (float) seedcount);
01189 msgInfo << "integrating " << seedcount << " field lines: " << tmpbuf << sendmsg;
01190 printdonemesg=1;
01191 }
01192
01193 int direction;
01194 for (direction=-1; direction != 1; direction=1) {
01195 float pos[3], comsum[3];
01196 vec_copy(pos, &seeds[seed*3]);
01197
01198
01199 points.clear();
01200
01201
01202 pointcount=0;
01203 totalpointcount++;
01204 float len=0;
01205 int iterations=0;
01206 float dir = (float) direction;
01207
01208 vec_zero(comsum);
01209
01210 while ((len<maxlen) && (totalpointcount < 100000000)) {
01211 float grad[3];
01212
01213
01214 v->voxel_gradient_interpolate_from_coord(pos, grad);
01215
01216
01217
01218
01219
01220
01221
01222 float gmag = norm(grad);
01223 if (!(gmag >= mingmag && gmag <= maxgmag))
01224 break;
01225
01226
01227
01228
01229
01230
01231
01232
01233 if (!(iterations & 1)) {
01234
01235 points.append3(&pos[0]);
01236
01237 vec_incr(comsum, pos);
01238
01239 pointcount++;
01240 totalpointcount++;
01241 }
01242
01243
01244
01245
01246 vec_scaled_add(pos, dir * delta / gmag, grad);
01247 len += delta;
01248
01249 iterations++;
01250 }
01251
01252 int drawfieldline = 1;
01253
01254
01255
01256
01257 if (pointcount < 2 || len < minlen)
01258 drawfieldline = 0;
01259
01260
01261 if (drawfieldline) {
01262 float com[3];
01263 vec_scale(com, 1.0f / (float) pointcount, comsum);
01264 float minlen2 = minlen*minlen;
01265
01266 drawfieldline = 0;
01267 int p;
01268 for (p=0; p<pointcount; p++) {
01269 if ((2.0f * distance2(com, &points[p*3])) > minlen2) {
01270 drawfieldline = 1;
01271 break;
01272 }
01273 }
01274 }
01275
01276
01277
01278 if (drawstyle != 0) {
01279
01280 if (drawfieldline) {
01281 cmdColorIndex.putdata(usecolor, cmdList);
01282 DispCmdCylinder cmdCyl;
01283 int maxcylidx = (pointcount - 1) * 3;
01284 int p;
01285 if (drawstyle == 1) {
01286 for (p=0; p<maxcylidx; p+=3) {
01287 cmdCyl.putdata(&points[p], &points[p+3], thickness,
01288 tuberes, 0, cmdList);
01289 }
01290 maxcylidx++;
01291 }
01292
01293 for (p=0; p<maxcylidx; p+=3) {
01294 cmdSphere.putdata(&points[p], thickness, cmdList);
01295 }
01296 }
01297 } else if (drawfieldline) {
01298
01299 cmdLineType.putdata(SOLIDLINE, cmdList);
01300 cmdLineWidth.putdata((int) thickness, cmdList);
01301 cmdColorIndex.putdata(usecolor, cmdList);
01302 DispCmdPolyLineArray cmdPolyLineArray;
01303 cmdPolyLineArray.putdata(&points[0], pointcount, cmdList);
01304 }
01305 }
01306 }
01307 wkf_msg_timer_destroy(msgt);
01308
01309 if (printdonemesg)
01310 msgInfo << "field line integration complete." << sendmsg;
01311 }
01312
01313