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

molemeshplugin.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr
00003  *cr            (C) Copyright 1995-2016 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: molemeshplugin.C,v $
00013  *      $Author: johns $       $Locker:  $             $State: Exp $
00014  *      $Revision: 1.3 $       $Date: 2016/11/28 05:01:54 $
00015  *
00016  ***************************************************************************/
00017 
00018 /*
00019  *  quadrilaterals are used to represent the geometry. 
00020  *
00021  *  ASCII pmesh file from mole 2.0 follows the following format. Files are case 
00022 insensitive
00023  *  and whitespace is ignored.
00024  *
00025  *  number of vertices        ()
00026  *  vertex v1x v1y v1z        (<v1> is the first vertex)
00027  *  vertex v2x v2y v2z        (vertices are given in some order)
00028  *  vertex v3x v3y v3z        (vertices are given as floating-point values)
00029  *  vertex v4x v4y v4z        (vertices are given as floating-point values)
00030  *  number of polygons/faces  
00031  *  face number               (in groups of 4?)
00032  */
00033 
00034 #include <stdlib.h>
00035 #include <stdio.h>
00036 #include <ctype.h>
00037 #include <math.h>
00038 #include <string.h>
00039 
00040 #if defined(_AIX)
00041 #include <strings.h>
00042 #endif
00043 
00044 #if defined(WIN32) || defined(WIN64)
00045 #define strcasecmp stricmp
00046 #endif
00047  
00048 #include "molfile_plugin.h"
00049 
00050 typedef struct graphics_list {
00051   molfile_graphics_t gItem;
00052   struct graphics_list *next;
00053 } molfile_graphics_list;
00054 
00055 typedef struct {
00056   FILE *fd;
00057   molfile_graphics_t *graphics;
00058 } pmesh_t;
00059 
00060 static void *open_file_read(const char *filepath, const char *filetype, int *natoms) {
00061    FILE *fd;
00062    pmesh_t *pmesh;
00063 
00064    fd = fopen(filepath, "rb");
00065    if (!fd) {
00066      fprintf(stderr, "molemeshplugin) Error opening file.\n");
00067      return NULL;
00068    }
00069    pmesh = new pmesh_t;
00070    pmesh->fd = fd;
00071    pmesh->graphics = NULL;
00072    *natoms = 0;
00073    return pmesh;
00074 } 
00075 static int read_rawgraphics(void *v, int *nelem, const molfile_graphics_t **data) {
00076     molfile_graphics_list *gListPtr=NULL, *tmpPtr=NULL;
00077     int i=0, ntriangles=0,j=0;
00078     int error=0, numVerts=0, numFacets=0, facetType=0, facet=0, tmpFacet[5];
00079     pmesh_t *pmesh = (pmesh_t *)v;
00080     FILE *infile = pmesh->fd;
00081     char line[81];
00082     float **tmpData;
00083 
00084     // Check your head(er)
00085     // "number of vertices"
00086     fgets(line, 80, infile);
00087     sscanf(line, "%d", &numVerts);
00088     if (numVerts  < 1) {
00089       fprintf(stderr, "molespmeshplugin) error: expected \"Positive Number of Vertices\".\n");
00090       error = 1;
00091       return MOLFILE_ERROR;
00092     } else {
00093      gListPtr = new molfile_graphics_list;
00094      gListPtr->next = NULL;
00095      gListPtr->gItem.type = MOLFILE_TRIANGLE;
00096      ntriangles++;
00097      tmpPtr = gListPtr;
00098    }
00099 
00100 //Allocate memory for 2d array.  maybe there is a better way to do this.
00101     tmpData = new float*[numVerts];
00102     for (int h=0 ; h < numVerts ; h++ ) {
00103          tmpData[h] = new float[3];
00104     }
00105 
00106 //we know how many vertices there are read them all into tmpData[j][i]
00107    for ( j=0 ; j < numVerts; j++) {
00108 // "first loop"
00109 // scan each vertex vx, vy, vz  
00110     i=0;
00111     fgets(line, 80, infile);
00112     float t1=0.0f, t2=0.0f, t3=0.0f;
00113     if ( sscanf(line, "%f %f %f", &t1, &t2, &t3) == 3 ) {
00114         tmpData[j][i++] = t1;
00115         tmpData[j][i++] = t2;
00116         tmpData[j][i++] = t3;
00117      } else if(ferror(infile)) {
00118        fprintf(stderr, "molespmeshplugin) error: problem reading file\n");
00119        error = 1;
00120        return MOLFILE_ERROR;
00121      }
00122    }
00123 //Read in the total number of facets.  For pmesh files the next number is the total number of triangle or quadrilaterals
00124 //If triangles, then the next number after the total is a 4, and the next four numbers after that describe the vertex index for
00125 //each point of the triangle.  If the set begins with a 5 then the next 5 numbers describe the vertex number for
00126 //each point of the quadrilateral.  So far this reader does not support multiple/concatenated mpesh files yet.
00127    fgets(line, 80, infile);
00128    sscanf(line, "%d", &numFacets);
00129 //printf("numFacets %d \n",numFacets);
00130    if (numFacets  < 1) {
00131       fprintf(stderr, "molespmeshplugin) error: expected \"Positive Number of Facets\".\n");
00132       error = 1;
00133       return MOLFILE_ERROR;
00134     } else {
00135      gListPtr = new molfile_graphics_list;
00136 
00137      gListPtr->next = NULL;
00138      gListPtr->gItem.type = MOLFILE_TRIANGLE;
00139      ntriangles++;
00140      tmpPtr = gListPtr;
00141    }
00142 //Read in the facet type 4=triangle 5=quadrilateral. need to do a while loop here, as long as xxxx<numFacets keep reading
00143    while ( !feof(infile) && ( error == 0 ) ) {
00144      fgets(line, 80, infile);
00145      sscanf(line, "%d", &facetType);
00146      if (facetType == 4) {
00147 //printf("facetype %d \n", facetType);
00148         int l=0;
00149         for (int k=0 ; k < facetType-1; k++) {
00150               fgets(line, 80, infile);
00151               sscanf(line, "%d", &facet);
00152               tmpPtr->gItem.data[l++] = tmpData[facet][0];
00153               tmpPtr->gItem.data[l++] = tmpData[facet][1];
00154               tmpPtr->gItem.data[l++] = tmpData[facet][2];
00155          }
00156      fgets(line, 80, infile); //one more read to keep us in sync
00157 // Create a new list item and initialize it for second triangle.
00158          tmpPtr->next = new molfile_graphics_list;
00159          tmpPtr = tmpPtr->next;
00160          tmpPtr->next = NULL;
00161          tmpPtr->gItem.type = MOLFILE_TRIANGLE;
00162          ntriangles++;
00163      } else if (facetType == 5 ) { 
00164                 for (int k=0 ; k < facetType-1; k++) {
00165                      fgets(line, 80, infile);
00166                      sscanf(line, "%d", &facet);
00167                      tmpFacet[k]=facet;
00168                 }
00169               
00170                 tmpPtr->gItem.data[0] = tmpData[tmpFacet[0]][0];
00171                 tmpPtr->gItem.data[1] = tmpData[tmpFacet[0]][1];
00172                 tmpPtr->gItem.data[2] = tmpData[tmpFacet[0]][2];
00173 
00174                 tmpPtr->gItem.data[3] = tmpData[tmpFacet[1]][0];
00175                 tmpPtr->gItem.data[4] = tmpData[tmpFacet[1]][1];
00176                 tmpPtr->gItem.data[5] = tmpData[tmpFacet[1]][2];
00177 
00178                 tmpPtr->gItem.data[6] = tmpData[tmpFacet[2]][0];
00179                 tmpPtr->gItem.data[7] = tmpData[tmpFacet[2]][1];
00180                 tmpPtr->gItem.data[8] = tmpData[tmpFacet[2]][2];
00181 
00182 // Create a new list item and initialize it for second triangle.
00183                 tmpPtr->next = new molfile_graphics_list;
00184                 tmpPtr = tmpPtr->next;
00185                 tmpPtr->next = NULL;
00186                 tmpPtr->gItem.type = MOLFILE_TRIANGLE;
00187                 ntriangles++;
00188 
00189                 tmpPtr->gItem.data[0] = tmpData[tmpFacet[0]][0];
00190                 tmpPtr->gItem.data[1] = tmpData[tmpFacet[0]][1];
00191                 tmpPtr->gItem.data[2] = tmpData[tmpFacet[0]][2];
00192 
00193                 tmpPtr->gItem.data[3] = tmpData[tmpFacet[2]][0];
00194                 tmpPtr->gItem.data[4] = tmpData[tmpFacet[2]][1];
00195                 tmpPtr->gItem.data[5] = tmpData[tmpFacet[2]][2];
00196 
00197                 tmpPtr->gItem.data[6] = tmpData[tmpFacet[3]][0];
00198                 tmpPtr->gItem.data[7] = tmpData[tmpFacet[3]][1];
00199                 tmpPtr->gItem.data[8] = tmpData[tmpFacet[3]][2];
00200 
00201 // Create a new list item and initialize it for first triangle of the second quadrilateral.
00202                 tmpPtr->next = new molfile_graphics_list;
00203                 tmpPtr = tmpPtr->next;
00204                 tmpPtr->next = NULL;
00205                 tmpPtr->gItem.type = MOLFILE_TRIANGLE;
00206                 ntriangles++;
00207      } else if ( (facetType != 4 || facetType != 5) && facetType >= 6 ) {
00208 //Find out if this is a concatenated file by reading the next value and testing for a series of three floats.
00209 //If so, free tmpData and reallocate according to this number. then read all the vertices into tmpData and do
00210 //a drop back into the while loop.
00211 //If not, exit with error.
00212          fgets(line, 80, infile);
00213          float t1=0.0f, t2=0.0f, t3=0.0f;
00214          if ( sscanf(line, "%f %f %f", &t1,&t2,&t3) ==3 ) {
00215 //free tmpData
00216              for (int x=0; x< 3; x++) free(tmpData[x]);
00217                   free (tmpData);
00218              numVerts=facetType;
00219              facetType=0;
00220 //Allocate new size for vertices array
00221              tmpData = new float*[numVerts];
00222              for (int h=0 ; h < numVerts ; h++ ) {
00223                  tmpData[h] = new float[3];
00224              }
00225 
00226 //Read in all new vertices after adding the first test vertex
00227              tmpData[0][0] = t1;
00228              tmpData[0][1] = t2;
00229              tmpData[0][2] = t3;
00230              for ( j=1 ; j < numVerts; j++) {
00231                  i=0;
00232                  fgets(line, 80, infile);
00233                  float t1=0.0f, t2=0.0f, t3=0.0f;
00234                  if ( sscanf(line, "%f %f %f", &t1, &t2, &t3) == 3 ) {
00235                     tmpData[j][i++] = t1;
00236                     tmpData[j][i++] = t2;
00237                     tmpData[j][i++] = t3;
00238                  } else if(ferror(infile)) {
00239                            fprintf(stderr, "molespmeshplugin) error: problem reading vertices from concatenated file\n");
00240                            error = 1;
00241                            break;
00242                 }
00243              }
00244          } else if ( feof(infile)  ) {
00245 //end file read gracefully at the last facet
00246                     break;
00247          } else { fprintf(stderr, "molespmeshplugin) error: problem reading concatenated file?\n");
00248                 error = 1;
00249                 break;
00250          }
00251          fgets(line, 80, infile);
00252          sscanf(line, "%d", &numFacets);
00253          if (numFacets  < 1) {
00254             fprintf(stderr, "molespmeshplugin) error: expected \"Positive Number of Facets\".\n");
00255            error = 1;
00256          }
00257      }
00258 //go back into the while loop with error=0 so that we can reuse the facet code
00259 //for additional meshes
00260      error = 0;
00261     }
00262     // If an error occurred, free the linked list and return MOLFILE_ERROR
00263     if (error != 0) {
00264       while (gListPtr != NULL) {
00265         tmpPtr = gListPtr->next;
00266         delete gListPtr;
00267         gListPtr = tmpPtr;
00268       }
00269      for (int x=0; x< 3; x++) free(tmpData[x]);
00270      free (tmpData);
00271       return MOLFILE_ERROR;
00272     }
00273 
00274     // Create the array of molfile_graphics_t, and copy the data from the
00275     // linked list into it, deleting the list as you go.
00276     pmesh->graphics = new molfile_graphics_t[ntriangles-1];
00277 //    printf("ntriangles %d \n", ntriangles);
00278     i = 0;
00279     while (gListPtr != NULL) {
00280       pmesh->graphics[i] = gListPtr->gItem;
00281       tmpPtr = gListPtr->next;
00282       delete gListPtr;
00283       gListPtr = tmpPtr;
00284       i++;
00285     }
00286 
00287     *nelem = ntriangles-1;
00288     *data = pmesh->graphics;
00289      for (int x=0; x< 3; x++) free(tmpData[x]);
00290      free(tmpData);
00291     return MOLFILE_SUCCESS;
00292 }
00293 
00294 static void close_file_read(void *v) {
00295   pmesh_t *pmesh = (pmesh_t *)v;
00296   fclose(pmesh->fd);
00297   if (pmesh->graphics != NULL)
00298     delete [] pmesh->graphics;
00299   delete pmesh;
00300 }
00301 
00302 
00303 /*
00304  * Initialization stuff here
00305  */
00306 static molfile_plugin_t plugin;
00307 
00308 VMDPLUGIN_API int VMDPLUGIN_init(void) {
00309   memset(&plugin, 0, sizeof(molfile_plugin_t));
00310   plugin.abiversion = vmdplugin_ABIVERSION;
00311   plugin.type = MOLFILE_PLUGIN_TYPE;
00312   plugin.name = "pmesh";
00313   plugin.prettyname = "polygon mesh";
00314   plugin.author = "Brian Bennion";
00315   plugin.minorv = 0;
00316   plugin.majorv = 1;
00317   plugin.is_reentrant = VMDPLUGIN_THREADSAFE;
00318   plugin.filename_extension = "mesh";
00319   plugin.open_file_read = open_file_read;
00320   plugin.read_rawgraphics = read_rawgraphics;
00321   plugin.close_file_read = close_file_read;
00322   return VMDPLUGIN_SUCCESS;
00323 }
00324 
00325 VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
00326   (*cb)(v, (vmdplugin_t *)&plugin);
00327   return VMDPLUGIN_SUCCESS;
00328 }
00329 
00330 VMDPLUGIN_API int VMDPLUGIN_fini(void) { return VMDPLUGIN_SUCCESS; }
00331 

Generated on Fri Jan 24 02:56:23 2020 for VMD Plugins (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002