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.101 $      $Date: 2011/12/05 06:28:43 $
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 //*************************************************************
00322 // draw a mesh consisting of vertices, facets, colors, normals etc.
00323 void DispCmdTriMesh::putdata(const float * vertices,
00324                              const float * normals,
00325                              const float * colors,
00326                              int num_facets,
00327                              VMDDisplayList * dobj) {
00328   // make a triangle mesh (no strips)
00329   DispCmdTriMesh *ptr;
00330   if (colors == NULL) {
00331     ptr = (DispCmdTriMesh *) 
00332                 (dobj->append(DTRIMESH_C3F_N3F_V3F, sizeof(DispCmdTriMesh) +
00333                                         sizeof(float) * num_facets * 3 * 6));
00334   } else {
00335     ptr = (DispCmdTriMesh *) 
00336                 (dobj->append(DTRIMESH_C3F_N3F_V3F, sizeof(DispCmdTriMesh) +
00337                                         sizeof(float) * num_facets * 3 * 9));
00338   }
00339 
00340   if (ptr == NULL)
00341     return;
00342 
00343   ptr->numverts=num_facets * 3;
00344   ptr->numfacets=num_facets;
00345 
00346   float *c=NULL, *n=NULL, *v=NULL;
00347   if (colors == NULL) {
00348     ptr->pervertexcolors=0;
00349     ptr->getpointers(n, v);
00350   } else {
00351     ptr->pervertexcolors=1;
00352     ptr->getpointers(c, n, v);
00353     memcpy(c, colors,   ptr->numverts * 3 * sizeof(float));
00354   }
00355 
00356   memcpy(n, normals,  ptr->numverts * 3 * sizeof(float));
00357   memcpy(v, vertices, ptr->numverts * 3 * sizeof(float));
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 float * colors,
00365                              int num_verts,
00366                              const int * facets,
00367                              int num_facets, 
00368                              int enablestrips,
00369                              VMDDisplayList * dobj) {
00370   int builtstrips = 0; 
00371 
00372 #if defined(VMDACTC) 
00373   if (enablestrips)  {
00374     // Rearrange face data into triangle strips
00375     ACTCData *tc = actcNew();  // intialize ACTC stripification library
00376     int fsize = num_facets * 3;
00377     int i, ind, ii;
00378     int iPrimCount = 0;
00379     int iCurrPrimSize;
00380 
00381     // XXX over-allocate the vertex and facet buffers to prevent an
00382     //     apparent bug in ACTC 1.1 from crashing VMD.  This was causing
00383     //     Surf surfaces to crash ACTC at times.
00384     int *p_iPrimSize = new int[fsize + 6];  // num vertices in a primitive 
00385     unsigned int *f2 = new uint[fsize + 6];
00386     
00387     if (tc == NULL) {
00388       msgErr << "ACTC initialization failed, using triangle mesh." << sendmsg;
00389     } else {
00390       msgInfo << "Performing ACTC Triangle Consolidation..." << sendmsg;
00391  
00392       // only produce strips, not fans, give a ridiculously high min value.
00393       actcParami(tc, ACTC_OUT_MIN_FAN_VERTS, 2147483647);
00394 
00395       // disabling honoring vertex winding order might allow ACTC to
00396       // consolidate more triangles into strips, but this is only useful
00397       // if VMD has two-sided lighting enabled.
00398       // actcParami(tc, ACTC_OUT_HONOR_WINDING, ACTC_TRUE);
00399         
00400       // send triangle data over to ACTC library
00401       actcBeginInput(tc);
00402       for (ii=0; ii < num_facets; ii++) {
00403         ind = ii * 3;
00404         if ((actcAddTriangle(tc, facets[ind], facets[ind + 1], facets[ind + 2])) != ACTC_NO_ERROR) {
00405           msgInfo << "ACTC Add Triangle Error." << sendmsg;
00406         }
00407       }
00408       actcEndInput(tc);
00409         
00410       // get triangle strips back from ACTC, loop through once to get sizes
00411       actcBeginOutput(tc);
00412       i = 0;
00413       while ((actcStartNextPrim(tc, &f2[i], &f2[i+1]) != ACTC_DATABASE_EMPTY)) {
00414         iCurrPrimSize = 2;  // if we're here, we got 2 vertices
00415         i+=2;               // increment array position
00416         while (actcGetNextVert(tc, &f2[i]) != ACTC_PRIM_COMPLETE) {
00417           iCurrPrimSize++;  // increment number of vertices for this primitive
00418           i++;              // increment array position
00419         }
00420 
00421         p_iPrimSize[iPrimCount] = iCurrPrimSize;  // save vertex count
00422         iPrimCount++;       // increment primitive counter
00423       }
00424       actcEndOutput(tc);
00425       msgInfo << "ACTC: Created " << iPrimCount << " triangle strips" << sendmsg;
00426       msgInfo << "ACTC: Average vertices per strip = " << i / iPrimCount  << sendmsg;
00427 
00428       // Draw triangle strips, uses double-sided lighting until we change
00429       // things to allow the callers to specify the desired lighting 
00430       // explicitly.
00431       DispCmdTriStrips::putdata(vertices, normals, colors, num_verts, p_iPrimSize, iPrimCount, f2, i, 1, dobj);
00432           
00433       // delete temporary memory
00434       delete [] f2;
00435       delete [] p_iPrimSize;
00436 
00437       // delete ACTC handle
00438       actcDelete(tc);
00439 
00440       builtstrips = 1; // don't generate a regular triangle mesh
00441     }  
00442   } 
00443 #endif
00444 
00445   if (!builtstrips) {
00446     // make a triangle mesh (no strips)
00447     DispCmdTriMesh *ptr = (DispCmdTriMesh *) 
00448                   (dobj->append(DTRIMESH_C4F_N3F_V3F, sizeof(DispCmdTriMesh) +
00449                                           sizeof(float) * num_verts * 10 +
00450                                           sizeof(int) * num_facets * 3));
00451     if (ptr == NULL)
00452       return;
00453     ptr->pervertexcolors=1;
00454     ptr->numverts=num_verts;
00455     ptr->numfacets=num_facets;
00456     float *cnv;
00457     int *f;
00458     ptr->getpointers(cnv, f);
00459 
00460 #if 1
00461     int ind10, ind3;
00462     for (ind10=0,ind3=0; ind10<num_verts*10; ind10+=10,ind3+=3) {
00463       cnv[ind10    ] =   colors[ind3    ];
00464       cnv[ind10 + 1] =   colors[ind3 + 1]; 
00465       cnv[ind10 + 2] =   colors[ind3 + 2]; 
00466       cnv[ind10 + 3] =   1.0; 
00467       cnv[ind10 + 4] =  normals[ind3    ];
00468       cnv[ind10 + 5] =  normals[ind3 + 1];
00469       cnv[ind10 + 6] =  normals[ind3 + 2];
00470       cnv[ind10 + 7] = vertices[ind3    ];
00471       cnv[ind10 + 8] = vertices[ind3 + 1];
00472       cnv[ind10 + 9] = vertices[ind3 + 2];
00473     }
00474 #else
00475     int i, ind, ind2;
00476     for (i=0; i<num_verts; i++) {
00477       ind = i * 10;
00478       ind2 = i * 3;
00479       cnv[ind    ] =   colors[ind2    ];
00480       cnv[ind + 1] =   colors[ind2 + 1]; 
00481       cnv[ind + 2] =   colors[ind2 + 2]; 
00482       cnv[ind + 3] =   1.0; 
00483       cnv[ind + 4] =  normals[ind2    ];
00484       cnv[ind + 5] =  normals[ind2 + 1];
00485       cnv[ind + 6] =  normals[ind2 + 2];
00486       cnv[ind + 7] = vertices[ind2    ];
00487       cnv[ind + 8] = vertices[ind2 + 1];
00488       cnv[ind + 9] = vertices[ind2 + 2];
00489     } 
00490 #endif
00491 
00492     memcpy(f, facets, ptr->numfacets * 3 * sizeof(int));
00493   }
00494 }
00495 
00496 //*************************************************************
00497 
00498 // draw a set of triangle strips
00499 void DispCmdTriStrips::putdata(const float * vertices,
00500                                const float * normals,
00501                                const float * colors,
00502                                int num_verts,
00503                                const int * verts_per_strip,
00504                                int num_strips,
00505                                const unsigned int * strip_data,
00506                                const int num_strip_verts,
00507                                int double_sided_lighting,
00508                                VMDDisplayList * dobj) {
00509 
00510   DispCmdTriStrips *ptr = (DispCmdTriStrips *) (dobj->append(DTRISTRIP, 
00511                                          sizeof(DispCmdTriStrips) +
00512                                          sizeof(int *) * num_strips +
00513                                          sizeof(float) * num_verts * 10 +
00514                                          sizeof(int) * num_strip_verts +
00515                                          sizeof(int) * num_strips));
00516   if (ptr == NULL) 
00517     return;
00518   ptr->numverts=num_verts;
00519   ptr->numstrips=num_strips;
00520   ptr->numstripverts=num_strip_verts;
00521   ptr->doublesided=double_sided_lighting;
00522 
00523   float *cnv;
00524   int *f;
00525   int *vertsperstrip;
00526   ptr->getpointers(cnv, f, vertsperstrip);
00527 
00528   // copy vertex,color,normal data
00529   int i, ind, ind2;
00530   for (i=0; i<num_verts; i++) {
00531     ind = i * 10;
00532     ind2 = i * 3;
00533     cnv[ind    ] =   colors[ind2    ];
00534     cnv[ind + 1] =   colors[ind2 + 1];
00535     cnv[ind + 2] =   colors[ind2 + 2];
00536     cnv[ind + 3] =   1.0;
00537     cnv[ind + 4] =  normals[ind2    ];
00538     cnv[ind + 5] =  normals[ind2 + 1];
00539     cnv[ind + 6] =  normals[ind2 + 2];
00540     cnv[ind + 7] = vertices[ind2    ];
00541     cnv[ind + 8] = vertices[ind2 + 1];
00542     cnv[ind + 9] = vertices[ind2 + 2];
00543   }
00544 
00545   // copy vertices per strip data
00546   for (i=0; i<num_strips; i++) {
00547     vertsperstrip[i] = verts_per_strip[i];
00548   }
00549 
00550   // copy face (triangle) data
00551   for (i=0; i<num_strip_verts; i++) {
00552     f[i] = strip_data[i];
00553   }
00554 }
00555 
00556 
00557 //*************************************************************
00558 
00559 void DispCmdWireMesh::putdata(const float * vertices,
00560                              const float * normals,
00561                              const float * colors,
00562                              int num_verts,
00563                              const int * lines,
00564                              int num_lines, VMDDisplayList * dobj) {
00565  
00566   DispCmdWireMesh *ptr = (DispCmdWireMesh *) (dobj->append(DWIREMESH, 
00567                                          sizeof(DispCmdWireMesh) +
00568                                          sizeof(float) * num_verts * 10 +
00569                                          sizeof(int) * num_lines * 3));
00570   if (ptr == NULL) 
00571     return;
00572   ptr->numverts=num_verts;
00573   ptr->numlines=num_lines;
00574 
00575   float *cnv;
00576   int *l;
00577   ptr->getpointers(cnv, l);
00578 
00579   int i, ind, ind2;
00580   for (i=0; i<num_verts; i++) {
00581     ind = i * 10;
00582     ind2 = i * 3;
00583     cnv[ind    ] =   colors[ind2    ];
00584     cnv[ind + 1] =   colors[ind2 + 1]; 
00585     cnv[ind + 2] =   colors[ind2 + 2]; 
00586     cnv[ind + 3] =   1.0; 
00587     cnv[ind + 4] =  normals[ind2    ];
00588     cnv[ind + 5] =  normals[ind2 + 1];
00589     cnv[ind + 6] =  normals[ind2 + 2];
00590     cnv[ind + 7] = vertices[ind2    ];
00591     cnv[ind + 8] = vertices[ind2 + 1];
00592     cnv[ind + 9] = vertices[ind2 + 2];
00593   } 
00594 
00595   memcpy(l, lines, ptr->numlines * 2 * sizeof(int));
00596 }
00597 
00598 //*************************************************************
00599 // plot a cylinder at the given position
00600 // this is used to precalculate the cylinder data for speedup
00601 // in renderers without hardware cylinders.  For example, the GL
00602 // library.  There are res number of edges (with a norm, and two points)
00603 
00604 DispCmdCylinder::DispCmdCylinder(void) {
00605   lastres = 0;
00606 }
00607 
00608 void DispCmdCylinder::putdata(const float *pos1, const float *pos2, float rad, 
00609                       int res, int filled, VMDDisplayList *dobj) {
00610 
00611   float lenaxis[3];
00612   vec_sub(lenaxis, pos1, pos2);  // check that it's valid
00613   if (dot_prod(lenaxis,lenaxis) == 0.0 || res <= 0) return;
00614 
00615   if (lastres != res ) {
00616     rot[0] = cosf( (float) VMD_TWOPI / (float) res);
00617     rot[1] = sinf( (float) VMD_TWOPI / (float) res);
00618   }
00619   lastres = res;
00620   size_t size = (9 + res*3*3)*sizeof(float);
00621 
00622   float *pos = (float *)(dobj->append(DCYLINDER, size));
00623   if (pos == NULL) 
00624     return;
00625 
00626   memcpy(pos,pos1,3*sizeof(float));
00627   memcpy(pos+3,pos2,3*sizeof(float));
00628   pos[6] = rad;
00629   pos[7] = (float)res;
00630   pos[8] = (float)filled;
00631 
00632   float axis[3];
00633   vec_sub(axis, pos1, pos2);
00634   vec_normalize(axis);
00635   int i;  // find an axis not aligned with the cylinder
00636   if (fabs(axis[0]) < fabs(axis[1]) &&
00637       fabs(axis[0]) < fabs(axis[2])) {
00638      i = 0;
00639   } else if (fabs(axis[1]) < fabs(axis[2])) {
00640      i = 1;
00641   } else {
00642      i = 2;
00643   }
00644   float perp[3];
00645   perp[i] = 0;                    // this is not aligned with the cylinder
00646   perp[(i+1)%3] = axis[(i+2)%3];
00647   perp[(i+2)%3] = -axis[(i+1)%3];
00648   vec_normalize(perp);
00649   float perp2[3];
00650   cross_prod(perp2, axis, perp); // find a normal to the cylinder
00651 
00652   float *posptr = pos+9;
00653   float m = rot[0], n = rot[1];
00654   for (int h=0; h<res; h++) {
00655     float tmp0, tmp1, tmp2;
00656     
00657     tmp0 = m*perp[0] + n*perp2[0]; // add the normal
00658     tmp1 = m*perp[1] + n*perp2[1];
00659     tmp2 = m*perp[2] + n*perp2[2];
00660 
00661     posptr[0] = tmp0; // add the normal
00662     posptr[1] = tmp1;
00663     posptr[2] = tmp2;
00664 
00665     posptr[3] = pos2[0] + rad * tmp0; // start
00666     posptr[4] = pos2[1] + rad * tmp1;
00667     posptr[5] = pos2[2] + rad * tmp2;
00668 
00669     posptr[6] = posptr[3] + lenaxis[0];  // and end of the edge
00670     posptr[7] = posptr[4] + lenaxis[1];
00671     posptr[8] = posptr[5] + lenaxis[2];
00672     posptr += 9;
00673     // use angle addition formulae:
00674     // cos(A+B) = cos A cos B - sin A sin B
00675     // sin(A+B) = cos A sin B + sin A cos B
00676     float mtmp = rot[0]*m - rot[1]*n;
00677     float ntmp = rot[0]*n + rot[1]*m; 
00678     m = mtmp;
00679     n = ntmp;
00680   }
00681 }
00682  
00683 //*************************************************************
00684 
00685 void DispCmdCone::putdata(float *p1,float *p2,float newrad,float newrad2,int newres,
00686                           VMDDisplayList *dobj) {
00687   DispCmdCone *ptr = (DispCmdCone *)(dobj->append(DCONE, 
00688                                          sizeof(DispCmdCone)));
00689   if (ptr == NULL) 
00690     return;
00691   memcpy(ptr->pos1,p1,3*sizeof(float));
00692   memcpy(ptr->pos2,p2,3*sizeof(float));
00693   ptr->radius=newrad;
00694   ptr->radius2=newrad2;
00695   ptr->res=newres;
00696 }
00697 
00698 // put in new data, and put the command
00699 void DispCmdColorIndex::putdata(int newcol, VMDDisplayList *dobj) {
00700   DispCmdColorIndex *ptr = (DispCmdColorIndex *)(dobj->append(DCOLORINDEX, 
00701                                          sizeof(DispCmdColorIndex)));
00702   if (ptr == NULL) 
00703     return;
00704   ptr->color = newcol;
00705 }
00706 
00707 //*************************************************************
00708 
00709 // display text at the given text coordinates
00710 void DispCmdText::putdata(const float *c, const char *s, 
00711                           float thickness, VMDDisplayList *dobj) {
00712   if (s != NULL) {
00713     size_t len = strlen(s)+1;
00714     char *buf = (char *)(dobj->append(DTEXT, len+4*sizeof(float)));
00715     if (buf == NULL) 
00716       return;
00717     ((float *)buf)[0] = c[0];          // X
00718     ((float *)buf)[1] = c[1];          // Y
00719     ((float *)buf)[2] = c[2];          // Z
00720     ((float *)buf)[3] = thickness;     // thickness
00721     memcpy(buf+4*sizeof(float),s,len); // text string
00722   }
00723 }
00724 
00725 void DispCmdTextOffset::putdata(float ox, float oy, VMDDisplayList *dobj) {
00726   DispCmdTextOffset *cmd = (DispCmdTextOffset *)(dobj->append(DTEXTOFFSET,
00727         sizeof(DispCmdTextOffset)));
00728   cmd->x = ox;
00729   cmd->y = oy;
00730 }
00731 
00732 //*************************************************************
00733 
00734 void DispCmdTextSize::putdata(float size1, VMDDisplayList *dobj) {
00735   DispCmdTextSize *ptr  = (DispCmdTextSize *)dobj->append(DTEXTSIZE,
00736                            sizeof(DispCmdTextSize));
00737   if (ptr == NULL)
00738     return;
00739   ptr->size = size1;
00740 }
00741 
00742 //*************************************************************
00743 
00744 void DispCmdVolSlice::putdata(int mode, const float *pnormal, const float *verts, 
00745     const float *texs, VMDDisplayList *dobj) {
00746 
00747   DispCmdVolSlice *cmd = (DispCmdVolSlice *) dobj->append(DVOLSLICE, 
00748                                        sizeof(DispCmdVolSlice));
00749   if (cmd == NULL)
00750     return;
00751 
00752   cmd->texmode = mode;
00753   memcpy(cmd->normal, pnormal, 3*sizeof(float));
00754   memcpy(cmd->v, verts, 12*sizeof(float));
00755   memcpy(cmd->t, texs,  12*sizeof(float));
00756 }
00757 
00758 //*************************************************************
00759 
00760 
00761 void DispCmdVolumeTexture::putdata(unsigned long texID, 
00762     const int size[3], unsigned char *texptr, const float pv0[3], 
00763     const float pv1[3], const float pv2[3], const float pv3[3], 
00764     VMDDisplayList *dobj) {
00765 
00766   DispCmdVolumeTexture *cmd = (DispCmdVolumeTexture *) dobj->append(DVOLUMETEXTURE,
00767       sizeof(DispCmdVolumeTexture));
00768 
00769   if (cmd == NULL) return;
00770 
00771   cmd->ID = texID;
00772   cmd->xsize = size[0];
00773   cmd->ysize = size[1];
00774   cmd->zsize = size[2];
00775   cmd->texmap = texptr;
00776   memcpy(cmd->v0, pv0, 3*sizeof(float));
00777   memcpy(cmd->v1, pv1, 3*sizeof(float));
00778   memcpy(cmd->v2, pv2, 3*sizeof(float));
00779   memcpy(cmd->v3, pv3, 3*sizeof(float));
00780 }
00781 
00782 //*************************************************************
00783 // put in new data, and put the command
00784 void DispCmdSphereRes::putdata(int newres, VMDDisplayList *dobj) {
00785   DispCmdSphereRes *ptr  = (DispCmdSphereRes *)dobj->append(DSPHERERES,
00786                            sizeof(DispCmdSphereRes));
00787   if (ptr == NULL)
00788     return;
00789   ptr->res = newres;
00790 }
00791 
00792 //*************************************************************
00793 
00794 // put in new data, and put the command
00795 void DispCmdSphereType::putdata(int newtype, VMDDisplayList *dobj) {
00796   DispCmdSphereType *ptr  = (DispCmdSphereType *)dobj->append(DSPHERETYPE,
00797                            sizeof(DispCmdSphereType));
00798   if (ptr == NULL)
00799     return;
00800   ptr->type = newtype;
00801 }
00802 
00803 //*************************************************************
00804 
00805 // put in new data, and put the command
00806 void DispCmdLineType::putdata(int newtype, VMDDisplayList *dobj) {
00807   DispCmdLineType* ptr  = (DispCmdLineType *)dobj->append(DLINESTYLE,
00808                            sizeof(DispCmdLineType));
00809   if (ptr == NULL)
00810     return;
00811   ptr->type = newtype;
00812 }
00813 
00814 //*************************************************************
00815 
00816 void DispCmdLineWidth::putdata(int newwidth, VMDDisplayList *dobj) {
00817   DispCmdLineWidth * ptr  = (DispCmdLineWidth *)dobj->append(DLINEWIDTH,
00818                            sizeof(DispCmdLineWidth));
00819   if (ptr == NULL)
00820     return;
00821   ptr->width = newwidth;
00822 }
00823 
00824 //*************************************************************
00825 
00826 void DispCmdPickPoint::putdata(float *pos, int newtag, VMDDisplayList *dobj) {
00827   DispCmdPickPoint *ptr = (DispCmdPickPoint *)(dobj->append(DPICKPOINT, 
00828                                                sizeof(DispCmdPickPoint)));
00829   if (ptr == NULL)
00830     return;
00831   memcpy(ptr->postag,pos,3*sizeof(float));
00832   ptr->tag=newtag;
00833 }
00834 
00835 //*************************************************************
00836 
00837 // put in new data, and put the command
00838 void DispCmdPickPointArray::putdata(int num, int numsel, int firstsel, int *on, 
00839                                     float *coords, VMDDisplayList *dobj) {
00840   if (numsel < 1)
00841     return;
00842 
00843   DispCmdPickPointArray *ptr;
00844   if (num == numsel) {
00845     // if all indices in a contiguous block are enabled (e.g. "all" selection)
00846     // then there's no need to actually store the pick point indices
00847     ptr = (DispCmdPickPointArray *) (dobj->append(DPICKPOINT_ARRAY, 
00848                                      sizeof(DispCmdPickPointArray) +
00849                                      3 * sizeof(float) * numsel));
00850   } else {
00851     // if only some of the indices are selected, then we allocate storage
00852     // for the list of indices to be copied in.
00853     ptr = (DispCmdPickPointArray *) (dobj->append(DPICKPOINT_ARRAY, 
00854                                      sizeof(DispCmdPickPointArray) + 
00855                                      3 * sizeof(float) * numsel +
00856                                      sizeof(int) * numsel));
00857   }
00858 
00859   if (ptr == NULL)
00860     return;
00861 
00862   ptr->numpicks = numsel;
00863   ptr->firstindex = firstsel;
00864 
00865   float *crds;
00866   int *tags;
00867   if (num == numsel) {
00868     // if all indices are selected note it, copy in coords, and we're done.
00869     ptr->allselected = 1;
00870     ptr->getpointers(crds, tags);
00871     memcpy(crds, coords, 3 * sizeof(float) * numsel);
00872   } else {
00873     // if only some indices are selected, copy in the selected ones
00874     ptr->allselected = 0;
00875     ptr->getpointers(crds, tags);
00876 
00877     // copy tags for selected/enabled indices
00878     int cnt=numsel; // early-exit as soon as we found the last selected atom
00879     int i,cp;
00880     for (cp=0,i=0; cnt > 0; i++) {
00881       if (on[i]) {
00882         cnt--;
00883 
00884         int idx = i*3;
00885         int idx2 = cp*3;
00886         crds[idx2    ] = coords[idx    ];
00887         crds[idx2 + 1] = coords[idx + 1];
00888         crds[idx2 + 2] = coords[idx + 2];
00889 
00890         tags[cp] = i + firstsel;
00891 
00892         cp++;
00893       }
00894     }
00895   }
00896 }
00897 
00898 //*************************************************************
00899 
00900 // put in new data, and put the command
00901 void DispCmdPickPointArray::putdata(int num, int *indices,
00902                                     float *coords, VMDDisplayList *dobj) {
00903   DispCmdPickPointArray *ptr;
00904 
00905   ptr = (DispCmdPickPointArray *) (dobj->append(DPICKPOINT_ARRAY, 
00906                                    sizeof(DispCmdPickPointArray) + 
00907                                    3 * sizeof(float) * num +
00908                                    sizeof(int) * num));
00909 
00910   if (ptr == NULL)
00911     return;
00912 
00913   ptr->numpicks = num;
00914   ptr->allselected = 0; // use the index array entries
00915   ptr->firstindex = indices[0];
00916 
00917   float *crds;
00918   int *tags;
00919   ptr->getpointers(crds, tags);
00920   memcpy(crds, coords, num * 3 * sizeof(float));
00921   memcpy(tags, indices, num * sizeof(int));
00922 }
00923 

Generated on Sat May 26 01:47:52 2012 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002