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(const 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(const 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 *addr;
00277 float pos[3];
00278 float xax[3], yax[3], zax[3];
00279 int pointcount = 0;
00280 int usecolor;
00281 ResizeArray<float> centers;
00282 ResizeArray<float> colors;
00283
00284 int i;
00285 float vorigin[3];
00286 for (i=0; i<3; i++) {
00287 vorigin[i] = float(v->origin[i]);
00288 }
00289
00290 append(DMATERIALOFF);
00291 usecolor = draw_volume_get_colorid();
00292 const float *cp = scene->color_value(usecolor);
00293 cmdColorIndex.putdata(usecolor, cmdList);
00294
00295
00296 v->cell_axes(xax, yax, zax);
00297
00298 for (z=0; z<v->zsize; z+=stepsize) {
00299 for (y=0; y<v->ysize; y+=stepsize) {
00300 addr = &(v->data[(z * (v->xsize * v->ysize)) + (y * v->xsize)]);
00301
00302
00303 for (x=0; x<(v->xsize - 1); x+=stepsize) {
00304 float diff, isodiff;
00305
00306
00307 diff = addr[x] - addr[x+1];
00308 isodiff = addr[x] - isovalue;
00309 if ((fabs(diff) > fabs(isodiff)) && (MYSGN(diff) == MYSGN(isodiff))) {
00310 pos[0] = vorigin[0] + x * xax[0] + y * yax[0] + z * zax[0];
00311 pos[1] = vorigin[1] + x * xax[1] + y * yax[1] + z * zax[1];
00312 pos[2] = vorigin[2] + x * xax[2] + y * yax[2] + z * zax[2];
00313
00314
00315 centers.append(pos[0]);
00316 centers.append(pos[1]);
00317 centers.append(pos[2]);
00318 colors.append(cp[0]);
00319 colors.append(cp[1]);
00320 colors.append(cp[2]);
00321
00322 pointcount++;
00323 }
00324 }
00325 }
00326 }
00327
00328 if (pointcount > 0) {
00329 cmdPointArray.putdata((float *) ¢ers[0],
00330 (float *) &colors[0],
00331 (float) thickness,
00332 pointcount,
00333 cmdList);
00334 }
00335 }
00336
00337
00338 void DrawMolItem::draw_volume_isosurface_lit_points(const VolumetricData * v,
00339 float isovalue, int stepsize, int thickness) {
00340 int x,y,z;
00341 float *addr;
00342 float pos[3];
00343 float xax[3], yax[3], zax[3];
00344 ResizeArray<float> centers;
00345 ResizeArray<float> normals;
00346 ResizeArray<float> colors;
00347
00348 int i;
00349 float vorigin[3];
00350 for (i=0; i<3; i++) {
00351 vorigin[i] = float(v->origin[i]);
00352 }
00353
00354 int pointcount = 0;
00355 int usecolor;
00356 append(DMATERIALON);
00357 usecolor = draw_volume_get_colorid();
00358 const float *cp = scene->color_value(usecolor);
00359 cmdColorIndex.putdata(usecolor, cmdList);
00360
00361
00362 v->cell_axes(xax, yax, zax);
00363
00364 for (z=0; z<v->zsize; z+=stepsize) {
00365 for (y=0; y<v->ysize; y+=stepsize) {
00366 addr = &(v->data[(z * (v->xsize * v->ysize)) + (y * v->xsize)]);
00367
00368
00369 for (x=0; x<(v->xsize - 1); x+=stepsize) {
00370 float diff, isodiff;
00371
00372
00373 diff = addr[x] - addr[x+1];
00374 isodiff = addr[x] - isovalue;
00375 if ((fabs(diff) > fabs(isodiff)) && (MYSGN(diff) == MYSGN(isodiff))) {
00376 pos[0] = vorigin[0] + x * xax[0] + y * yax[0] + z * zax[0];
00377 pos[1] = vorigin[1] + x * xax[1] + y * yax[1] + z * zax[1];
00378 pos[2] = vorigin[2] + x * xax[2] + y * yax[2] + z * zax[2];
00379
00380 float norm[3];
00381 vec_copy(norm, &v->gradient[(z*v->xsize*v->ysize + y*v->xsize + x) * 3]);
00382
00383
00384 centers.append(pos[0]);
00385 centers.append(pos[1]);
00386 centers.append(pos[2]);
00387 normals.append(norm[0]);
00388 normals.append(norm[1]);
00389 normals.append(norm[2]);
00390 colors.append(cp[0]);
00391 colors.append(cp[1]);
00392 colors.append(cp[2]);
00393
00394 pointcount++;
00395 }
00396 }
00397 }
00398 }
00399
00400 if (pointcount > 0) {
00401 DispCmdLitPointArray cmdLitPointArray;
00402 cmdLitPointArray.putdata((float *) ¢ers[0],
00403 (float *) &normals[0],
00404 (float *) &colors[0],
00405 (float) thickness,
00406 pointcount,
00407 cmdList);
00408 }
00409 }
00410
00411
00412 void DrawMolItem::draw_volume_isosurface_lines(const VolumetricData * v,
00413 float isovalue, int stepsize, int thickness) {
00414 int i, usecolor;
00415 IsoSurface *s = new IsoSurface;
00416 s->clear();
00417 s->compute(v, isovalue, stepsize);
00418
00419 if (s->numtriangles > 0) {
00420 append(DMATERIALOFF);
00421 cmdLineType.putdata(SOLIDLINE, cmdList);
00422 cmdLineWidth.putdata(thickness, cmdList);
00423
00424 usecolor = draw_volume_get_colorid();
00425 cmdColorIndex.putdata(usecolor, cmdList);
00426
00427
00428 for (i=0; i<s->numtriangles; i++) {
00429 float *addr;
00430 addr = &(s->v[i * 9]);
00431 cmdLine.putdata(&addr[0], &addr[3], cmdList);
00432 cmdLine.putdata(&addr[3], &addr[6], cmdList);
00433 cmdLine.putdata(&addr[6], &addr[0], cmdList);
00434 }
00435 }
00436
00437 delete s;
00438 }
00439
00440
00441
00442 void DrawMolItem::draw_volume_isosurface_trimesh(const VolumetricData * v,
00443 float isovalue, int stepsize) {
00444 int i, usecolor;
00445 IsoSurface s;
00446 s.clear();
00447 s.compute(v, isovalue, stepsize);
00448 s.vertexfusion(v, 36, 36);
00449 s.normalize();
00450
00451 if (s.numtriangles > 0) {
00452 append(DMATERIALON);
00453 usecolor = draw_volume_get_colorid();
00454 cmdColorIndex.putdata(usecolor, cmdList);
00455
00456
00457 float *c = new float[s.numtriangles * 9];
00458 const float *fp = scene->color_value(usecolor);
00459 for (i=0; i<s.numtriangles; i++) {
00460 int ind = i * 9;
00461
00462 c[ind ] = fp[0];
00463 c[ind + 1] = fp[1];
00464 c[ind + 2] = fp[2];
00465
00466 ind+=3;
00467 c[ind ] = fp[0];
00468 c[ind + 1] = fp[1];
00469 c[ind + 2] = fp[2];
00470
00471 ind+=3;
00472 c[ind ] = fp[0];
00473 c[ind + 1] = fp[1];
00474 c[ind + 2] = fp[2];
00475 }
00476
00477
00478
00479
00480 cmdTriMesh.putdata(&s.v[0], &s.n[0], c, s.v.num() / 3,
00481 &s.f[0], s.numtriangles, 0, cmdList);
00482
00483 delete [] c;
00484 }
00485 }
00486
00487
00488
00489
00490
00491 static void prepare_texture_coordinates(const VolumetricData *v,
00492 float loc, int axis, float *sliceNormal, float *sliceTextureCoords,
00493 float *sliceVertexes) {
00494
00495 float t0[3], t1[3], t2[3], t3[3];
00496 float v0[3], v1[3], v2[3], v3[3];
00497 float normal[3];
00498
00499 float vorigin[3], vxaxis[3], vyaxis[3], vzaxis[3];
00500 int i;
00501 for (i=0; i<3; i++) {
00502 vorigin[i] = float(v->origin[i]);
00503 vxaxis[i] = float(v->xaxis[i]);
00504 vyaxis[i] = float(v->yaxis[i]);
00505 vzaxis[i] = float(v->zaxis[i]);
00506 }
00507
00508
00509 if (loc < 0.0f)
00510 loc = 0.0f;
00511
00512 if (loc > 1.0f)
00513 loc = 1.0f;
00514
00515 switch (axis) {
00516
00517 case 0:
00518 default:
00519 t0[0] = loc;
00520 t0[1] = 0.0f;
00521 t0[2] = 0.0f;
00522
00523 t1[0] = loc;
00524 t1[1] = 0.0f;
00525 t1[2] = 1.0f;
00526
00527 t2[0] = loc;
00528 t2[1] = 1.0f;
00529 t2[2] = 1.0f;
00530
00531 t3[0] = loc;
00532 t3[1] = 1.0f;
00533 t3[2] = 0.0f;
00534
00535 v0[0] = vorigin[0] + (vxaxis[0] * loc);
00536 v0[1] = vorigin[1] + (vxaxis[1] * loc);
00537 v0[2] = vorigin[2] + (vxaxis[2] * loc);
00538
00539 v1[0] = v0[0] + vzaxis[0];
00540 v1[1] = v0[1] + vzaxis[1];
00541 v1[2] = v0[2] + vzaxis[2];
00542
00543 v2[0] = v0[0] + vzaxis[0] + vyaxis[0];
00544 v2[1] = v0[1] + vzaxis[1] + vyaxis[1];
00545 v2[2] = v0[2] + vzaxis[2] + vyaxis[2];
00546
00547 v3[0] = v0[0] + vyaxis[0];
00548 v3[1] = v0[1] + vyaxis[1];
00549 v3[2] = v0[2] + vyaxis[2];
00550
00551 normal[0] = vxaxis[0];
00552 normal[1] = vxaxis[1];
00553 normal[2] = vxaxis[2];
00554 vec_normalize(&normal[0]);
00555 break;
00556
00557
00558 case 1:
00559 t0[0] = 0.0f;
00560 t0[1] = loc;
00561 t0[2] = 0.0f;
00562
00563 t1[0] = 1.0f;
00564 t1[1] = loc;
00565 t1[2] = 0.0f;
00566
00567 t2[0] = 1.0f;
00568 t2[1] = loc;
00569 t2[2] = 1.0f;
00570
00571 t3[0] = 0.0f;
00572 t3[1] = loc;
00573 t3[2] = 1.0f;
00574
00575 v0[0] = vorigin[0] + (vyaxis[0] * loc);
00576 v0[1] = vorigin[1] + (vyaxis[1] * loc);
00577 v0[2] = vorigin[2] + (vyaxis[2] * loc);
00578
00579 v1[0] = v0[0] + vxaxis[0];
00580 v1[1] = v0[1] + vxaxis[1];
00581 v1[2] = v0[2] + vxaxis[2];
00582
00583 v2[0] = v0[0] + vxaxis[0] + vzaxis[0];
00584 v2[1] = v0[1] + vxaxis[1] + vzaxis[1];
00585 v2[2] = v0[2] + vxaxis[2] + vzaxis[2];
00586
00587 v3[0] = v0[0] + vzaxis[0];
00588 v3[1] = v0[1] + vzaxis[1];
00589 v3[2] = v0[2] + vzaxis[2];
00590
00591 normal[0] = vyaxis[0];
00592 normal[1] = vyaxis[1];
00593 normal[2] = vyaxis[2];
00594 vec_normalize(&normal[0]);
00595 break;
00596
00597
00598 case 2:
00599 t0[0] = 0.0f;
00600 t0[1] = 0.0f;
00601 t0[2] = loc;
00602
00603 t1[0] = 1.0f;
00604 t1[1] = 0.0f;
00605 t1[2] = loc;
00606
00607 t2[0] = 1.0f;
00608 t2[1] = 1.0f;
00609 t2[2] = loc;
00610
00611 t3[0] = 0.0f;
00612 t3[1] = 1.0f;
00613 t3[2] = loc;
00614
00615 v0[0] = vorigin[0] + (vzaxis[0] * loc);
00616 v0[1] = vorigin[1] + (vzaxis[1] * loc);
00617 v0[2] = vorigin[2] + (vzaxis[2] * loc);
00618
00619 v1[0] = v0[0] + vxaxis[0];
00620 v1[1] = v0[1] + vxaxis[1];
00621 v1[2] = v0[2] + vxaxis[2];
00622
00623 v2[0] = v0[0] + vxaxis[0] + vyaxis[0];
00624 v2[1] = v0[1] + vxaxis[1] + vyaxis[1];
00625 v2[2] = v0[2] + vxaxis[2] + vyaxis[2];
00626
00627 v3[0] = v0[0] + vyaxis[0];
00628 v3[1] = v0[1] + vyaxis[1];
00629 v3[2] = v0[2] + vyaxis[2];
00630
00631 normal[0] = vzaxis[0];
00632 normal[1] = vzaxis[1];
00633 normal[2] = vzaxis[2];
00634 vec_normalize(&normal[0]);
00635 break;
00636 }
00637
00638 vec_copy(sliceTextureCoords , t0);
00639 vec_copy(sliceTextureCoords+3, t1);
00640 vec_copy(sliceTextureCoords+6, t2);
00641 vec_copy(sliceTextureCoords+9, t3);
00642 vec_copy(sliceVertexes , v0);
00643 vec_copy(sliceVertexes+3, v1);
00644 vec_copy(sliceVertexes+6, v2);
00645 vec_copy(sliceVertexes+9, v3);
00646 vec_copy(sliceNormal, normal);
00647 }
00648
00649 void DrawMolItem::updateVolumeTexture() {
00650 float vmin, vmax;
00651 int volid = atomColor->volume_index();
00652 if (atomRep->method()==AtomRep::VOLSLICE) {
00653
00654 volid = (int)atomRep->get_data(AtomRep::SPHERERES);
00655 }
00656
00657 const VolumetricData *v = mol->get_volume_data(volid);
00658 if (v == NULL) {
00659 msgInfo << "No volume data loaded at index " << volid << sendmsg;
00660 return;
00661 }
00662
00663
00664
00665
00666
00667 atomColor->get_colorscale_minmax(&vmin, &vmax);
00668 if (!vmin && !vmax) {
00669 vmin = v->datamin;
00670 vmax = v->datamax;
00671 }
00672
00673 if (volumeTexture.getTextureMap() && !(needRegenerate & COL_REGEN) &&
00674 volid == voltexVolid && atomColor->method() == voltexColorMethod &&
00675 voltexDataMin == vmin && voltexDataMax == vmax) {
00676
00677 return;
00678 }
00679
00680 voltexColorMethod = atomColor->method();
00681 voltexVolid = volid;
00682 voltexDataMin = vmin;
00683 voltexDataMax = vmax;
00684
00685 volumeTexture.setGridData(v);
00686
00687
00688 switch (atomColor->method()) {
00689 case AtomColor::POS:
00690 case AtomColor::POSX:
00691 case AtomColor::POSY:
00692 case AtomColor::POSZ:
00693 volumeTexture.generatePosTexture();
00694 break;
00695
00696 case AtomColor::INDEX:
00697 volumeTexture.generateIndexTexture();
00698 break;
00699
00700 case AtomColor::CHARGE:
00701 volumeTexture.generateChargeTexture(vmin, vmax);
00702 break;
00703
00704 case AtomColor::VOLUME:
00705 volumeTexture.generateColorScaleTexture(vmin, vmax, scene);
00706 break;
00707
00708 #if 0
00709 case AtomColor::STRUCTURE:
00710
00711 volumeTexture.generateContourLineTexture(0.5, 0.5);
00712 break;
00713 #endif
00714
00715 case AtomColor::NAME:
00716 default:
00717
00718 volumeTexture.generateHSVTexture(vmin, vmax);
00719 break;
00720 }
00721 }
00722
00723
00724 void DrawMolItem::draw_volslice(int volid, float slice, int axis, int texmode) {
00725 const VolumetricData *v = mol->get_volume_data(volid);
00726 float sliceNormal[3];
00727 float sliceTextureCoords[12];
00728 float sliceVertexes[12];
00729 if (!volumeTexture.getTextureMap()) {
00730 msgErr << "draw_volslice: no texture map has been generated!" << sendmsg;
00731 return;
00732 }
00733
00734 sprintf(commentBuffer, "MoleculeID: %d ReprID: %d Beginning VolSlice",
00735 mol->id(), repNumber);
00736 cmdCommentX.putdata(commentBuffer, cmdList);
00737
00738 prepare_texture_coordinates(v, slice, axis, sliceNormal, sliceTextureCoords,
00739 sliceVertexes);
00740
00741
00742
00743
00744
00745
00746 float tscale[3] = { float(v->xsize), float(v->ysize), float(v->zsize) };
00747 const int *size = volumeTexture.getTextureSize();
00748 for (int i=0; i<3; i++) {
00749 float rescale = (tscale[i] / (float)size[i]) * 0.99999f;
00750 sliceTextureCoords[i ] *= rescale;
00751 sliceTextureCoords[i+3] *= rescale;
00752 sliceTextureCoords[i+6] *= rescale;
00753 sliceTextureCoords[i+9] *= rescale;
00754 }
00755
00756 append(DMATERIALON);
00757
00758
00759 cmdVolSlice.putdata(texmode, sliceNormal, sliceVertexes, sliceTextureCoords, cmdList);
00760 }
00761
00762
00763 void DrawMolItem::draw_isosurface(int volid, float isovalue, int drawbox, int style, int stepsize, int thickness) {
00764 const VolumetricData * v = NULL;
00765
00766 v = mol->get_volume_data(volid);
00767 if (v == NULL) {
00768 msgInfo << "No volume data loaded at index " << volid << sendmsg;
00769 return;
00770 }
00771
00772 sprintf(commentBuffer, "MoleculeID: %d ReprID: %d Beginning Isosurface",
00773 mol->id(), repNumber);
00774 cmdCommentX.putdata(commentBuffer, cmdList);
00775
00776
00777 if (stepsize >= v->xsize)
00778 stepsize = (v->xsize - 1);
00779 if (stepsize >= v->ysize)
00780 stepsize = (v->ysize - 1);
00781 if (stepsize >= v->zsize)
00782 stepsize = (v->zsize - 1);
00783 if (stepsize < 2)
00784 stepsize = 1;
00785
00786 if (drawbox > 0) {
00787
00788 if (atomColor->method() == AtomColor::VOLUME) {
00789 append(DVOLTEXOFF);
00790 }
00791
00792 if (style > 0 || drawbox == 2) {
00793 draw_volume_box_lines(v);
00794 } else {
00795 draw_volume_box_solid(v);
00796 }
00797 if (atomColor->method() == AtomColor::VOLUME) {
00798 append(DVOLTEXON);
00799 }
00800 }
00801
00802 if ((drawbox == 2) || (drawbox == 0)) {
00803 switch (style) {
00804 case 3:
00805
00806 draw_volume_isosurface_lit_points(v, isovalue, stepsize, thickness);
00807 break;
00808
00809 case 2:
00810
00811 draw_volume_isosurface_points(v, isovalue, stepsize, thickness);
00812 break;
00813
00814 case 1:
00815
00816 draw_volume_isosurface_lines(v, isovalue, stepsize, thickness);
00817 break;
00818
00819 case 0:
00820 default:
00821
00822 draw_volume_isosurface_trimesh(v, isovalue, stepsize);
00823 break;
00824 }
00825 }
00826 }
00827
00828
00829 #if 0
00830
00831 void DrawMolItem::draw_volslice_contour_lines(int volid, float slice, int axis) {
00832 const VolumetricData * v = NULL;
00833
00834 v = mol->get_volume_data(volid);
00835
00836 if (v == NULL) {
00837 msgInfo << "No volume data loaded at index " << volid << sendmsg;
00838 return;
00839 }
00840
00841 msgInfo << "Placeholder for contour slice not implemented yet..."
00842 }
00843 #endif
00844
00845
00846
00847 int DrawMolItem::calcseeds_gradient_magnitude(const VolumetricData * v, ResizeArray<float> *seeds, float seedmin, float seedmax) {
00848 float seedmin2 = seedmin*seedmin;
00849 float seedmax2 = seedmax*seedmax;
00850
00851 int i;
00852 float vorigin[3];
00853 for (i=0; i<3; i++) {
00854 vorigin[i] = float(v->origin[i]);
00855 }
00856
00857
00858 float xax[3], yax[3], zax[3];
00859 v->cell_axes(xax, yax, zax);
00860
00861 int maxseedcount = 50000;
00862 int seedcount = maxseedcount+1;
00863 int stepsize = 1;
00864
00865
00866 while (seedcount > maxseedcount) {
00867 seedcount=0;
00868 seeds->clear();
00869
00870 int x,y,z;
00871 float pos[3];
00872 for (z=0; z<v->zsize && seedcount < maxseedcount; z+=stepsize) {
00873 for (y=0; y<v->ysize; y+=stepsize) {
00874 for (x=0; x<v->xsize; x+=stepsize) {
00875 float grad[3];
00876 float gradmag2;
00877 vec_copy(grad, &v->gradient[(z*v->xsize*v->ysize + y*v->xsize + x) * 3]);
00878 gradmag2 = dot_prod(grad, grad);
00879
00880 if ((gradmag2 <= seedmax2) &&
00881 (gradmag2 >= seedmin2)) {
00882 pos[0] = vorigin[0] + x * xax[0] + y * yax[0] + z * zax[0];
00883 pos[1] = vorigin[1] + x * xax[1] + y * yax[1] + z * zax[1];
00884 pos[2] = vorigin[2] + x * xax[2] + y * yax[2] + z * zax[2];
00885
00886 seedcount++;
00887 seeds->append(pos[0]);
00888 seeds->append(pos[1]);
00889 seeds->append(pos[2]);
00890 }
00891 }
00892 }
00893 }
00894 stepsize++;
00895 }
00896
00897 return seedcount;
00898 }
00899
00900
00901
00902 void DrawMolItem::draw_volume_field_lines(int volid, float seedval, float minlen, float maxlen, float thickness) {
00903 const VolumetricData * v = NULL;
00904 v = mol->get_volume_data(volid);
00905 int printdonemesg=0;
00906
00907 if (v == NULL) {
00908 msgInfo << "No volume data loaded at index " << volid << sendmsg;
00909 return;
00910 }
00911
00912 int seedcount = 0;
00913 int pointcount = 0;
00914 int totalpointcount = 0;
00915 int usecolor;
00916 ResizeArray<float> seeds;
00917
00918 append(DMATERIALOFF);
00919 usecolor = draw_volume_get_colorid();
00920 cmdColorIndex.putdata(usecolor, cmdList);
00921
00922 seedcount = calcseeds_gradient_magnitude(v, &seeds, seedval*0.5f, seedval*1.5f);
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935 float lx, ly, lz;
00936 v->cell_lengths(&lx, &ly, &lz);
00937 float mincelllen=lx;
00938 mincelllen = (mincelllen < ly) ? mincelllen : ly;
00939 mincelllen = (mincelllen < lz) ? mincelllen : lz;
00940 float delta=mincelllen * 0.25f;
00941
00942
00943
00944 float mingmag = 0.0001f;
00945
00946
00947 float maxgmag = 5;
00948
00949 ResizeArray<float> points;
00950
00951
00952
00953
00954 wkfmsgtimer *msgt = wkf_msg_timer_create(1);
00955 int seed;
00956 for (seed=0; seed < seedcount; seed++) {
00957
00958 if (!(seed & 7) && wkf_msg_timer_timeout(msgt)) {
00959 char tmpbuf[128];
00960 sprintf(tmpbuf, "%6.2f %% complete", (100.0f * seed) / (float) seedcount);
00961 msgInfo << "integrating " << seedcount << " field lines: " << tmpbuf << sendmsg;
00962 printdonemesg=1;
00963 }
00964
00965 int direction;
00966 for (direction=-1; direction != 1; direction=1) {
00967 float pos[3], comsum[3];
00968 vec_copy(pos, &seeds[seed*3]);
00969
00970
00971 points.clear();
00972
00973
00974 pointcount=0;
00975 totalpointcount++;
00976 float len=0;
00977 int iterations=0;
00978 float dir = (float) direction;
00979
00980 vec_zero(comsum);
00981
00982 while ((len<maxlen) && (totalpointcount < 100000000)) {
00983 float grad[3];
00984
00985
00986 v->voxel_gradient_interpolate_from_coord(pos, grad);
00987
00988
00989
00990
00991 float gmag = norm(grad);
00992 if (gmag < mingmag || gmag > maxgmag)
00993 break;
00994
00995
00996
00997
00998
00999
01000
01001
01002 if (!(iterations & 1)) {
01003
01004 points.append(pos[0]);
01005 points.append(pos[1]);
01006 points.append(pos[2]);
01007
01008 vec_incr(comsum, pos);
01009
01010 pointcount++;
01011 totalpointcount++;
01012 }
01013
01014
01015
01016
01017 vec_scaled_add(pos, dir * delta / gmag, grad);
01018 len += delta;
01019
01020 iterations++;
01021 }
01022
01023 int drawfieldline = 1;
01024
01025
01026
01027
01028 if (pointcount < 2 || len < minlen)
01029 drawfieldline = 0;
01030
01031
01032 if (drawfieldline) {
01033 float com[3];
01034 vec_scale(com, 1.0f / (float) pointcount, comsum);
01035 float minlen2 = minlen*minlen;
01036
01037 drawfieldline = 0;
01038 int p;
01039 for (p=0; p<pointcount; p++) {
01040 if ((2.0f * distance2(com, &points[p*3])) > minlen2) {
01041 drawfieldline = 1;
01042 break;
01043 }
01044 }
01045 }
01046
01047
01048 if (drawfieldline) {
01049 cmdLineType.putdata(SOLIDLINE, cmdList);
01050 cmdLineWidth.putdata((int) thickness, cmdList);
01051 cmdColorIndex.putdata(usecolor, cmdList);
01052 DispCmdPolyLineArray cmdPolyLineArray;
01053 cmdPolyLineArray.putdata(&points[0], pointcount, cmdList);
01054 }
01055 }
01056 }
01057 wkf_msg_timer_destroy(msgt);
01058
01059 if (printdonemesg)
01060 msgInfo << "field line integration complete." << sendmsg;
01061 }
01062
01063