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

DispCmds.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 * RCS INFORMATION:
00010 *
00011 * $RCSfile: DispCmds.C,v $
00012 * $Author: johns $ $Locker: $ $State: Exp $
00013 * $Revision: 1.121 $ $Date: 2021年05月14日 22:47:22 $
00014 *
00015 ***************************************************************************/
00037 #include <string.h>
00038 #include <stdlib.h>
00039 #include <stdio.h>
00040 #include <math.h>
00041 
00042 #ifdef VMDACTC
00043 extern "C" {
00044 // XXX 
00045 // The regular ACTC distribution compiles as plain C, need to send 
00046 // a header file fix to Brad Grantham so C++ codes don't need this.
00047 #include <tc.h>
00048 }
00049 #endif
00050 
00051 #include "Scene.h"
00052 #include "DispCmds.h"
00053 #include "utilities.h"
00054 #include "Matrix4.h"
00055 #include "VMDDisplayList.h"
00056 #include "Inform.h"
00057 #include "VMDApp.h" // needed for texture serial numbers
00058 
00059 //*************************************************************
00060 // Mark the beginning of the geometry associated with a representation
00061 void DispCmdBeginRepGeomGroup::putdata(const char *newtxt, VMDDisplayList *dobj) {
00062 char *buf = (char *) dobj->append(DBEGINREPGEOMGROUP, strlen(newtxt)+1);
00063 if (buf == NULL)
00064 return;
00065 memcpy(buf, newtxt, strlen(newtxt)+1);
00066 }
00067 
00068 
00069 //*************************************************************
00070 // include comments in the display list, useful for Token Rendering
00071 void DispCmdComment::putdata(const char *newtxt, VMDDisplayList *dobj) {
00072 char *buf = (char *) dobj->append(DCOMMENT, strlen(newtxt)+1);
00073 if (buf == NULL)
00074 return;
00075 memcpy(buf, newtxt, strlen(newtxt)+1);
00076 }
00077 
00078 
00079 //*************************************************************
00080 // plot a point at the given position
00081 void DispCmdPoint::putdata(const float *newpos, VMDDisplayList *dobj) {
00082 DispCmdPoint *ptr = (DispCmdPoint *)(dobj->append(DPOINT, 
00083 sizeof(DispCmdPoint)));
00084 if (ptr == NULL)
00085 return;
00086 ptr->pos[0]=newpos[0];
00087 ptr->pos[1]=newpos[1];
00088 ptr->pos[2]=newpos[2];
00089 }
00090 
00091 //*************************************************************
00092 // plot a sphere of specified radius at the given position
00093 void DispCmdSphere::putdata(float *newpos, float radius, VMDDisplayList *dobj) {
00094 DispCmdSphere *ptr = (DispCmdSphere *)(dobj->append(DSPHERE, 
00095 sizeof(DispCmdSphere)));
00096 if (ptr == NULL)
00097 return;
00098 ptr->pos_r[0]=newpos[0];
00099 ptr->pos_r[1]=newpos[1];
00100 ptr->pos_r[2]=newpos[2];
00101 ptr->pos_r[3]=radius; 
00102 } 
00103 
00104 
00105 void DispCmdSphereArray::putdata(const float * spcenters,
00106 const float * spradii,
00107 const float * spcolors,
00108 int num_spheres,
00109 int sphere_res,
00110 VMDDisplayList * dobj) {
00111 
00112 DispCmdSphereArray *ptr = (DispCmdSphereArray *) dobj->append(DSPHEREARRAY, 
00113 sizeof(DispCmdSphereArray) +
00114 sizeof(float) * num_spheres * 3L +
00115 sizeof(float) * num_spheres + 
00116 sizeof(float) * num_spheres * 3L +
00117 sizeof(int) * 2L);
00118 if (ptr == NULL)
00119 return;
00120 ptr->numspheres = num_spheres;
00121 ptr->sphereres = sphere_res;
00122 
00123 float *centers;
00124 float *radii;
00125 float *colors;
00126 ptr->getpointers(centers, radii, colors);
00127 
00128 memcpy(centers, spcenters, sizeof(float) * num_spheres * 3L);
00129 memcpy(radii, spradii, sizeof(float) * num_spheres);
00130 memcpy(colors, spcolors, sizeof(float) * num_spheres * 3L);
00131 }
00132 
00133 
00134 //*************************************************************
00135 // plot a lattice cube with side length equal to 2x radius at the given position
00136 void DispCmdLatticeCubeArray::putdata(const float * cbcenters,
00137 const float * cbradii,
00138 const float * cbcolors,
00139 int num_cubes,
00140 VMDDisplayList * dobj) {
00141 
00142 DispCmdLatticeCubeArray *ptr = (DispCmdLatticeCubeArray *) dobj->append(DCUBEARRAY, 
00143 sizeof(DispCmdLatticeCubeArray) +
00144 sizeof(float) * num_cubes * 3L +
00145 sizeof(float) * num_cubes + 
00146 sizeof(float) * num_cubes * 3L +
00147 sizeof(int) * 1L);
00148 if (ptr == NULL)
00149 return;
00150 ptr->numcubes = num_cubes;
00151 
00152 float *centers;
00153 float *radii;
00154 float *colors;
00155 ptr->getpointers(centers, radii, colors);
00156 
00157 memcpy(centers, cbcenters, sizeof(float) * num_cubes * 3L);
00158 memcpy(radii, cbradii, sizeof(float) * num_cubes);
00159 memcpy(colors, cbcolors, sizeof(float) * num_cubes * 3L);
00160 }
00161 
00162 
00163 //*************************************************************
00164 
00165 void DispCmdPointArray::putdata(const float * pcenters,
00166 const float * pcolors,
00167 float psize,
00168 int num_points,
00169 VMDDisplayList * dobj) {
00170 
00171 DispCmdPointArray *ptr = (DispCmdPointArray *) dobj->append(DPOINTARRAY, 
00172 sizeof(DispCmdPointArray) +
00173 sizeof(float) * num_points * 3L +
00174 sizeof(float) * num_points * 3L +
00175 sizeof(float) +
00176 sizeof(int));
00177 if (ptr == NULL)
00178 return;
00179 ptr->size = psize;
00180 ptr->numpoints = num_points;
00181 
00182 float *centers;
00183 float *colors;
00184 ptr->getpointers(centers, colors);
00185 
00186 memcpy(centers, pcenters, sizeof(float) * num_points * 3L);
00187 memcpy(colors, pcolors, sizeof(float) * num_points * 3L);
00188 }
00189 
00190 void DispCmdPointArray::putdata(const float * pcenters,
00191 const int * pcolors,
00192 Scene * scene,
00193 float psize,
00194 int num_atoms,
00195 const int *on,
00196 int num_selected,
00197 VMDDisplayList * dobj) {
00198 
00199 // If we have a reasonable size atom selection and therefore 
00200 // vertex buffer size, we use a very fast/simple path for populating the 
00201 // display command buffer.
00202 // If we have too many vertices, we have to break up the vertex buffers
00203 // and emit several smaller buffers to prevent integer wraparound in 
00204 // vertex indexing in back-end renderers. 
00205 int totalpoints=0;
00206 int i=0;
00207 while (totalpoints < num_selected) {
00208 int chunksize = num_selected - totalpoints;
00209 if (chunksize > VMDMAXVERTEXBUFSZ)
00210 chunksize = VMDMAXVERTEXBUFSZ;
00211 
00212 DispCmdPointArray *ptr = (DispCmdPointArray *) dobj->append(DPOINTARRAY, 
00213 sizeof(DispCmdPointArray) +
00214 sizeof(float) * chunksize * 3L +
00215 sizeof(float) * chunksize * 3L +
00216 sizeof(float) +
00217 sizeof(int));
00218 if (ptr == NULL)
00219 return;
00220 ptr->size = psize;
00221 ptr->numpoints = chunksize;
00222 
00223 float *centers, *colors;
00224 ptr->getpointers(centers, colors);
00225 
00226 const float *fp = pcenters + 3L*i;
00227 ptrdiff_t ind;
00228 int cnt;
00229 for (ind=0,cnt=0; ((cnt < VMDMAXVERTEXBUFSZ) && (i < num_atoms)); i++) {
00230 // draw a point for each selected atom
00231 if (on[i]) {
00232 cnt++;
00233 centers[ind ] = fp[0];
00234 centers[ind + 1] = fp[1];
00235 centers[ind + 2] = fp[2];
00236 
00237 const float *cp = scene->color_value(pcolors[i]);
00238 colors[ind ] = cp[0];
00239 colors[ind + 1] = cp[1];
00240 colors[ind + 2] = cp[2];
00241 ind += 3L;
00242 }
00243 fp += 3L;
00244 }
00245 totalpoints+=cnt;
00246 }
00247 }
00248 
00249 
00250 
00251 //*************************************************************
00252 
00253 void DispCmdLitPointArray::putdata(const float * pcenters,
00254 const float * pnormals,
00255 const float * pcolors,
00256 float psize,
00257 int num_points,
00258 VMDDisplayList * dobj) {
00259 
00260 DispCmdLitPointArray *ptr = (DispCmdLitPointArray *) dobj->append(DLITPOINTARRAY, 
00261 sizeof(DispCmdLitPointArray) +
00262 sizeof(float) * num_points * 3L +
00263 sizeof(float) * num_points * 3L +
00264 sizeof(float) * num_points * 3L +
00265 sizeof(float) +
00266 sizeof(int));
00267 if (ptr == NULL)
00268 return;
00269 ptr->size = psize;
00270 ptr->numpoints = num_points;
00271 
00272 float *centers;
00273 float *normals;
00274 float *colors;
00275 ptr->getpointers(centers, normals, colors);
00276 
00277 memcpy(centers, pcenters, sizeof(float) * num_points * 3L);
00278 memcpy(normals, pnormals, sizeof(float) * num_points * 3L);
00279 memcpy(colors, pcolors, sizeof(float) * num_points * 3L);
00280 }
00281 
00282 //*************************************************************
00283 
00284 // plot a line at the given position
00285 void DispCmdLine::putdata(float *newpos1, float *newpos2, VMDDisplayList *dobj) {
00286 DispCmdLine *ptr = (DispCmdLine *)(dobj->append(DLINE, 
00287 sizeof(DispCmdLine)));
00288 if (ptr == NULL)
00289 return;
00290 memcpy(ptr->pos1, newpos1, 3L*sizeof(float));
00291 memcpy(ptr->pos2, newpos2, 3L*sizeof(float));
00292 }
00293 
00294 // draw a series of independent lines, (v0 v1), (v2 v3), (v4 v5)
00295 void DispCmdLineArray::putdata(float *v, int n, VMDDisplayList *dobj) {
00296 void *ptr = dobj->append(DLINEARRAY, (1+6L*n)*sizeof(float));
00297 if (ptr == NULL)
00298 return;
00299 float *fltptr = (float *)ptr;
00300 *fltptr = (float)n;
00301 memcpy(fltptr+1, v, 6L*n*sizeof(float));
00302 }
00303 
00304 // draw a series of connected polylines, (v0 v1 v2 v3 v4 v5)
00305 void DispCmdPolyLineArray::putdata(float *v, int n, VMDDisplayList *dobj) {
00306 void *ptr = dobj->append(DPOLYLINEARRAY, (1+3L*n)*sizeof(float));
00307 if (ptr == NULL)
00308 return;
00309 float *fltptr = (float *)ptr;
00310 *fltptr = (float)n;
00311 memcpy(fltptr+1, v, 3L*n*sizeof(float));
00312 }
00313 
00314 //*************************************************************
00315 // draw a triangle
00316 
00317 // set up the data for the DTRIANGLE drawing command
00318 void DispCmdTriangle::set_array(const float *p1,const float *p2,const float *p3,
00319 const float *n1, const float *n2, const float *n3, VMDDisplayList *dobj) {
00320 DispCmdTriangle *ptr = (DispCmdTriangle *)(dobj->append(DTRIANGLE, 
00321 sizeof(DispCmdTriangle)));
00322 if (ptr == NULL)
00323 return;
00324 memcpy(ptr->pos1, p1, 3L*sizeof(float)); 
00325 memcpy(ptr->pos2, p2, 3L*sizeof(float)); 
00326 memcpy(ptr->pos3, p3, 3L*sizeof(float)); 
00327 memcpy(ptr->norm1, n1, 3L*sizeof(float)); 
00328 memcpy(ptr->norm2, n2, 3L*sizeof(float)); 
00329 memcpy(ptr->norm3, n3, 3L*sizeof(float)); 
00330 }
00331 
00332 // put in new data, and put the command
00333 void DispCmdTriangle::putdata(const float *p1, const float *p2, 
00334 const float *p3, VMDDisplayList *dobj) {
00335 int i;
00336 float tmp1[3], tmp2[3], tmp3[3]; // precompute the normal for
00337 for (i=0; i<3; i++) { // faster drawings later
00338 tmp1[i] = p2[i] - p1[i];
00339 tmp2[i] = p3[i] - p2[i];
00340 }
00341 cross_prod( tmp3, tmp1, tmp2); 
00342 vec_normalize(tmp3);
00343 set_array(p1, p2, p3, tmp3, tmp3, tmp3, dobj);
00344 }
00345 void DispCmdTriangle::putdata(const float *p1, const float *p2,const float *p3,
00346 const float *n1, const float *n2,const float *n3,
00347 VMDDisplayList *dobj) {
00348 set_array(p1,p2,p3,n1,n2,n3,dobj);
00349 }
00350 
00351 //*************************************************************
00352 
00353 // draw a square, given 3 of four points
00354 void DispCmdSquare::putdata(float *p1, float *p2,float *p3,VMDDisplayList *dobj) {
00355 DispCmdSquare *ptr = (DispCmdSquare *)(dobj->append(DSQUARE, 
00356 sizeof(DispCmdSquare)));
00357 if (ptr == NULL)
00358 return;
00359 int i;
00360 float tmp1[3], tmp2[3]; // precompute the normal for
00361 for (i=0; i<3; i++) { // faster drawings later
00362 tmp1[i] = p2[i] - p1[i];
00363 tmp2[i] = p3[i] - p2[i];
00364 }
00365 cross_prod(ptr->norml, tmp1, tmp2); 
00366 vec_normalize(ptr->norml);
00367 
00368 memcpy(ptr->pos1, p1, 3L*sizeof(float));
00369 memcpy(ptr->pos2, p2, 3L*sizeof(float));
00370 memcpy(ptr->pos3, p3, 3L*sizeof(float));
00371 for (i=0; i<3; i++)
00372 ptr->pos4[i] = p1[i] + tmp2[i]; // compute the fourth point
00373 }
00374 
00375 
00376 //*************************************************************
00377 // draw a mesh consisting of vertices, facets, colors, normals etc.
00378 void DispCmdTriMesh::putdata(const float * vertices,
00379 const float * normals,
00380 const float * colors,
00381 int num_facets,
00382 VMDDisplayList * dobj) {
00383 // make a triangle mesh (no strips)
00384 DispCmdTriMesh *ptr;
00385 if (colors == NULL) {
00386 ptr = (DispCmdTriMesh *) 
00387 (dobj->append(DTRIMESH_C3F_N3F_V3F, sizeof(DispCmdTriMesh) +
00388 sizeof(float) * num_facets * 3L * 6L));
00389 } else {
00390 ptr = (DispCmdTriMesh *) 
00391 (dobj->append(DTRIMESH_C3F_N3F_V3F, sizeof(DispCmdTriMesh) +
00392 sizeof(float) * num_facets * 3L * 9L));
00393 }
00394 
00395 if (ptr == NULL)
00396 return;
00397 
00398 ptr->numverts=num_facets * 3L;
00399 ptr->numfacets=num_facets;
00400 
00401 float *c=NULL, *n=NULL, *v=NULL;
00402 if (colors == NULL) {
00403 ptr->pervertexcolors=0;
00404 ptr->getpointers(n, v);
00405 } else {
00406 ptr->pervertexcolors=1;
00407 ptr->getpointers(c, n, v);
00408 memcpy(c, colors, ptr->numverts * 3L * sizeof(float));
00409 }
00410 
00411 if (normals == NULL) {
00412 ptr->pervertexnormals=0;
00413 ptrdiff_t i;
00414 for (i=0; i<(num_facets * 9L); i+=9) {
00415 float tmp1[3], tmp2[3], tmpnorm[3];
00416 const float *v0 = &vertices[i ];
00417 const float *v1 = &vertices[i+3];
00418 const float *v2 = &vertices[i+6];
00419 
00420 vec_sub(tmp1, v1, v0);
00421 vec_sub(tmp2, v2, v1);
00422 cross_prod(tmpnorm, tmp1, tmp2);
00423 vec_normalize(tmpnorm);
00424 
00425 n[i ] = tmpnorm[0];
00426 n[i+1] = tmpnorm[1];
00427 n[i+2] = tmpnorm[2];
00428 
00429 n[i+3] = tmpnorm[0];
00430 n[i+4] = tmpnorm[1];
00431 n[i+5] = tmpnorm[2];
00432 
00433 n[i+6] = tmpnorm[0];
00434 n[i+7] = tmpnorm[1];
00435 n[i+8] = tmpnorm[2];
00436 } 
00437 } else {
00438 ptr->pervertexnormals=1;
00439 memcpy(n, normals, ptr->numverts * 3L * sizeof(float));
00440 }
00441 
00442 memcpy(v, vertices, ptr->numverts * 3L * sizeof(float));
00443 }
00444 
00445 
00446 //*************************************************************
00447 // draw a mesh consisting of vertices, facets, colors, normals etc.
00448 void DispCmdTriMesh::putdata(const float * vertices,
00449 const float * normals,
00450 const unsigned char * colors,
00451 int num_facets,
00452 VMDDisplayList * dobj) {
00453 // make a triangle mesh (no strips)
00454 DispCmdTriMesh *ptr;
00455 if (colors == NULL) {
00456 ptr = (DispCmdTriMesh *) 
00457 (dobj->append(DTRIMESH_C4U_N3F_V3F, sizeof(DispCmdTriMesh) +
00458 sizeof(float) * num_facets * 3L * 6L));
00459 } else {
00460 ptr = (DispCmdTriMesh *) 
00461 (dobj->append(DTRIMESH_C4U_N3F_V3F, sizeof(DispCmdTriMesh) +
00462 4L * sizeof(unsigned char) * num_facets * 3L +
00463 sizeof(float) * num_facets * 3L * 6L));
00464 }
00465 
00466 if (ptr == NULL)
00467 return;
00468 
00469 ptr->numverts=num_facets * 3L;
00470 ptr->numfacets=num_facets;
00471 
00472 unsigned char *c=NULL;
00473 float *n=NULL, *v=NULL;
00474 if (colors == NULL) {
00475 ptr->pervertexcolors=0;
00476 ptr->getpointers(n, v);
00477 } else {
00478 ptr->pervertexcolors=1;
00479 ptr->getpointers(c, n, v);
00480 memcpy(c, colors, ptr->numverts * 4L * sizeof(unsigned char));
00481 }
00482 
00483 ptr->pervertexnormals=1;
00484 memcpy(n, normals, ptr->numverts * 3L * sizeof(float));
00485 memcpy(v, vertices, ptr->numverts * 3L * sizeof(float));
00486 }
00487 
00488 
00489 //*************************************************************
00490 // draw a mesh consisting of vertices, facets, colors, normals etc.
00491 void DispCmdTriMesh::putdata(const float * vertices,
00492 const char * normals,
00493 const unsigned char * colors,
00494 int num_facets,
00495 VMDDisplayList * dobj) {
00496 // make a triangle mesh (no strips)
00497 DispCmdTriMesh *ptr;
00498 if (colors == NULL) {
00499 ptr = (DispCmdTriMesh *) 
00500 (dobj->append(DTRIMESH_C4U_N3B_V3F, sizeof(DispCmdTriMesh) +
00501 sizeof(char) * num_facets * 3L * 3L +
00502 sizeof(float) * num_facets * 3L * 3L));
00503 } else {
00504 ptr = (DispCmdTriMesh *) 
00505 (dobj->append(DTRIMESH_C4U_N3B_V3F, sizeof(DispCmdTriMesh) +
00506 4L * sizeof(unsigned char) * num_facets * 3L +
00507 sizeof(char) * num_facets * 3L * 3L +
00508 sizeof(float) * num_facets * 3L * 3L));
00509 }
00510 
00511 if (ptr == NULL)
00512 return;
00513 
00514 ptr->numverts=num_facets * 3L;
00515 ptr->numfacets=num_facets;
00516 
00517 unsigned char *c=NULL;
00518 signed char *n=NULL;
00519 float *v=NULL;
00520 if (colors == NULL) {
00521 ptr->pervertexcolors=0;
00522 ptr->getpointers(n, v);
00523 } else {
00524 ptr->pervertexcolors=1;
00525 ptr->getpointers(c, n, v);
00526 memcpy(c, colors, ptr->numverts * 4L * sizeof(unsigned char));
00527 }
00528 
00529 ptr->pervertexnormals=1;
00530 memcpy(n, normals, ptr->numverts * 3L * sizeof(char));
00531 memcpy(v, vertices, ptr->numverts * 3L * sizeof(float));
00532 }
00533 
00534 
00535 // draw a mesh consisting of vertices, facets, colors, normals etc.
00536 void DispCmdTriMesh::putdata(const float * vertices,
00537 const float * normals,
00538 const float * colors,
00539 int num_verts,
00540 const int * facets,
00541 int num_facets, 
00542 int enablestrips,
00543 VMDDisplayList * dobj) {
00544 int builtstrips = 0; 
00545 
00546 #if defined(VMDACTC) 
00547 if (enablestrips) {
00548 // Rearrange face data into triangle strips
00549 ACTCData *tc = actcNew(); // intialize ACTC stripification library
00550 ptrdiff_t fsize = num_facets * 3L;
00551 ptrdiff_t i, ind, ii;
00552 ptrdiff_t iPrimCount = 0;
00553 ptrdiff_t iCurrPrimSize;
00554 
00555 // XXX over-allocate the vertex and facet buffers to prevent an
00556 // apparent bug in ACTC 1.1 from crashing VMD. This was causing
00557 // Surf surfaces to crash ACTC at times.
00558 int *p_iPrimSize = new int[fsize + 6]; // num vertices in a primitive 
00559 unsigned int *f2 = new uint[fsize + 6];
00560 
00561 if (tc == NULL) {
00562 msgErr << "ACTC initialization failed, using triangle mesh." << sendmsg;
00563 } else {
00564 msgInfo << "Performing ACTC Triangle Consolidation..." << sendmsg;
00565 
00566 // only produce strips, not fans, give a ridiculously high min value.
00567 actcParami(tc, ACTC_OUT_MIN_FAN_VERTS, 2147483647);
00568 
00569 // disabling honoring vertex winding order might allow ACTC to
00570 // consolidate more triangles into strips, but this is only useful
00571 // if VMD has two-sided lighting enabled.
00572 // actcParami(tc, ACTC_OUT_HONOR_WINDING, ACTC_TRUE);
00573 
00574 // send triangle data over to ACTC library
00575 actcBeginInput(tc);
00576 for (ii=0; ii < num_facets; ii++) {
00577 ind = ii * 3L;
00578 if ((actcAddTriangle(tc, facets[ind], facets[ind + 1], facets[ind + 2])) != ACTC_NO_ERROR) {
00579 msgInfo << "ACTC Add Triangle Error." << sendmsg;
00580 }
00581 }
00582 actcEndInput(tc);
00583 
00584 // get triangle strips back from ACTC, loop through once to get sizes
00585 actcBeginOutput(tc);
00586 i = 0;
00587 while ((actcStartNextPrim(tc, &f2[i], &f2[i+1]) != ACTC_DATABASE_EMPTY)) {
00588 iCurrPrimSize = 2; // if we're here, we got 2 vertices
00589 i+=2; // increment array position
00590 while (actcGetNextVert(tc, &f2[i]) != ACTC_PRIM_COMPLETE) {
00591 iCurrPrimSize++; // increment number of vertices for this primitive
00592 i++; // increment array position
00593 }
00594 
00595 p_iPrimSize[iPrimCount] = iCurrPrimSize; // save vertex count
00596 iPrimCount++; // increment primitive counter
00597 }
00598 actcEndOutput(tc);
00599 msgInfo << "ACTC: Created " << iPrimCount << " triangle strips" << sendmsg;
00600 msgInfo << "ACTC: Average vertices per strip = " << i / iPrimCount << sendmsg;
00601 
00602 // Draw triangle strips, uses double-sided lighting until we change
00603 // things to allow the callers to specify the desired lighting 
00604 // explicitly.
00605 DispCmdTriStrips::putdata(vertices, normals, colors, num_verts, p_iPrimSize, iPrimCount, f2, i, 1, dobj);
00606 
00607 // delete temporary memory
00608 delete [] f2;
00609 delete [] p_iPrimSize;
00610 
00611 // delete ACTC handle
00612 actcDelete(tc);
00613 
00614 builtstrips = 1; // don't generate a regular triangle mesh
00615 } 
00616 } 
00617 #endif
00618 
00619 if (!builtstrips) {
00620 // make a triangle mesh (no strips)
00621 DispCmdTriMesh *ptr = (DispCmdTriMesh *) 
00622 (dobj->append(DTRIMESH_C4F_N3F_V3F, sizeof(DispCmdTriMesh) +
00623 sizeof(float) * num_verts * 10L +
00624 sizeof(int) * num_facets * 3L));
00625 if (ptr == NULL)
00626 return;
00627 ptr->pervertexcolors=1;
00628 ptr->pervertexnormals=1;
00629 ptr->numverts=num_verts;
00630 ptr->numfacets=num_facets;
00631 float *cnv;
00632 int *f;
00633 ptr->getpointers(cnv, f);
00634 
00635 #if 1
00636 ptrdiff_t ind10, ind3;
00637 for (ind10=0,ind3=0; ind10<num_verts*10L; ind10+=10,ind3+=3) {
00638 cnv[ind10 ] = colors[ind3 ];
00639 cnv[ind10 + 1] = colors[ind3 + 1]; 
00640 cnv[ind10 + 2] = colors[ind3 + 2]; 
00641 cnv[ind10 + 3] = 1.0; 
00642 cnv[ind10 + 4] = normals[ind3 ];
00643 cnv[ind10 + 5] = normals[ind3 + 1];
00644 cnv[ind10 + 6] = normals[ind3 + 2];
00645 cnv[ind10 + 7] = vertices[ind3 ];
00646 cnv[ind10 + 8] = vertices[ind3 + 1];
00647 cnv[ind10 + 9] = vertices[ind3 + 2];
00648 }
00649 #else
00650 ptrdiff_t i, ind, ind2;
00651 for (i=0; i<num_verts; i++) {
00652 ind = i * 10L;
00653 ind2 = i * 3L;
00654 cnv[ind ] = colors[ind2 ];
00655 cnv[ind + 1] = colors[ind2 + 1]; 
00656 cnv[ind + 2] = colors[ind2 + 2]; 
00657 cnv[ind + 3] = 1.0; 
00658 cnv[ind + 4] = normals[ind2 ];
00659 cnv[ind + 5] = normals[ind2 + 1];
00660 cnv[ind + 6] = normals[ind2 + 2];
00661 cnv[ind + 7] = vertices[ind2 ];
00662 cnv[ind + 8] = vertices[ind2 + 1];
00663 cnv[ind + 9] = vertices[ind2 + 2];
00664 } 
00665 #endif
00666 
00667 memcpy(f, facets, ptr->numfacets * 3L * sizeof(int));
00668 }
00669 }
00670 
00671 //*************************************************************
00672 
00673 // draw a set of triangle strips
00674 void DispCmdTriStrips::putdata(const float * vertices,
00675 const float * normals,
00676 const float * colors,
00677 int num_verts,
00678 const int * verts_per_strip,
00679 int num_strips,
00680 const unsigned int * strip_data,
00681 const int num_strip_verts,
00682 int double_sided_lighting,
00683 VMDDisplayList * dobj) {
00684 
00685 DispCmdTriStrips *ptr = (DispCmdTriStrips *) (dobj->append(DTRISTRIP, 
00686 sizeof(DispCmdTriStrips) +
00687 sizeof(int *) * num_strips +
00688 sizeof(float) * num_verts * 10L +
00689 sizeof(int) * num_strip_verts +
00690 sizeof(int) * num_strips));
00691 if (ptr == NULL) 
00692 return;
00693 ptr->numverts=num_verts;
00694 ptr->numstrips=num_strips;
00695 ptr->numstripverts=num_strip_verts;
00696 ptr->doublesided=double_sided_lighting;
00697 
00698 float *cnv;
00699 int *f;
00700 int *vertsperstrip;
00701 ptr->getpointers(cnv, f, vertsperstrip);
00702 
00703 // copy vertex,color,normal data
00704 ptrdiff_t i, ind, ind2;
00705 for (i=0; i<num_verts; i++) {
00706 ind = i * 10L;
00707 ind2 = i * 3L;
00708 cnv[ind ] = colors[ind2 ];
00709 cnv[ind + 1] = colors[ind2 + 1];
00710 cnv[ind + 2] = colors[ind2 + 2];
00711 cnv[ind + 3] = 1.0;
00712 cnv[ind + 4] = normals[ind2 ];
00713 cnv[ind + 5] = normals[ind2 + 1];
00714 cnv[ind + 6] = normals[ind2 + 2];
00715 cnv[ind + 7] = vertices[ind2 ];
00716 cnv[ind + 8] = vertices[ind2 + 1];
00717 cnv[ind + 9] = vertices[ind2 + 2];
00718 }
00719 
00720 // copy vertices per strip data
00721 for (i=0; i<num_strips; i++) {
00722 vertsperstrip[i] = verts_per_strip[i];
00723 }
00724 
00725 // copy face (triangle) data
00726 for (i=0; i<num_strip_verts; i++) {
00727 f[i] = strip_data[i];
00728 }
00729 }
00730 
00731 
00732 //*************************************************************
00733 
00734 void DispCmdWireMesh::putdata(const float * vertices,
00735 const float * normals,
00736 const float * colors,
00737 int num_verts,
00738 const int * lines,
00739 int num_lines, VMDDisplayList * dobj) {
00740 
00741 DispCmdWireMesh *ptr = (DispCmdWireMesh *) (dobj->append(DWIREMESH, 
00742 sizeof(DispCmdWireMesh) +
00743 sizeof(float) * num_verts * 10L +
00744 sizeof(int) * num_lines * 3L));
00745 if (ptr == NULL) 
00746 return;
00747 ptr->numverts=num_verts;
00748 ptr->numlines=num_lines;
00749 
00750 float *cnv;
00751 int *l;
00752 ptr->getpointers(cnv, l);
00753 
00754 ptrdiff_t i, ind, ind2;
00755 for (i=0; i<num_verts; i++) {
00756 ind = i * 10L;
00757 ind2 = i * 3L;
00758 cnv[ind ] = colors[ind2 ];
00759 cnv[ind + 1] = colors[ind2 + 1]; 
00760 cnv[ind + 2] = colors[ind2 + 2]; 
00761 cnv[ind + 3] = 1.0; 
00762 cnv[ind + 4] = normals[ind2 ];
00763 cnv[ind + 5] = normals[ind2 + 1];
00764 cnv[ind + 6] = normals[ind2 + 2];
00765 cnv[ind + 7] = vertices[ind2 ];
00766 cnv[ind + 8] = vertices[ind2 + 1];
00767 cnv[ind + 9] = vertices[ind2 + 2];
00768 } 
00769 
00770 memcpy(l, lines, ptr->numlines * 2L * sizeof(int));
00771 }
00772 
00773 //*************************************************************
00774 // plot a cylinder at the given position
00775 // this is used to precalculate the cylinder data for speedup
00776 // in renderers without hardware cylinders. For example, the GL
00777 // library. There are res number of edges (with a norm, and two points)
00778 
00779 DispCmdCylinder::DispCmdCylinder(void) {
00780 lastres = 0;
00781 }
00782 
00783 void DispCmdCylinder::putdata(const float *pos1, const float *pos2, float rad, 
00784 int res, int filled, VMDDisplayList *dobj) {
00785 
00786 float lenaxis[3];
00787 vec_sub(lenaxis, pos1, pos2); // check that it's valid
00788 if (dot_prod(lenaxis,lenaxis) == 0.0 || res <= 0) return;
00789 
00790 if (lastres != res ) {
00791 rot[0] = cosf( (float) VMD_TWOPI / (float) res);
00792 rot[1] = sinf( (float) VMD_TWOPI / (float) res);
00793 }
00794 lastres = res;
00795 size_t size = (9L + res*3L*3L)*sizeof(float);
00796 
00797 float *pos = (float *)(dobj->append(DCYLINDER, size));
00798 if (pos == NULL) 
00799 return;
00800 
00801 memcpy(pos, pos1, 3L*sizeof(float));
00802 memcpy(pos+3, pos2, 3L*sizeof(float));
00803 pos[6] = rad;
00804 pos[7] = (float)res;
00805 pos[8] = (float)filled;
00806 
00807 float axis[3];
00808 vec_sub(axis, pos1, pos2);
00809 vec_normalize(axis);
00810 int i; // find an axis not aligned with the cylinder
00811 if (fabs(axis[0]) < fabs(axis[1]) &&
00812 fabs(axis[0]) < fabs(axis[2])) {
00813 i = 0;
00814 } else if (fabs(axis[1]) < fabs(axis[2])) {
00815 i = 1;
00816 } else {
00817 i = 2;
00818 }
00819 float perp[3];
00820 perp[i] = 0; // this is not aligned with the cylinder
00821 perp[(i+1)%3] = axis[(i+2)%3];
00822 perp[(i+2)%3] = -axis[(i+1)%3];
00823 vec_normalize(perp);
00824 float perp2[3];
00825 cross_prod(perp2, axis, perp); // find a normal to the cylinder
00826 
00827 float *posptr = pos+9;
00828 float m = rot[0], n = rot[1];
00829 for (int h=0; h<res; h++) {
00830 float tmp0, tmp1, tmp2;
00831 
00832 tmp0 = m*perp[0] + n*perp2[0]; // add the normal
00833 tmp1 = m*perp[1] + n*perp2[1];
00834 tmp2 = m*perp[2] + n*perp2[2];
00835 
00836 posptr[0] = tmp0; // add the normal
00837 posptr[1] = tmp1;
00838 posptr[2] = tmp2;
00839 
00840 posptr[3] = pos2[0] + rad * tmp0; // start
00841 posptr[4] = pos2[1] + rad * tmp1;
00842 posptr[5] = pos2[2] + rad * tmp2;
00843 
00844 posptr[6] = posptr[3] + lenaxis[0]; // and end of the edge
00845 posptr[7] = posptr[4] + lenaxis[1];
00846 posptr[8] = posptr[5] + lenaxis[2];
00847 posptr += 9;
00848 // use angle addition formulae:
00849 // cos(A+B) = cos A cos B - sin A sin B
00850 // sin(A+B) = cos A sin B + sin A cos B
00851 float mtmp = rot[0]*m - rot[1]*n;
00852 float ntmp = rot[0]*n + rot[1]*m; 
00853 m = mtmp;
00854 n = ntmp;
00855 }
00856 }
00857 
00858 
00859 #if defined(VMDOPTIXRTRT)
00860 //*************************************************************
00861 
00862 void DispCmdCylinderArray::putdata(const float * cylpoints,
00863 const float * cylradii,
00864 const float * cylcolors,
00865 int num_cyls, int cyl_res, int cyl_caps,
00866 VMDDisplayList * dobj) {
00867 
00868 DispCmdCylinderArray *ptr = (DispCmdCylinderArray *) dobj->append(DCYLINDERARRAY, 
00869 sizeof(DispCmdCylinderArray) +
00870 sizeof(float) * num_cyls * 6L +
00871 sizeof(float) * num_cyls + 
00872 sizeof(float) * num_cyls * 3L +
00873 sizeof(int) * 3L);
00874 if (ptr == NULL)
00875 return;
00876 ptr->numcylinders = num_cyls;
00877 ptr->cylinderres = cyl_res;
00878 ptr->cylindercaps = cyl_caps;
00879 
00880 float *points;
00881 float *radii;
00882 float *colors;
00883 ptr->getpointers(points, radii, colors);
00884 
00885 memcpy(points, cylpoints, sizeof(float) * num_cyls * 6L);
00886 memcpy(radii, cylradii, sizeof(float) * num_cyls);
00887 memcpy(colors, cylcolors, sizeof(float) * num_cyls * 3L);
00888 }
00889 #endif
00890 
00891 
00892 //*************************************************************
00893 
00894 void DispCmdCone::putdata(const float *p1, const float *p2,
00895 float newrad, float newrad2, int newres,
00896 VMDDisplayList *dobj) {
00897 DispCmdCone *ptr = (DispCmdCone *)(dobj->append(DCONE, 
00898 sizeof(DispCmdCone)));
00899 if (ptr == NULL) 
00900 return;
00901 memcpy(ptr->pos1, p1, 3L*sizeof(float));
00902 memcpy(ptr->pos2, p2, 3L*sizeof(float));
00903 ptr->radius=newrad;
00904 ptr->radius2=newrad2;
00905 ptr->res=newres;
00906 }
00907 
00908 // put in new data, and put the command
00909 void DispCmdColorIndex::putdata(int newcol, VMDDisplayList *dobj) {
00910 DispCmdColorIndex *ptr = (DispCmdColorIndex *)(dobj->append(DCOLORINDEX, 
00911 sizeof(DispCmdColorIndex)));
00912 if (ptr == NULL) 
00913 return;
00914 ptr->color = newcol;
00915 }
00916 
00917 //*************************************************************
00918 
00919 // display text at the given text coordinates
00920 void DispCmdText::putdata(const float *c, const char *s, float thickness, 
00921 float size, float ox, float oy, VMDDisplayList *dobj) {
00922 if (s != NULL) {
00923 size_t len = strlen(s)+1;
00924 char *buf = (char *)(dobj->append(DTEXT, len+7L*sizeof(float)));
00925 if (buf == NULL) 
00926 return;
00927 ((float *)buf)[0] = c[0]; // X
00928 ((float *)buf)[1] = c[1]; // Y
00929 ((float *)buf)[2] = c[2]; // Z
00930 ((float *)buf)[3] = thickness; // thickness
00931 ((float *)buf)[4] = size; // size
00932 ((float *)buf)[5] = ox; // X offset
00933 ((float *)buf)[6] = oy; // Y offset
00934 memcpy(buf+7L*sizeof(float),s,len); // text string
00935 }
00936 }
00937 
00938 //*************************************************************
00939 
00940 void DispCmdVolSlice::putdata(int mode, const float *pnormal, const float *verts, 
00941 const float *texs, VMDDisplayList *dobj) {
00942 
00943 DispCmdVolSlice *cmd = (DispCmdVolSlice *) dobj->append(DVOLSLICE, 
00944 sizeof(DispCmdVolSlice));
00945 if (cmd == NULL)
00946 return;
00947 
00948 cmd->texmode = mode;
00949 memcpy(cmd->normal, pnormal, 3L*sizeof(float));
00950 memcpy(cmd->v, verts, 12L*sizeof(float));
00951 memcpy(cmd->t, texs, 12L*sizeof(float));
00952 }
00953 
00954 //*************************************************************
00955 
00956 
00957 void DispCmdVolumeTexture::putdata(unsigned long texID, 
00958 const int size[3], unsigned char *texptr, const float pv0[3], 
00959 const float pv1[3], const float pv2[3], const float pv3[3], 
00960 VMDDisplayList *dobj) {
00961 
00962 DispCmdVolumeTexture *cmd = (DispCmdVolumeTexture *) dobj->append(DVOLUMETEXTURE,
00963 sizeof(DispCmdVolumeTexture));
00964 
00965 if (cmd == NULL) return;
00966 
00967 cmd->ID = texID;
00968 cmd->xsize = size[0];
00969 cmd->ysize = size[1];
00970 cmd->zsize = size[2];
00971 cmd->texmap = texptr;
00972 memcpy(cmd->v0, pv0, 3L*sizeof(float));
00973 memcpy(cmd->v1, pv1, 3L*sizeof(float));
00974 memcpy(cmd->v2, pv2, 3L*sizeof(float));
00975 memcpy(cmd->v3, pv3, 3L*sizeof(float));
00976 }
00977 
00978 //*************************************************************
00979 // put in new data, and put the command
00980 void DispCmdSphereRes::putdata(int newres, VMDDisplayList *dobj) {
00981 DispCmdSphereRes *ptr = (DispCmdSphereRes *)dobj->append(DSPHERERES,
00982 sizeof(DispCmdSphereRes));
00983 if (ptr == NULL)
00984 return;
00985 ptr->res = newres;
00986 }
00987 
00988 //*************************************************************
00989 
00990 // put in new data, and put the command
00991 void DispCmdSphereType::putdata(int newtype, VMDDisplayList *dobj) {
00992 DispCmdSphereType *ptr = (DispCmdSphereType *)dobj->append(DSPHERETYPE,
00993 sizeof(DispCmdSphereType));
00994 if (ptr == NULL)
00995 return;
00996 ptr->type = newtype;
00997 }
00998 
00999 //*************************************************************
01000 
01001 // put in new data, and put the command
01002 void DispCmdLineType::putdata(int newtype, VMDDisplayList *dobj) {
01003 DispCmdLineType* ptr = (DispCmdLineType *)dobj->append(DLINESTYLE,
01004 sizeof(DispCmdLineType));
01005 if (ptr == NULL)
01006 return;
01007 ptr->type = newtype;
01008 }
01009 
01010 //*************************************************************
01011 
01012 void DispCmdLineWidth::putdata(int newwidth, VMDDisplayList *dobj) {
01013 DispCmdLineWidth * ptr = (DispCmdLineWidth *)dobj->append(DLINEWIDTH,
01014 sizeof(DispCmdLineWidth));
01015 if (ptr == NULL)
01016 return;
01017 ptr->width = newwidth;
01018 }
01019 
01020 //*************************************************************
01021 
01022 // put in new data, and put the command
01023 void DispCmdPickPointArray::putdata(int num, int numsel, int firstsel, int *on, 
01024 float *coords, VMDDisplayList *dobj) {
01025 if (numsel < 1)
01026 return;
01027 
01028 DispCmdPickPointArray *ptr;
01029 if (num == numsel) {
01030 // if all indices in a contiguous block are enabled (e.g. "all" selection)
01031 // then there's no need to actually store the pick point indices
01032 ptr = (DispCmdPickPointArray *) (dobj->append(DPICKPOINT_ARRAY, 
01033 sizeof(DispCmdPickPointArray) +
01034 3L * sizeof(float) * numsel));
01035 } else {
01036 // if only some of the indices are selected, then we allocate storage
01037 // for the list of indices to be copied in.
01038 ptr = (DispCmdPickPointArray *) (dobj->append(DPICKPOINT_ARRAY, 
01039 sizeof(DispCmdPickPointArray) + 
01040 3L * sizeof(float) * numsel +
01041 sizeof(int) * numsel));
01042 }
01043 
01044 if (ptr == NULL)
01045 return;
01046 
01047 ptr->numpicks = numsel;
01048 ptr->firstindex = firstsel;
01049 
01050 float *crds;
01051 int *tags;
01052 if (num == numsel) {
01053 // if all indices are selected note it, copy in coords, and we're done.
01054 ptr->allselected = 1;
01055 ptr->getpointers(crds, tags);
01056 memcpy(crds, coords, 3L * sizeof(float) * numsel);
01057 } else {
01058 // if only some indices are selected, copy in the selected ones
01059 ptr->allselected = 0;
01060 ptr->getpointers(crds, tags);
01061 
01062 // copy tags for selected/enabled indices
01063 ptrdiff_t cnt=numsel; // early-exit as soon as we found the last selected atom
01064 ptrdiff_t i, cp;
01065 for (cp=0,i=0; cnt > 0; i++) {
01066 if (on[i]) {
01067 cnt--;
01068 
01069 ptrdiff_t idx = i*3L;
01070 ptrdiff_t idx2 = cp*3L;
01071 crds[idx2 ] = coords[idx ];
01072 crds[idx2 + 1] = coords[idx + 1];
01073 crds[idx2 + 2] = coords[idx + 2];
01074 
01075 tags[cp] = i + firstsel;
01076 
01077 cp++;
01078 }
01079 }
01080 }
01081 }
01082 
01083 //*************************************************************
01084 
01085 // put in new data, and put the command
01086 void DispCmdPickPointArray::putdata(int num, int *indices,
01087 float *coords, VMDDisplayList *dobj) {
01088 DispCmdPickPointArray *ptr;
01089 
01090 ptr = (DispCmdPickPointArray *) (dobj->append(DPICKPOINT_ARRAY, 
01091 sizeof(DispCmdPickPointArray) + 
01092 3L * sizeof(float) * num +
01093 sizeof(int) * num));
01094 
01095 if (ptr == NULL)
01096 return;
01097 
01098 ptr->numpicks = num;
01099 ptr->allselected = 0; // use the index array entries
01100 ptr->firstindex = indices[0];
01101 
01102 float *crds;
01103 int *tags;
01104 ptr->getpointers(crds, tags);
01105 memcpy(crds, coords, num * 3L * sizeof(float));
01106 memcpy(tags, indices, num * sizeof(int));
01107 }
01108 

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

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