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

DispCmds.C

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

Generated on Thu Jun 20 01:49:32 2013 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002