1 /* MACHINE GENERATED FILE, DO NOT EDIT! */
2 
3 #define VMDPLUGIN molfile_molemeshplugin
4 #define STATIC_PLUGIN 1
5 
6 /***************************************************************************
7  *cr
8  *cr            (C) Copyright 1995-2016 The Board of Trustees of the
9  *cr                        University of Illinois
10  *cr                         All Rights Reserved
11  *cr
12  ***************************************************************************/
13 
14 /***************************************************************************
15  * RCS INFORMATION:
16  *
17  *      $RCSfile: molemeshplugin.C,v $
18  *      $Author: johns $       $Locker:  $             $State: Exp $
19  *      $Revision: 1.3 $       $Date: 2016/11/28 05:01:54 $
20  *
21  ***************************************************************************/
22 
23 /*
24  *  quadrilaterals are used to represent the geometry.
25  *
26  *  ASCII pmesh file from mole 2.0 follows the following format. Files are case
27 insensitive
28  *  and whitespace is ignored.
29  *
30  *  number of vertices        ()
31  *  vertex v1x v1y v1z        (<v1> is the first vertex)
32  *  vertex v2x v2y v2z        (vertices are given in some order)
33  *  vertex v3x v3y v3z        (vertices are given as floating-point values)
34  *  vertex v4x v4y v4z        (vertices are given as floating-point values)
35  *  number of polygons/faces
36  *  face number               (in groups of 4?)
37  */
38 
39 #include <stdlib.h>
40 #include <stdio.h>
41 #include <ctype.h>
42 #include <math.h>
43 #include <string.h>
44 
45 #if defined(_AIX)
46 #include <strings.h>
47 #endif
48 
49 #if defined(WIN32) || defined(WIN64)
50 #define strcasecmp stricmp
51 #endif
52 
53 #include "molfile_plugin.h"
54 
55 typedef struct graphics_list {
56   molfile_graphics_t gItem;
57   struct graphics_list *next;
58 } molfile_graphics_list;
59 
60 typedef struct {
61   FILE *fd;
62   molfile_graphics_t *graphics;
63 } pmesh_t;
64 
open_file_read(const char * filepath,const char * filetype,int * natoms)65 static void *open_file_read(const char *filepath, const char *filetype, int *natoms) {
66    FILE *fd;
67    pmesh_t *pmesh;
68 
69    fd = fopen(filepath, "rb");
70    if (!fd) {
71      fprintf(stderr, "molemeshplugin) Error opening file.\n");
72      return NULL;
73    }
74    pmesh = new pmesh_t;
75    pmesh->fd = fd;
76    pmesh->graphics = NULL;
77    *natoms = 0;
78    return pmesh;
79 }
read_rawgraphics(void * v,int * nelem,const molfile_graphics_t ** data)80 static int read_rawgraphics(void *v, int *nelem, const molfile_graphics_t **data) {
81     molfile_graphics_list *gListPtr=NULL, *tmpPtr=NULL;
82     int i=0, ntriangles=0,j=0;
83     int error=0, numVerts=0, numFacets=0, facetType=0, facet=0, tmpFacet[5];
84     pmesh_t *pmesh = (pmesh_t *)v;
85     FILE *infile = pmesh->fd;
86     char line[81];
87     float **tmpData;
88 
89     // Check your head(er)
90     // "number of vertices"
91     fgets(line, 80, infile);
92     sscanf(line, "%d", &numVerts);
93     if (numVerts  < 1) {
94       fprintf(stderr, "molespmeshplugin) error: expected \"Positive Number of Vertices\".\n");
95       error = 1;
96       return MOLFILE_ERROR;
97     } else {
98      gListPtr = new molfile_graphics_list;
99      gListPtr->next = NULL;
100      gListPtr->gItem.type = MOLFILE_TRIANGLE;
101      ntriangles++;
102      tmpPtr = gListPtr;
103    }
104 
105 //Allocate memory for 2d array.  maybe there is a better way to do this.
106     tmpData = new float*[numVerts];
107     for (int h=0 ; h < numVerts ; h++ ) {
108          tmpData[h] = new float[3];
109     }
110 
111 //we know how many vertices there are read them all into tmpData[j][i]
112    for ( j=0 ; j < numVerts; j++) {
113 // "first loop"
114 // scan each vertex vx, vy, vz
115     i=0;
116     fgets(line, 80, infile);
117     float t1=0.0f, t2=0.0f, t3=0.0f;
118     if ( sscanf(line, "%f %f %f", &t1, &t2, &t3) == 3 ) {
119         tmpData[j][i++] = t1;
120         tmpData[j][i++] = t2;
121         tmpData[j][i++] = t3;
122      } else if(ferror(infile)) {
123        fprintf(stderr, "molespmeshplugin) error: problem reading file\n");
124        error = 1;
125        return MOLFILE_ERROR;
126      }
127    }
128 //Read in the total number of facets.  For pmesh files the next number is the total number of triangle or quadrilaterals
129 //If triangles, then the next number after the total is a 4, and the next four numbers after that describe the vertex index for
130 //each point of the triangle.  If the set begins with a 5 then the next 5 numbers describe the vertex number for
131 //each point of the quadrilateral.  So far this reader does not support multiple/concatenated mpesh files yet.
132    fgets(line, 80, infile);
133    sscanf(line, "%d", &numFacets);
134 //printf("numFacets %d \n",numFacets);
135    if (numFacets  < 1) {
136       fprintf(stderr, "molespmeshplugin) error: expected \"Positive Number of Facets\".\n");
137       error = 1;
138       return MOLFILE_ERROR;
139     } else {
140      gListPtr = new molfile_graphics_list;
141 
142      gListPtr->next = NULL;
143      gListPtr->gItem.type = MOLFILE_TRIANGLE;
144      ntriangles++;
145      tmpPtr = gListPtr;
146    }
147 //Read in the facet type 4=triangle 5=quadrilateral. need to do a while loop here, as long as xxxx<numFacets keep reading
148    while ( !feof(infile) && ( error == 0 ) ) {
149      fgets(line, 80, infile);
150      sscanf(line, "%d", &facetType);
151      if (facetType == 4) {
152 //printf("facetype %d \n", facetType);
153         int l=0;
154         for (int k=0 ; k < facetType-1; k++) {
155               fgets(line, 80, infile);
156               sscanf(line, "%d", &facet);
157               tmpPtr->gItem.data[l++] = tmpData[facet][0];
158               tmpPtr->gItem.data[l++] = tmpData[facet][1];
159               tmpPtr->gItem.data[l++] = tmpData[facet][2];
160          }
161      fgets(line, 80, infile); //one more read to keep us in sync
162 // Create a new list item and initialize it for second triangle.
163          tmpPtr->next = new molfile_graphics_list;
164          tmpPtr = tmpPtr->next;
165          tmpPtr->next = NULL;
166          tmpPtr->gItem.type = MOLFILE_TRIANGLE;
167          ntriangles++;
168      } else if (facetType == 5 ) {
169                 for (int k=0 ; k < facetType-1; k++) {
170                      fgets(line, 80, infile);
171                      sscanf(line, "%d", &facet);
172                      tmpFacet[k]=facet;
173                 }
174 
175                 tmpPtr->gItem.data[0] = tmpData[tmpFacet[0]][0];
176                 tmpPtr->gItem.data[1] = tmpData[tmpFacet[0]][1];
177                 tmpPtr->gItem.data[2] = tmpData[tmpFacet[0]][2];
178 
179                 tmpPtr->gItem.data[3] = tmpData[tmpFacet[1]][0];
180                 tmpPtr->gItem.data[4] = tmpData[tmpFacet[1]][1];
181                 tmpPtr->gItem.data[5] = tmpData[tmpFacet[1]][2];
182 
183                 tmpPtr->gItem.data[6] = tmpData[tmpFacet[2]][0];
184                 tmpPtr->gItem.data[7] = tmpData[tmpFacet[2]][1];
185                 tmpPtr->gItem.data[8] = tmpData[tmpFacet[2]][2];
186 
187 // Create a new list item and initialize it for second triangle.
188                 tmpPtr->next = new molfile_graphics_list;
189                 tmpPtr = tmpPtr->next;
190                 tmpPtr->next = NULL;
191                 tmpPtr->gItem.type = MOLFILE_TRIANGLE;
192                 ntriangles++;
193 
194                 tmpPtr->gItem.data[0] = tmpData[tmpFacet[0]][0];
195                 tmpPtr->gItem.data[1] = tmpData[tmpFacet[0]][1];
196                 tmpPtr->gItem.data[2] = tmpData[tmpFacet[0]][2];
197 
198                 tmpPtr->gItem.data[3] = tmpData[tmpFacet[2]][0];
199                 tmpPtr->gItem.data[4] = tmpData[tmpFacet[2]][1];
200                 tmpPtr->gItem.data[5] = tmpData[tmpFacet[2]][2];
201 
202                 tmpPtr->gItem.data[6] = tmpData[tmpFacet[3]][0];
203                 tmpPtr->gItem.data[7] = tmpData[tmpFacet[3]][1];
204                 tmpPtr->gItem.data[8] = tmpData[tmpFacet[3]][2];
205 
206 // Create a new list item and initialize it for first triangle of the second quadrilateral.
207                 tmpPtr->next = new molfile_graphics_list;
208                 tmpPtr = tmpPtr->next;
209                 tmpPtr->next = NULL;
210                 tmpPtr->gItem.type = MOLFILE_TRIANGLE;
211                 ntriangles++;
212      } else if ( (facetType != 4 || facetType != 5) && facetType >= 6 ) {
213 //Find out if this is a concatenated file by reading the next value and testing for a series of three floats.
214 //If so, free tmpData and reallocate according to this number. then read all the vertices into tmpData and do
215 //a drop back into the while loop.
216 //If not, exit with error.
217          fgets(line, 80, infile);
218          float t1=0.0f, t2=0.0f, t3=0.0f;
219          if ( sscanf(line, "%f %f %f", &t1,&t2,&t3) ==3 ) {
220 //free tmpData
221              for (int x=0; x< 3; x++) free(tmpData[x]);
222                   free (tmpData);
223              numVerts=facetType;
224              facetType=0;
225 //Allocate new size for vertices array
226              tmpData = new float*[numVerts];
227              for (int h=0 ; h < numVerts ; h++ ) {
228                  tmpData[h] = new float[3];
229              }
230 
231 //Read in all new vertices after adding the first test vertex
232              tmpData[0][0] = t1;
233              tmpData[0][1] = t2;
234              tmpData[0][2] = t3;
235              for ( j=1 ; j < numVerts; j++) {
236                  i=0;
237                  fgets(line, 80, infile);
238                  float t1=0.0f, t2=0.0f, t3=0.0f;
239                  if ( sscanf(line, "%f %f %f", &t1, &t2, &t3) == 3 ) {
240                     tmpData[j][i++] = t1;
241                     tmpData[j][i++] = t2;
242                     tmpData[j][i++] = t3;
243                  } else if(ferror(infile)) {
244                            fprintf(stderr, "molespmeshplugin) error: problem reading vertices from concatenated file\n");
245                            error = 1;
246                            break;
247                 }
248              }
249          } else if ( feof(infile)  ) {
250 //end file read gracefully at the last facet
251                     break;
252          } else { fprintf(stderr, "molespmeshplugin) error: problem reading concatenated file?\n");
253                 error = 1;
254                 break;
255          }
256          fgets(line, 80, infile);
257          sscanf(line, "%d", &numFacets);
258          if (numFacets  < 1) {
259             fprintf(stderr, "molespmeshplugin) error: expected \"Positive Number of Facets\".\n");
260            error = 1;
261          }
262      }
263 //go back into the while loop with error=0 so that we can reuse the facet code
264 //for additional meshes
265      error = 0;
266     }
267     // If an error occurred, free the linked list and return MOLFILE_ERROR
268     if (error != 0) {
269       while (gListPtr != NULL) {
270         tmpPtr = gListPtr->next;
271         delete gListPtr;
272         gListPtr = tmpPtr;
273       }
274      for (int x=0; x< 3; x++) free(tmpData[x]);
275      free (tmpData);
276       return MOLFILE_ERROR;
277     }
278 
279     // Create the array of molfile_graphics_t, and copy the data from the
280     // linked list into it, deleting the list as you go.
281     pmesh->graphics = new molfile_graphics_t[ntriangles-1];
282 //    printf("ntriangles %d \n", ntriangles);
283     i = 0;
284     while (gListPtr != NULL) {
285       pmesh->graphics[i] = gListPtr->gItem;
286       tmpPtr = gListPtr->next;
287       delete gListPtr;
288       gListPtr = tmpPtr;
289       i++;
290     }
291 
292     *nelem = ntriangles-1;
293     *data = pmesh->graphics;
294      for (int x=0; x< 3; x++) free(tmpData[x]);
295      free(tmpData);
296     return MOLFILE_SUCCESS;
297 }
298 
close_file_read(void * v)299 static void close_file_read(void *v) {
300   pmesh_t *pmesh = (pmesh_t *)v;
301   fclose(pmesh->fd);
302   if (pmesh->graphics != NULL)
303     delete [] pmesh->graphics;
304   delete pmesh;
305 }
306 
307 
308 /*
309  * Initialization stuff here
310  */
311 static molfile_plugin_t plugin;
312 
VMDPLUGIN_init(void)313 VMDPLUGIN_API int VMDPLUGIN_init(void) {
314   memset(&plugin, 0, sizeof(molfile_plugin_t));
315   plugin.abiversion = vmdplugin_ABIVERSION;
316   plugin.type = MOLFILE_PLUGIN_TYPE;
317   plugin.name = "pmesh";
318   plugin.prettyname = "polygon mesh";
319   plugin.author = "Brian Bennion";
320   plugin.minorv = 0;
321   plugin.majorv = 1;
322   plugin.is_reentrant = VMDPLUGIN_THREADSAFE;
323   plugin.filename_extension = "mesh";
324   plugin.open_file_read = open_file_read;
325   plugin.read_rawgraphics = read_rawgraphics;
326   plugin.close_file_read = close_file_read;
327   return VMDPLUGIN_SUCCESS;
328 }
329 
VMDPLUGIN_register(void * v,vmdplugin_register_cb cb)330 VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
331   (*cb)(v, (vmdplugin_t *)&plugin);
332   return VMDPLUGIN_SUCCESS;
333 }
334 
VMDPLUGIN_fini(void)335 VMDPLUGIN_API int VMDPLUGIN_fini(void) { return VMDPLUGIN_SUCCESS; }
336 
337