00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdio.h>
00024 #include "MoleculeGraphics.h"
00025 #include "DispCmds.h"
00026 #include "VMDApp.h"
00027 #include "Inform.h"
00028 #include "JString.h"
00029 #include "Scene.h"
00030 #include "utilities.h"
00031
00032 void MoleculeGraphics::create_cmdlist(void) {
00033 reset_disp_list();
00034
00035 DispCmdTriangle triangle;
00036 DispCmdCylinder cylinder;
00037 DispCmdPoint point;
00038 DispCmdLine line;
00039 DispCmdCone cone;
00040 DispCmdColorIndex color;
00041 DispCmdLineType linetype;
00042 DispCmdLineWidth linewidth;
00043 DispCmdSphere sphere;
00044 DispCmdSphereRes sph_res;
00045
00046
00047 append(DMATERIALON);
00048 color.putdata(0, cmdList);
00049 int last_res = -1;
00050
00051 int last_line = ::SOLIDLINE;
00052 linetype.putdata(last_line, cmdList);
00053 int last_width = 1;
00054 linewidth.putdata(last_width, cmdList);
00055
00056 ResizeArray<float> pickpointcoords;
00057 ResizeArray<int> pickpointindices;
00058
00059
00060 int num = num_elements();
00061 ShapeClass *shape;
00062 int sidx=0;
00063 while (sidx<num) {
00064 shape = &(shapes[sidx]);
00065
00066 switch (shape->shape) {
00067 case NONE: {
00068 break;
00069 }
00070
00071 case POINT: {
00072 append(DMATERIALOFF);
00073 point.putdata(shape->data+0, cmdList);
00074 append(DMATERIALON);
00075 break;
00076 }
00077
00078 case PICKPOINT:
00079 pickpointcoords.append3(shape->data);
00080 pickpointindices.append((int)shape->data[3]);
00081 break;
00082
00083 case LINE: {
00084 append(DMATERIALOFF);
00085 int style = int(shape->data[6]);
00086 int width = int(shape->data[7]);
00087 if (style != last_line) {
00088 linetype.putdata(style, cmdList);
00089 last_line = style;
00090 }
00091 if (width != last_width) {
00092 linewidth.putdata(width, cmdList);
00093 last_width = width;
00094 }
00095 line.putdata(shape->data+0, shape->data+3, cmdList);
00096 append(DMATERIALON);
00097 break;
00098 }
00099
00100 case TRIANGLE: {
00101 ResizeArray<float> triangle_vert_buffer;
00102 int tricount=0;
00103 while ((sidx<num) && (tricount < 50000000) && (shape->shape == TRIANGLE)) {
00104 triangle_vert_buffer.append9(&shape->data[0]);
00105 tricount++;
00106 sidx++;
00107 shape = &(shapes[sidx]);
00108 }
00109 sidx--;
00110
00111 int cnt = triangle_vert_buffer.num() / 9;
00112 if (cnt > 0) {
00113 DispCmdTriMesh::putdata(&triangle_vert_buffer[0], (float *) NULL,
00114 (float *) NULL, cnt, cmdList);
00115 }
00116 break;
00117 }
00118
00119 case TRINORM: {
00120 triangle.putdata(shape->data+0, shape->data+3 , shape->data+6,
00121 shape->data+9, shape->data+12, shape->data+15, cmdList);
00122 break;
00123 }
00124
00125 case TRICOLOR: {
00126
00127 float colors[9];
00128 for (int i=0; i<3; i++) {
00129 int c = (int)shape->data[18+i];
00130 c = clamp_int(c, 0, MAXCOLORS-1);
00131 vec_copy(colors+3L*i, scene->color_value(c));
00132 }
00133 const float *verts = shape->data+0;
00134 const float *norms = shape->data+9;
00135 int facets[3] = { 0,1,2 };
00136 DispCmdTriMesh::putdata(verts, norms, colors, 3, facets, 1, 0, cmdList);
00137 }
00138 break;
00139
00140 case CYLINDER: {
00141 cylinder.putdata(shape->data+0, shape->data+3, shape->data[6],
00142 int(shape->data[7]),
00143 (int (shape->data[8])) ?
00144 CYLINDER_TRAILINGCAP | CYLINDER_LEADINGCAP : 0,
00145 cmdList);
00146 break;
00147 }
00148
00149 case CONE: {
00150 cone.putdata(shape->data+0, shape->data+3, shape->data[6],
00151 shape->data[8], int(shape->data[7]), cmdList);
00152 break;
00153 }
00154
00155 case TEXT: {
00156 append(DMATERIALOFF);
00157 DispCmdText text;
00158 text.putdata(shape->data, shapetext[(int)shape->data[5]], shape->data[4], shape->data[3], 0, 0, cmdList);
00159 append(DMATERIALON);
00160 break;
00161 }
00162
00163 case SPHERETUBE: {
00164 if (!shape->extradata)
00165 break;
00166
00167 const int numcoords = int(shape->data[0]);
00168 const int numradii = int(shape->data[1]);
00169 const float defradius = shape->data[2];
00170
00171 const int drawtubes = int(shape->data[4]);
00172 const int res = int(shape->data[5]);
00173
00174 #if 0
00175 printf("***** spheretube draw: coords %d rads %d defrad %f cols %d tubes %d res %d\n",
00176 numcoords, numradii, defradius, numcolors, drawtubes, res);
00177 #endif
00178
00179 const int coordsz = numcoords * 3;
00180 const int colorsz = numcoords * 3;
00181 const float *xyz3fv = (float *) shape->extradata;
00182 const float *rgb3fv = xyz3fv + coordsz;
00183 const float *radii1fv = xyz3fv + coordsz + colorsz;
00184
00185
00186
00187 float *colors = NULL;
00188 float *tmpradii = NULL;
00189 const float *useradii = NULL;
00190 if ((numradii > 1) && (numradii == numcoords)) {
00191 useradii = radii1fv;
00192
00193 } else {
00194
00195 tmpradii = new float[numradii];
00196 for (int i=0; i<numcoords; i++) {
00197 tmpradii[i] = defradius;
00198 }
00199 useradii = tmpradii;
00200
00201 }
00202
00203 DispCmdSphereArray cmdSphereArray;
00204 cmdSphereArray.putdata(xyz3fv,
00205 useradii,
00206 rgb3fv,
00207 numcoords,
00208 res,
00209 cmdList);
00210
00211
00212 if (drawtubes) {
00213
00214 int i,j;
00215 for (i=0,j=0; i<(numcoords-1); i++,j+=3) {
00216
00217 cone.putdata(xyz3fv+j, xyz3fv+j+3,
00218 useradii[i], useradii[i+1], res, cmdList);
00219 }
00220 }
00221
00222 delete [] tmpradii;
00223 delete [] colors;
00224 break;
00225 }
00226
00227
00228 #if 0
00229
00230 case DBEGINREPGEOMGROUP: {
00231 char *s = (char *) (shape);
00232 beginrepgeomgroup.putdata(s,cmdList);
00233 break;
00234 }
00235
00236 case DCOMMENT: {
00237 char *s = (char *) (shape);
00238 comment.putdata(s,cmdList);
00239 break;
00240 }
00241 #endif
00242
00243 case SPHERE: {
00244 int res = int (shape->data[4]);
00245 if (res != last_res) {
00246 sph_res.putdata(res, cmdList);
00247 last_res = res;
00248 }
00249 sphere.putdata(shape->data+0, shape->data[3], cmdList);
00250 break;
00251 }
00252
00253 case MATERIALS: {
00254 if (shape->data[0] == 0) append(DMATERIALOFF);
00255 else append(DMATERIALON);
00256 break;
00257 }
00258
00259 case MATERIAL: {
00260 const float *data = shape->data;
00261 cmdList->ambient = data[0];
00262 cmdList->specular = data[1];
00263 cmdList->diffuse = data[2];
00264 cmdList->shininess = data[3];
00265 cmdList->mirror = data[4];
00266 cmdList->opacity = data[5];
00267 cmdList->outline = data[6];
00268 cmdList->outlinewidth = data[7];
00269 cmdList->transmode = data[8];
00270 cmdList->materialtag = (int)data[9];
00271 break;
00272 }
00273
00274 case COLOR: {
00275 color.putdata(int(shape->data[0]), cmdList);
00276 break;
00277 }
00278
00279 default:
00280 msgErr << "Sorry, can't draw that" << sendmsg;
00281 }
00282
00283 sidx++;
00284 }
00285
00286
00287 if (pickpointindices.num() > 0) {
00288 DispCmdPickPointArray pickPointArray;
00289 pickPointArray.putdata(pickpointindices.num(), &pickpointindices[0],
00290 &pickpointcoords[0], cmdList);
00291 }
00292
00293 needRegenerate = 0;
00294 }
00295
00296
00297
00298
00299 int MoleculeGraphics::added(void) {
00300 needRegenerate = 1;
00301 next_index = shapes.num();
00302 int retval = next_id;
00303 if (next_id == max_id) {
00304 max_id++;
00305 }
00306 next_id = max_id;
00307 return retval;
00308 }
00309
00310
00311 int MoleculeGraphics::add_triangle(const float *x1, const float *x2, const float *x3) {
00312
00313 ShapeClass s(TRIANGLE, 9, next_id);
00314 float *data = s.data;
00315 vec_copy(data+0, x1);
00316 vec_copy(data+3, x2);
00317 vec_copy(data+6, x3);
00318
00319
00320 if (next_index < num_elements())
00321 shapes[next_index] = s;
00322 else
00323 shapes.append(s);
00324 return added();
00325 }
00326
00327
00328 int MoleculeGraphics::add_trinorm(const float *x1, const float *x2, const float *x3,
00329 const float *n1, const float *n2, const float *n3) {
00330
00331 ShapeClass s(TRINORM, 18, next_id);
00332 float *data = s.data;
00333 vec_copy(data+ 0, x1);
00334 vec_copy(data+ 3, x2);
00335 vec_copy(data+ 6, x3);
00336
00337 vec_copy(data+ 9, n1);
00338 vec_normalize(data+ 9);
00339 vec_copy(data+12, n2);
00340 vec_normalize(data+12);
00341 vec_copy(data+15, n3);
00342 vec_normalize(data+15);
00343
00344
00345 if (next_index < num_elements())
00346 shapes[next_index] = s;
00347 else
00348 shapes.append(s);
00349
00350 return added();
00351 }
00352
00353
00354 int MoleculeGraphics::add_tricolor(const float *x1, const float *x2, const float *x3,
00355 const float *n1, const float *n2, const float *n3, int c1, int c2,
00356 int c3) {
00357 ShapeClass s(TRICOLOR, 21, next_id);
00358 float *data = s.data;
00359 vec_copy(data+ 0, x1);
00360 vec_copy(data+ 3, x2);
00361 vec_copy(data+ 6, x3);
00362
00363 vec_copy(data+ 9, n1);
00364 vec_normalize(data+ 9);
00365 vec_copy(data+12, n2);
00366 vec_normalize(data+12);
00367 vec_copy(data+15, n3);
00368 vec_normalize(data+15);
00369
00370 data[18] = (float)c1;
00371 data[19] = (float)c2;
00372 data[20] = (float)c3;
00373
00374
00375 if (next_index < num_elements())
00376 shapes[next_index] = s;
00377 else
00378 shapes.append(s);
00379
00380 return added();
00381 }
00382
00383
00384 int MoleculeGraphics::add_point(const float *x) {
00385 ShapeClass s(POINT, 3, next_id);
00386 float *data = s.data;
00387 vec_copy(data+0, x);
00388
00389 if (next_index < num_elements())
00390 shapes[next_index] = s;
00391 else
00392 shapes.append(s);
00393
00394 return added();
00395 }
00396
00397 int MoleculeGraphics::add_pickpoint(const float *x) {
00398 ShapeClass s(PICKPOINT, 4, next_id);
00399 float *data = s.data;
00400 vec_copy(data+0, x);
00401 data[3] = (float) next_index;
00402
00403 if (next_index < num_elements())
00404 shapes[next_index] = s;
00405 else
00406 shapes.append(s);
00407
00408 return added();
00409 }
00410
00411 int MoleculeGraphics::add_line(const float *x1, const float *x2, int style, int width) {
00412 ShapeClass s(LINE, 8, next_id);
00413 float *data = s.data;
00414 vec_copy(data+0, x1);
00415 vec_copy(data+3, x2);
00416 data[6] = float(style) + 0.1f;
00417 data[7] = float(width) + 0.1f;
00418 if (next_index < num_elements())
00419 shapes[next_index] = s;
00420 else
00421 shapes.append(s);
00422 return added();
00423 }
00424
00425
00426 int MoleculeGraphics::add_cylinder(const float *x1, const float *x2, float rad,
00427 int n, int filled) {
00428 ShapeClass s(CYLINDER, 9, next_id);
00429 float *data = s.data;
00430 vec_copy(data+0, x1);
00431 vec_copy(data+3, x2);
00432 data[6] = rad;
00433 data[7] = float(n) + 0.1f;
00434 data[8] = float(filled) + 0.1f;
00435
00436
00437 if (next_index < num_elements())
00438 shapes[next_index] = s;
00439 else
00440 shapes.append(s);
00441 return added();
00442 }
00443
00444
00445 int MoleculeGraphics::add_cone(const float *x1, const float *x2, float rad, float radsq, int n) {
00446
00447 ShapeClass s(CONE, 9, next_id);
00448 float *data = s.data;
00449 vec_copy(data+0, x1);
00450 vec_copy(data+3, x2);
00451 data[6] = rad;
00452 data[7] = float(n) + 0.1f;
00453 data[8] = radsq;
00454
00455
00456 if (next_index < num_elements())
00457 shapes[next_index] = s;
00458 else
00459 shapes.append(s);
00460 return added();
00461 }
00462
00463
00464 int MoleculeGraphics::add_sphere(const float *x, float rad, int n) {
00465 ShapeClass s(SPHERE, 5, next_id);
00466 float *data = s.data;
00467 vec_copy(data+0, x);
00468 data[3] = rad;
00469 data[4] = float(n) + 0.1f;
00470
00471
00472 if (next_index < num_elements())
00473 shapes[next_index] = s;
00474 else
00475 shapes.append(s);
00476 return added();
00477 }
00478
00479
00480 int MoleculeGraphics::add_text(const float *x, const char *text,
00481 float size, float thickness) {
00482 ShapeClass s(TEXT, 6, next_id);
00483 float *data = s.data;
00484 vec_copy(data+0, x);
00485 data[3] = size;
00486 data[4] = thickness;
00487 data[5] = (float)shapetext.num();
00488 shapetext.append(stringdup(text));
00489 if (next_index < num_elements())
00490 shapes[next_index] = s;
00491 else
00492 shapes.append(s);
00493 return added();
00494 }
00495
00496
00497 int MoleculeGraphics::add_spheretube(const int numcoords, const float *xyz3fv,
00498 const int numradii, const float *radii1fv,
00499 const int numcolors,
00500 const float *rgb3fv, const int *colorids,
00501 int drawtubes, int res) {
00502 ShapeClass s(SPHERETUBE, 6, next_id);
00503 float *data = s.data;
00504 data[0] = float(numcoords);
00505 data[1] = float(numradii);
00506 data[2] = radii1fv[0];
00507 data[3] = float(numcolors);
00508 data[4] = float(drawtubes);
00509 data[5] = float(res);
00510
00511
00512 const int coordsz = numcoords * 3;
00513 const int colorsz = numcoords * 3;
00514 float *tmp = (float *) malloc((coordsz + colorsz + numradii) * sizeof(float));
00515 memcpy(tmp, xyz3fv, coordsz * sizeof(float));
00516
00517
00518 if (numcolors < numcoords) {
00519
00520 const float *tc = scene->color_value(colorID);
00521 for (int i=0; i<colorsz; i+=3) {
00522 vec_copy(tmp+coordsz + i, tc);
00523 }
00524 } else {
00525 if (rgb3fv != NULL) {
00526 memcpy(tmp+coordsz, rgb3fv, colorsz * sizeof(float));
00527 } if (colorids != NULL) {
00528 for (int i=0; i<numcolors; i++) {
00529 int c = colorids[i];
00530 c = clamp_int(c, 0, MAXCOLORS-1);
00531 vec_copy(tmp+coordsz + i*3, scene->color_value(c));
00532 }
00533 }
00534 }
00535
00536 memcpy(tmp+coordsz+colorsz, radii1fv, numradii * sizeof(float));
00537 s.extradata = tmp;
00538
00539
00540 if (next_index < num_elements())
00541 shapes[next_index] = s;
00542 else
00543 shapes.append(s);
00544 return added();
00545 }
00546
00547
00548 int MoleculeGraphics::use_materials(int yes_no) {
00549 ShapeClass s(MATERIALS, 1, next_id);
00550 float *data = s.data;
00551 data[0] = (float) yes_no;
00552 if (next_index < num_elements())
00553 shapes[next_index] = s;
00554 else
00555 shapes.append(s);
00556 return added();
00557 }
00558
00559
00560 int MoleculeGraphics::use_material(const Material *mat) {
00561 ShapeClass s(MATERIAL, 10, next_id);
00562 float *data = s.data;
00563 data[0] = mat->ambient;
00564 data[1] = mat->specular;
00565 data[2] = mat->diffuse;
00566 data[3] = mat->shininess;
00567 data[4] = mat->mirror;
00568 data[5] = mat->opacity;
00569 data[6] = mat->outline;
00570 data[7] = mat->outlinewidth;
00571 data[8] = mat->transmode;
00572 data[9] = (float)mat->ind;
00573
00574 if (next_index < num_elements())
00575 shapes[next_index] = s;
00576 else
00577 shapes.append(s);
00578 return added();
00579 }
00580
00581
00582
00583 int MoleculeGraphics::use_color(int index) {
00584 colorID = index;
00585
00586 ShapeClass s(COLOR, 1, next_id);
00587 float *data = s.data;
00588 data[0] = float(index) + 0.1f;
00589 if (next_index < num_elements())
00590 shapes[next_index] = s;
00591 else
00592 shapes.append(s);
00593 return added();
00594 }
00595
00596
00597
00598 int MoleculeGraphics::index_id(int find_id) {
00599
00600
00601 int max_loc = num_elements()-1;
00602 int min_loc = 0;
00603 if (max_loc < min_loc) {
00604 return -1;
00605 }
00606 int loc = (max_loc + min_loc) / 2;
00607 int id = shapes[loc].id;
00608 while (id != find_id && min_loc < max_loc) {
00609 if (id < find_id) {
00610 min_loc = loc+1;
00611 } else {
00612 max_loc = loc-1;
00613 }
00614 loc = (max_loc + min_loc) / 2;
00615 if (loc < 0) break;
00616 id = shapes[loc].id;
00617 }
00618
00619 if (id == find_id && shapes[loc].shape != NONE) {
00620 return loc;
00621 }
00622 return -1;
00623 }
00624
00625
00626
00627 void MoleculeGraphics::delete_all(void) {
00628 shapes.clear();
00629 delete_shapetext();
00630 delete_count = 0;
00631 next_index = 0;
00632 next_id = 0;
00633 max_id = 0;
00634 needRegenerate = 1;
00635 }
00636
00637
00638
00639 void MoleculeGraphics::delete_id(int id) {
00640 int index = index_id(id);
00641 if (index < 0) return;
00642 shapes[index].clear();
00643 delete_count++;
00644 if (delete_count > 1
00645 ) {
00646
00647 int i, j=0, n = num_elements();
00648
00649 for (i=0; i<n; i++) {
00650 if (shapes[i].shape != NONE) {
00651 if (i != j) {
00652 shapes[j] = shapes[i];
00653 }
00654 j++;
00655 }
00656 }
00657 i=j;
00658 while (i<n) {
00659 shapes[i].clear();
00660 i++;
00661 }
00662
00663 for (int k=n-1; k >= j; k--) shapes.remove(k);
00664 delete_count = 0;
00665 }
00666 needRegenerate = 1;
00667
00668 next_id = max_id;
00669 next_index = num_elements();
00670 }
00671
00672
00673
00674
00675 int MoleculeGraphics::replace_id(int id) {
00676 int index = index_id(id);
00677 if (index < 0) return -1;
00678
00679
00680 if (next_id != max_id) {
00681 delete_count++;
00682 }
00683
00684 shapes[index].clear();
00685 next_id = id;
00686 next_index = index;
00687 return index;
00688 }
00689
00690
00691 const char *MoleculeGraphics::info_id(int id) {
00692 int index = index_id(id);
00693 if (index < 0) return NULL;
00694 ShapeClass *shape;
00695 shape = &(shapes[index]);
00696
00697 if (graphics_info_xl != NULL)
00698 delete graphics_info_xl;
00699
00700 switch (shape->shape) {
00701 case NONE: {
00702 graphics_info[0] = '\0';
00703 return graphics_info;
00704 }
00705 case POINT: {
00706 sprintf(graphics_info, "point {%f %f %f}",
00707 shape->data[0], shape->data[1], shape->data[2]);
00708 return graphics_info;
00709 }
00710 case PICKPOINT: {
00711 sprintf(graphics_info, "pickpoint {%f %f %f} %d",
00712 shape->data[0], shape->data[1], shape->data[2], (int)shape->data[3]);
00713 return graphics_info;
00714 }
00715 case LINE: {
00716 sprintf(graphics_info, "line {%f %f %f} {%f %f %f} style %s width %d",
00717 shape->data[0], shape->data[1], shape->data[2],
00718 shape->data[3], shape->data[4], shape->data[5],
00719 shape->data[6] < 0.5 ? "solid" : "dashed",
00720 int(shape->data[7]));
00721 return graphics_info;
00722 }
00723 case TRIANGLE: {
00724 sprintf(graphics_info, "triangle {%f %f %f} {%f %f %f} {%f %f %f}",
00725 shape->data[0], shape->data[1], shape->data[2],
00726 shape->data[3], shape->data[4], shape->data[5],
00727 shape->data[6], shape->data[7], shape->data[8]);
00728 return graphics_info;
00729 }
00730 case TRINORM: {
00731 sprintf(graphics_info, "trinorm {%f %f %f} {%f %f %f} {%f %f %f} "
00732 "{%f %f %f} {%f %f %f} {%f %f %f}",
00733 shape->data[0], shape->data[1], shape->data[2],
00734 shape->data[3], shape->data[4], shape->data[5],
00735 shape->data[6], shape->data[7], shape->data[8],
00736 shape->data[9], shape->data[10], shape->data[11],
00737 shape->data[12], shape->data[13], shape->data[14],
00738 shape->data[15], shape->data[16], shape->data[17]);
00739 return graphics_info;
00740 }
00741 case TRICOLOR: {
00742 sprintf(graphics_info, "tricolor {%f %f %f} {%f %f %f} {%f %f %f} "
00743 "{%f %f %f} {%f %f %f} {%f %f %f} %d %d %d",
00744 shape->data[0], shape->data[1], shape->data[2],
00745 shape->data[3], shape->data[4], shape->data[5],
00746 shape->data[6], shape->data[7], shape->data[8],
00747 shape->data[9], shape->data[10], shape->data[11],
00748 shape->data[12], shape->data[13], shape->data[14],
00749 shape->data[15], shape->data[16], shape->data[17],
00750 (int)shape->data[18], (int)shape->data[19], (int)shape->data[20]);
00751 return graphics_info;
00752 }
00753 case CYLINDER: {
00754 sprintf(graphics_info, "cylinder {%f %f %f} {%f %f %f} "
00755 "radius %f resolution %d filled %d",
00756 shape->data[0], shape->data[1], shape->data[2],
00757 shape->data[3], shape->data[4], shape->data[5],
00758 shape->data[6], int(shape->data[7]), int(shape->data[8]));
00759 return graphics_info;
00760 }
00761 case CONE: {
00762 sprintf(graphics_info, "cone {%f %f %f} {%f %f %f} "
00763 "radius %f radius2 %f resolution %d",
00764 shape->data[0], shape->data[1], shape->data[2],
00765 shape->data[3], shape->data[4], shape->data[5],
00766 shape->data[6], shape->data[8], int(shape->data[7]));
00767 return graphics_info;
00768 }
00769 case SPHERE: {
00770 sprintf(graphics_info, "sphere {%f %f %f} radius %f resolution %d",
00771 shape->data[0], shape->data[1], shape->data[2],
00772 shape->data[3], int(shape->data[4]));
00773 return graphics_info;
00774 }
00775 case TEXT: {
00776 sprintf(graphics_info, "text {%f %f %f} {%s} size %f thickness %f",
00777 shape->data[0], shape->data[1], shape->data[2],
00778 shapetext[(int)shape->data[5]], shape->data[3], shape->data[4]);
00779 return graphics_info;
00780 }
00781 case SPHERETUBE: {
00782 const int numcoords = int(shape->data[0]);
00783 const int numradii = int(shape->data[1]);
00784 const float defradius = shape->data[2];
00785
00786 const int drawtubes = int(shape->data[4]);
00787 const int res = int(shape->data[5]);
00788 const int coordsz = numcoords * 3;
00789 const int colorsz = numcoords * 3;
00790 const float *xyz3fv = (float *) shape->extradata;
00791 const float *rgb3fv = xyz3fv + coordsz;
00792 const float *radii1fv = xyz3fv + coordsz + colorsz;
00793 int i;
00794
00795 graphics_info_xl = new JString("spheretube {");
00796 for (i=0; i<coordsz; i+=3) {
00797 sprintf(graphics_info, "{%g %g %g} ", xyz3fv[i], xyz3fv[i+1], xyz3fv[i+2]);
00798 *graphics_info_xl += (const char *) graphics_info;
00799 }
00800 *graphics_info_xl += "} ";
00801
00802 if (numradii > 1) {
00803 *graphics_info_xl += "radii {";
00804 for (i=0; i<numcoords; i++) {
00805 sprintf(graphics_info, "%g ", radii1fv[i]);
00806 *graphics_info_xl += (const char *) graphics_info;
00807 }
00808 *graphics_info_xl += "} ";
00809 } else {
00810 sprintf(graphics_info, "radius %g ", defradius);
00811 *graphics_info_xl += "} ";
00812 }
00813
00814
00815
00816
00817 *graphics_info_xl += "colors {";
00818 for (i=0; i<colorsz; i+=3) {
00819 sprintf(graphics_info, "{%g %g %g} ", rgb3fv[i], rgb3fv[i+1], rgb3fv[i+2]);
00820 *graphics_info_xl += (const char *) graphics_info;
00821 }
00822 *graphics_info_xl += "} ";
00823
00824 if (drawtubes) {
00825 *graphics_info_xl += "drawtubes 1 ";
00826 }
00827
00828 sprintf(graphics_info, "resolution %d ", res);
00829 *graphics_info_xl += (const char *) graphics_info;
00830 return ((const char *) *graphics_info_xl);
00831 }
00832 case MATERIALS: {
00833 sprintf(graphics_info, "materials %d", int(shape->data[0]));
00834 return graphics_info;
00835 }
00836 case MATERIAL: {
00837 sprintf(graphics_info, "material %d", int(shape->data[9]));
00838 return graphics_info;
00839 }
00840 case COLOR: {
00841 sprintf(graphics_info, "color %d", int(shape->data[0]));
00842 return graphics_info;
00843 }
00844 default:
00845 return "";
00846 }
00847 }
00848
00849
00850
00851 #define CHECK_RANGE(v) \
00852 { \
00853 if (!found_one) { \
00854 found_one = 1; \
00855 minx = maxx = (v)[0]; \
00856 miny = maxy = (v)[1]; \
00857 minz = maxz = (v)[2]; \
00858 } else { \
00859 if (minx > (v)[0]) minx = (v)[0]; if (maxx < (v)[0]) maxx = (v)[0]; \
00860 if (miny > (v)[1]) miny = (v)[1]; if (maxy < (v)[1]) maxy = (v)[1]; \
00861 if (minz > (v)[2]) minz = (v)[2]; if (maxz < (v)[2]) maxz = (v)[2]; \
00862 } \
00863 }
00864
00865
00866 void MoleculeGraphics::find_bounds(void) {
00867 float minx=0.0f, maxx=0.0f;
00868 float miny=0.0f, maxy=0.0f;
00869 float minz=0.0f, maxz=0.0f;
00870 int found_one = 0;
00871
00872 int num = num_elements();
00873 ShapeClass *shape;
00874 for (int i=0; i<num; i++) {
00875 shape = &(shapes[i]);
00876 switch (shape->shape) {
00877 case NONE: {
00878 break;
00879 }
00880 case POINT: {
00881 CHECK_RANGE(shape->data+0);
00882 break;
00883 }
00884 case PICKPOINT: {
00885 CHECK_RANGE(shape->data+0);
00886 break;
00887 }
00888 case LINE: {
00889 CHECK_RANGE(shape->data+0);
00890 CHECK_RANGE(shape->data+3);
00891 break;
00892 }
00893 case TRIANGLE: {
00894 CHECK_RANGE(shape->data+0);
00895 CHECK_RANGE(shape->data+3);
00896 CHECK_RANGE(shape->data+6);
00897 break;
00898 }
00899 case TRINORM: {
00900 CHECK_RANGE(shape->data+0);
00901 CHECK_RANGE(shape->data+3);
00902 CHECK_RANGE(shape->data+6);
00903 break;
00904 }
00905 case TRICOLOR: {
00906 CHECK_RANGE(shape->data+0);
00907 CHECK_RANGE(shape->data+3);
00908 CHECK_RANGE(shape->data+6);
00909 break;
00910 }
00911 case CYLINDER: {
00912 CHECK_RANGE(shape->data+0);
00913 CHECK_RANGE(shape->data+3);
00914 break;
00915 }
00916 case CONE: {
00917 CHECK_RANGE(shape->data+0);
00918 CHECK_RANGE(shape->data+3);
00919 break;
00920 }
00921 case SPHERE: {
00922 CHECK_RANGE(shape->data+0);
00923 break;
00924 }
00925 case TEXT: {
00926 CHECK_RANGE(shape->data+0);
00927 break;
00928 }
00929 case SPHERETUBE: {
00930 int numcoords = int(shape->data[0]);
00931 float lmin[3], lmax[3];
00932 const float *coords = (const float *) shape->extradata;
00933 minmax_3fv_aligned(coords, numcoords, lmin, lmax);
00934 minx = lmin[0];
00935 miny = lmin[1];
00936 minz = lmin[2];
00937 maxx = lmax[0];
00938 maxy = lmax[1];
00939 maxz = lmax[2];
00940 break;
00941 }
00942 default:
00943 break;
00944 }
00945 }
00946
00947
00948 if (!found_one) {
00949 cov_pos[0] = cov_pos[1] = cov_pos[2];
00950 cov_scale = 0.1f;
00951 } else {
00952 cov_pos[0] = (minx + maxx) / 2.0f;
00953 cov_pos[1] = (miny + maxy) / 2.0f;
00954 cov_pos[2] = (minz + maxz) / 2.0f;
00955 float dx = maxx - minx;
00956 float dy = maxy - miny;
00957 float dz = maxz - minz;
00958
00959 if (dx == 0 && dy == 0 && dz == 0) dx = 10;
00960 if (dx > dy) {
00961 if (dx > dz) {
00962 cov_scale = 2.0f / dx;
00963 } else {
00964 cov_scale = 2.0f / dz;
00965 }
00966 } else {
00967 if (dy > dz) {
00968 cov_scale = 2.0f / dy;
00969 } else {
00970 cov_scale = 2.0f / dz;
00971 }
00972 }
00973 }
00974 }
00975
00976
00977 void MoleculeGraphics::delete_shapetext() {
00978 for (int i=0; i<shapetext.num(); i++)
00979 delete [] shapetext[i];
00980
00981 shapetext.clear();
00982 }
00983