Main Page   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

graspplugin.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr
00003  *cr            (C) Copyright 1995-2006 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: graspplugin.C,v $
00013  *      $Author: johns $       $Locker:  $             $State: Exp $
00014  *      $Revision: 1.17 $       $Date: 2006/02/23 19:36:44 $
00015  *
00016  ***************************************************************************/
00017 
00018 /* 
00019  * Reader for GRASP binary surface files
00020  * The file format is briefly described at these two sites:
00021  *   http://honiglab.cpmc.columbia.edu/grasp/grasp_contents.html#A.1
00022  *   http://www.msg.ucsf.edu/local/programs/grasp/html/Appendix%20A.html
00023  */
00024 #include <stdio.h>
00025 #include <math.h>
00026 #include <string.h>
00027 #include "molfile_plugin.h"
00028 #include "endianswap.h"
00029 
00030 static int is_little_endian(void) {
00031   int x=1;
00032   return *((char *)&x);
00033 }   
00034 
00035 typedef struct {
00036   FILE *fd;
00037   molfile_graphics_t *graphics;
00038 } grasp_t;
00039 
00040 static void *open_file_read(const char *filepath, const char *filetype,
00041     int *natoms) {
00042   FILE *fd;
00043   grasp_t *grasp;
00044   
00045   fd = fopen(filepath, "rb");
00046   if (!fd) 
00047     return NULL;
00048   grasp = new grasp_t;
00049   grasp->fd = fd;
00050   grasp->graphics = NULL;
00051   *natoms = 0;
00052   return grasp;
00053 }
00054 
00055 static int read_rawgraphics(void *v, int *nelem, 
00056     const molfile_graphics_t **data) {
00057   grasp_t *grasp = (grasp_t *)v;
00058   FILE *infile = grasp->fd;
00059 
00060   // Reverse engineering is your friend, and combined with FORTRAN code, voila!
00061   // od -c shows the header starts off:
00062   // \0  \0  \0   P   f   o   r   m   a   t   =   2
00063   // and according to ungrasp, this is a 1 for grasp versions 1.0
00064   // and 1.1, and 2 for grasp version 1.2
00065   // Also, the header lines are of length 80 characters + 4 header chars
00066   // + 4 trailer chars
00067   // The 4 bytes at the beginning/end are standard Fortran array trash
00068   char trash[4];
00069 #define TRASH fread(trash, 4, 1, infile)
00070   char line[81];
00071 
00072   // FIRST LINE OF HEADER; contains format type
00073   TRASH; 
00074   fread(line, 1, 80, infile); 
00075   // make sure it says 'format='
00076   if (strncmp(line, "format=", 7) != 0) {
00077     fprintf(stderr, "First characters of file don't look like a GRASP file\n");
00078     return MOLFILE_ERROR;
00079   }
00080   TRASH;
00081    
00082   // next char should be a 0 or 1
00083   char gfiletype = line[7];
00084   if (gfiletype == '1') {
00085     gfiletype = 1;
00086   } else if (gfiletype == '2') {
00087     gfiletype = 2;
00088   } else {
00089     fprintf(stderr, "GRASP file is in format %c, but only '1' or '2' is supported\n", gfiletype);
00090     return MOLFILE_ERROR;
00091   }
00092 
00093   // SECOND LINE: contains "vertices,accessibles,normals,triangles"
00094   TRASH; 
00095   fread(line, 1, 80, infile); 
00096   TRASH;
00097 
00098   // THIRD LINE: contains (0 or more of)?
00099   //  "potentials,curvature,distances,gproperty,g2property,vertexcolor
00100   char line3[81];
00101   TRASH; 
00102   fread(line3, 1, 80, infile); 
00103   line3[80] = 0;
00104   TRASH;
00105 
00106   // FOURTH LINE stores vertices, triangles, gridsize, lattice spacing
00107   int nvert, ntriangles, gridsize;
00108   float lattice;
00109   TRASH; 
00110   fread(line, 1, 80, infile); 
00111   TRASH;
00112   sscanf(line, "%d%d%d%f", &nvert, &ntriangles, &gridsize, &lattice);
00113 
00114   // FIFTH LINE stores the center (x,y,z) position
00115   float center[3];
00116   TRASH; 
00117   fread(line, 1, 80, infile); 
00118   TRASH;
00119   sscanf(line, "%f%f%f", center, center+1, center+2);
00120 
00121   float *vertex = new float[3 * nvert];
00122   float *access = new float[3 * nvert];
00123   float *normal = new float[3 * nvert];
00124   int *triangle = new int[3 * ntriangles];
00125 
00126   if (!vertex || !access || !normal || !triangle) {
00127     delete [] vertex;
00128     delete [] access;
00129     delete [] normal;
00130     delete [] triangle;
00131     fprintf(stderr, "Failed vertex/access/normal/triangle allocations.\n");
00132     return MOLFILE_ERROR;
00133   }
00134 
00135   // ungrasp says:
00136   //    if (filetype.eq.1) then integer*2
00137   //    if (filetype.eq.2) then integer*4
00138 
00139   // And read them in.  Who needs error checking?
00140   TRASH; 
00141   fread(vertex, 3 * sizeof(float), nvert, infile); 
00142   TRASH;
00143   TRASH; 
00144   fread(access, 3 * sizeof(float), nvert, infile); 
00145   TRASH;
00146   TRASH; 
00147   fread(normal, 3 * sizeof(float), nvert, infile); 
00148   TRASH;
00149 
00150   if (is_little_endian()) {
00151     swap4_aligned(vertex, 3*nvert);
00152     swap4_aligned(access, 3*nvert);
00153     swap4_aligned(normal, 3*nvert);
00154   }
00155 
00156   if (gfiletype == 2) {
00157     TRASH; 
00158     fread(triangle, 3 * sizeof(int), ntriangles, infile); 
00159     TRASH;
00160     if (is_little_endian())
00161       swap4_aligned(triangle, 3*ntriangles);
00162   } else {
00163 #if 1
00164     int i;
00165     short *striangle = new short[3 * ntriangles];
00166     if (!striangle) {
00167       delete [] vertex;
00168       delete [] access;
00169       delete [] normal;
00170       delete [] triangle;
00171       fprintf(stderr, "Failed short triangle allocation.\n");
00172       return MOLFILE_ERROR;
00173     }
00174 
00175     TRASH;
00176     fread(striangle, sizeof(short), 3 * ntriangles, infile);
00177     if (is_little_endian()) swap2_aligned(striangle, 3 * ntriangles);
00178     for (i=0; i<3*ntriangles; i++) {
00179       triangle[i] = striangle[i];
00180     }
00181     delete [] striangle;  
00182     TRASH;
00183 #else
00184     // do it the slow way (converting from short to int)
00185     int i;
00186     short tmp[3];
00187     TRASH;
00188     for (i=0; i<ntriangles; i++) {
00189       fread(tmp, sizeof(short), 3, infile);
00190       if (is_little_endian()) swap2_aligned(tmp, 3);
00191       triangle[3*i+0] = tmp[0];
00192       triangle[3*i+1] = tmp[1];
00193       triangle[3*i+2] = tmp[2];
00194     }
00195     TRASH;
00196 #endif
00197   }
00198 
00199   // And draw things
00200   grasp->graphics = new molfile_graphics_t[2*ntriangles];
00201   int vert1, vert2, vert3;
00202 
00203   for (int tri_count = 0; tri_count < ntriangles; tri_count++) {
00204     vert1 = triangle[3*tri_count+0] - 1;  // from 1-based FORTRAN
00205     vert2 = triangle[3*tri_count+1] - 1;  // to 0-based C++
00206     vert3 = triangle[3*tri_count+2] - 1;
00207 
00208     if (vert1 <      0 || vert2 <      0 || vert3 <      0 ||
00209         vert1 >= nvert || vert2 >= nvert || vert3 >= nvert) {
00210       printf("graspplugin) Error, out-of-range vertex index, aborting.\n"); 
00211       delete [] vertex;
00212       delete [] access;
00213       delete [] normal;
00214       delete [] triangle;
00215       return MOLFILE_ERROR;
00216     }
00217 
00218     grasp->graphics[2*tri_count  ].type = MOLFILE_TRINORM;
00219     grasp->graphics[2*tri_count+1].type = MOLFILE_NORMS;
00220 
00221     float *tridata =  grasp->graphics[2*tri_count  ].data;
00222     float *normdata = grasp->graphics[2*tri_count+1].data;
00223     memcpy(tridata  , vertex+3*vert1, 3*sizeof(float));
00224     memcpy(tridata+3, vertex+3*vert2, 3*sizeof(float));
00225     memcpy(tridata+6, vertex+3*vert3, 3*sizeof(float));
00226     memcpy(normdata  , normal+3*vert1, 3*sizeof(float));
00227     memcpy(normdata+3, normal+3*vert2, 3*sizeof(float));
00228     memcpy(normdata+6, normal+3*vert3, 3*sizeof(float));
00229   } 
00230 
00231   *nelem = 2*ntriangles;
00232   *data = grasp->graphics;
00233 
00234   delete [] triangle;
00235   delete [] normal;
00236   delete [] access;
00237   delete [] vertex;
00238 
00239   return MOLFILE_SUCCESS;
00240 }
00241 
00242 
00243 static void close_file_read(void *v) {
00244   grasp_t *grasp = (grasp_t *)v;
00245   fclose(grasp->fd);
00246   delete [] grasp->graphics;
00247   delete grasp;
00248 }
00249 
00250 
00251 /*
00252  * Initialization stuff here
00253  */
00254 static molfile_plugin_t plugin = {
00255   vmdplugin_ABIVERSION,               // ABI version
00256   MOLFILE_PLUGIN_TYPE,                // type of plugin
00257   "grasp",                            // short name of plugin
00258   "GRASP",                            // pretty name of plugin
00259   "Justin Gullingsrud, John Stone",   // author
00260   0,                                  // major version
00261   5,                                  // minor version
00262   VMDPLUGIN_THREADSAFE,               // is reentrant
00263   "srf,grasp"                         // filename extension 
00264 };
00265 
00266 VMDPLUGIN_API int VMDPLUGIN_init(void) { return VMDPLUGIN_SUCCESS; }
00267 VMDPLUGIN_API int VMDPLUGIN_fini(void) { return VMDPLUGIN_SUCCESS; }
00268 VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
00269   plugin.open_file_read = open_file_read;
00270   plugin.read_rawgraphics = read_rawgraphics;
00271   plugin.close_file_read = close_file_read;
00272   (*cb)(v, (vmdplugin_t *)&plugin);
00273   return VMDPLUGIN_SUCCESS;
00274 }
00275 
00276 

Generated on Wed Mar 22 13:15:29 2006 for VMD Plugins (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002