00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
00061
00062
00063
00064
00065
00066
00067
00068 char trash[4];
00069 #define TRASH fread(trash, 4, 1, infile)
00070 char line[81];
00071
00072
00073 TRASH;
00074 fread(line, 1, 80, infile);
00075
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
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
00094 TRASH;
00095 fread(line, 1, 80, infile);
00096 TRASH;
00097
00098
00099
00100 char line3[81];
00101 TRASH;
00102 fread(line3, 1, 80, infile);
00103 line3[80] = 0;
00104 TRASH;
00105
00106
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
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
00136
00137
00138
00139
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
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
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;
00205 vert2 = triangle[3*tri_count+1] - 1;
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
00253
00254 static molfile_plugin_t plugin = {
00255 vmdplugin_ABIVERSION,
00256 MOLFILE_PLUGIN_TYPE,
00257 "grasp",
00258 "GRASP",
00259 "Justin Gullingsrud, John Stone",
00260 0,
00261 5,
00262 VMDPLUGIN_THREADSAFE,
00263 "srf,grasp"
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