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