Main Page Namespace List Class Hierarchy Alphabetical List Compound List File List Namespace Members Compound Members File Members Related Pages

MoleculeGraphics.C

Go to the documentation of this file.
00001 /***************************************************************************
00002 *cr 
00003 *cr (C) Copyright 1995-2019 The Board of Trustees of the 
00004 *cr University of Illinois 
00005 *cr All Rights Reserved 
00006 *cr 
00007 ***************************************************************************/
00008 
00009 /***************************************************************************
00010 * RCS INFORMATION:
00011 *
00012 * $RCSfile: MoleculeGraphics.C,v $
00013 * $Author: johns $ $Locker: $ $State: Exp $
00014 * $Revision: 1.89 $ $Date: 2021年12月21日 05:59:15 $
00015 *
00016 ***************************************************************************
00017 * DESCRIPTION:
00018 * Manages a list of graphics objects. They can be queried and modified.
00019 * This is for use by the text interface (and perhaps others).
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 // set the default values
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 //DispCmdComment comment;
00046 
00047 append(DMATERIALON);
00048 color.putdata(0, cmdList); // use the first color by default (blue)
00049 int last_res = -1; // default sphere resolution
00050 
00051 int last_line = ::SOLIDLINE; // default for lines
00052 linetype.putdata(last_line, cmdList); // solid and
00053 int last_width = 1;
00054 linewidth.putdata(last_width, cmdList); // of width 1
00055 
00056 ResizeArray<float> pickpointcoords;
00057 ResizeArray<int> pickpointindices;
00058 
00059 // go down the list and draw things
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++; // go to the next shape/object
00107 shape = &(shapes[sidx]);
00108 }
00109 sidx--; // correct count prior to outer loop increment
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 // compute rgb colors from indices
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 // const int numcolors = shape->data[3]);
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; // we MUST provide per-sphere colors
00181 const float *xyz3fv = (float *) shape->extradata;
00182 const float *rgb3fv = xyz3fv + coordsz;
00183 const float *radii1fv = xyz3fv + coordsz + colorsz;
00184 
00185 // use either a constant color for all spheres, or use a 
00186 // color-per-sphere 
00187 float *colors = NULL;
00188 float *tmpradii = NULL; 
00189 const float *useradii = NULL;
00190 if ((numradii > 1) && (numradii == numcoords)) {
00191 useradii = radii1fv;
00192 // printf("** using radii array radii[0] = %g\n", useradii[0]);
00193 } else {
00194 // printf("** defradius: %f\n", defradius);
00195 tmpradii = new float[numradii];
00196 for (int i=0; i<numcoords; i++) {
00197 tmpradii[i] = defradius;
00198 }
00199 useradii = tmpradii;
00200 // printf("** using defradius radii[0] = %g\n", useradii[0]);
00201 }
00202 
00203 DispCmdSphereArray cmdSphereArray;
00204 cmdSphereArray.putdata(xyz3fv,
00205 useradii,
00206 rgb3fv,
00207 numcoords,
00208 res,
00209 cmdList);
00210 
00211 // optionally draw interconnecting tubes
00212 if (drawtubes) {
00213 // if tubes have varying radii, we must draw cones
00214 int i,j;
00215 for (i=0,j=0; i<(numcoords-1); i++,j+=3) {
00216 // XXX we don't handle color-per sphere yet
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 // these aren't supported yet
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++; // go to the next shape/object
00284 }
00285 
00286 // draw the pickpoints if we have any
00287 if (pickpointindices.num() > 0) {
00288 DispCmdPickPointArray pickPointArray;
00289 pickPointArray.putdata(pickpointindices.num(), &pickpointindices[0],
00290 &pickpointcoords[0], cmdList);
00291 }
00292 
00293 needRegenerate = 0; // cmdlist has been udpated 
00294 }
00295 
00296 
00297 // resets the {next,max}_{id,index} values after something is added
00298 // returns the value of the new element
00299 int MoleculeGraphics::added(void) {
00300 needRegenerate = 1;
00301 next_index = shapes.num();
00302 int retval = next_id;
00303 if (next_id == max_id) { // this was a new shape
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 // save the points
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 // new one goes at next_id
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 // save the points
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); // normalize this normal to prevent problems later
00339 vec_copy(data+12, n2);
00340 vec_normalize(data+12); // normalize this normal to prevent problems later
00341 vec_copy(data+15, n3);
00342 vec_normalize(data+15); // normalize this normal to prevent problems later
00343 
00344 // new one goes at next_id
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); // normalize this normal to prevent problems later
00365 vec_copy(data+12, n2);
00366 vec_normalize(data+12); // normalize this normal to prevent problems later
00367 vec_copy(data+15, n3);
00368 vec_normalize(data+15); // normalize this normal to prevent problems later
00369 
00370 data[18] = (float)c1;
00371 data[19] = (float)c2;
00372 data[20] = (float)c3;
00373 
00374 // new one goes at next_id
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; // this will break for anything >= 2^24
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 // new one goes at next_id
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 // save the points
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 // new one goes at next_id
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 // new one goes at next_id
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(); // index where the text will be stored
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]; // if numradii == 1, then this is the global radius
00507 data[3] = float(numcolors); // if numcolors == 0, we pack a 1-color array
00508 data[4] = float(drawtubes);
00509 data[5] = float(res);
00510 
00511 // store bulk coordinates in an attached memory buffer
00512 const int coordsz = numcoords * 3;
00513 const int colorsz = numcoords * 3; // we MUST provide per-sphere colors
00514 float *tmp = (float *) malloc((coordsz + colorsz + numradii) * sizeof(float));
00515 memcpy(tmp, xyz3fv, coordsz * sizeof(float));
00516 
00517 // we must provide full color-per-sphere data presently
00518 if (numcolors < numcoords) {
00519 // use last draw color state, copied to buffer of elements
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 // new one goes at next_id
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 // do this based on the index
00583 int MoleculeGraphics::use_color(int index) {
00584 colorID = index; // record most recently set color index
00585 
00586 ShapeClass s(COLOR, 1, next_id);
00587 float *data = s.data;
00588 data[0] = float(index) + 0.1f; // just to be on the safe side for rounding
00589 if (next_index < num_elements())
00590 shapes[next_index] = s;
00591 else
00592 shapes.append(s);
00593 return added();
00594 }
00595 
00596 
00597 // return the index in the array, or -1 if it doesn't exist
00598 int MoleculeGraphics::index_id(int find_id) {
00599 // the values in the array are numerically increasing, so I can do
00600 // a binary search.
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 // and make sure it is for real
00619 if (id == find_id && shapes[loc].shape != NONE) {
00620 return loc;
00621 }
00622 return -1; // not found
00623 }
00624 
00625 
00626 // delete everything
00627 void MoleculeGraphics::delete_all(void) {
00628 shapes.clear(); 
00629 delete_shapetext(); // since there are no references to it now
00630 delete_count = 0; // and reset the internal variables
00631 next_index = 0;
00632 next_id = 0;
00633 max_id = 0;
00634 needRegenerate = 1;
00635 }
00636 
00637 
00638 // delete given the id
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 float(delete_count)/float(num_elements()) > 0.2*/) {
00646 // clear out the deleted elements
00647 int i, j=0, n = num_elements();
00648 // moving from i to j
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 // remove in reverse order so we don't have to copy anything
00663 for (int k=n-1; k >= j; k--) shapes.remove(k);
00664 delete_count = 0;
00665 }
00666 needRegenerate = 1;
00667 // delete overrides a replace
00668 next_id = max_id;
00669 next_index = num_elements();
00670 }
00671 
00672 
00673 // have the next added shape replace the given element
00674 // returns index
00675 int MoleculeGraphics::replace_id(int id) {
00676 int index = index_id(id);
00677 if (index < 0) return -1;
00678 // if one was already assigned to be replaced, and we want to
00679 // replace another, increase the delete count
00680 if (next_id != max_id) {
00681 delete_count++;
00682 }
00683 // do the replacement
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 // const int numcolors = int(shape->data[3]);
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; // we MUST provide per-sphere colors
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 // XXX incorrect logging at present
00815 // XXX right now this will result in colorID arrays getting converted
00816 // into RGB values incorrectly, we'll need to store them
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 // return the center of volume and scaling factor
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 // go down the list and draw things
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: { // I suppose I should include +/- radius ...
00922 CHECK_RANGE(shape->data+0);
00923 break;
00924 }
00925 case TEXT: { // I suppose I should include the string length size...
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 // compute the values for center of volume center and scale
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 // a bit of sanity check (eg, suppose there is only one point)
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 

Generated on Wed Nov 19 02:46:35 2025 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002

AltStyle によって変換されたページ (->オリジナル) /