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