00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <stdio.h>
00020 #include <math.h>
00021 #include <string.h>
00022 #include <stdlib.h>
00023
00024 #include "molfile_plugin.h"
00025
00026 typedef struct {
00027 FILE *fd;
00028 molfile_graphics_t *graphics;
00029 } handle_t;
00030
00031 static void *open_file_read(const char *filepath, const char *filetype,
00032 int *natoms) {
00033 FILE *fd;
00034 handle_t *handle;
00035
00036 fd = fopen(filepath, "rt");
00037 if (!fd)
00038 return NULL;
00039 handle = new handle_t;
00040 handle->fd = fd;
00041 handle->graphics = NULL;
00042 *natoms = 0;
00043 return handle;
00044 }
00045
00046 static void next_elem(int &n, int &max, molfile_graphics_t *& graphics) {
00047 ++n;
00048 if (n == max) {
00049 max *= 2;
00050 graphics = (molfile_graphics_t *)realloc(graphics, max*sizeof(molfile_graphics_t));
00051 }
00052 }
00053
00054
00055 static int get_line(int &line, char *buf, int len, FILE *f) {
00056 do {
00057 line++;
00058 if (!fgets(buf, len - 1, f)) return 0;
00059 } while (buf[0] == '#');
00060 return 1;
00061 }
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 static int read_rawgraphics(void *v, int *nelem, const molfile_graphics_t **gdata) {
00108 int count, i;
00109 char buffer[200];
00110 float mat[16];
00111 FILE *infile = NULL;
00112 int futureVersion = 0;
00113 int line = 0;
00114
00115 handle_t *handle = (handle_t *)v;
00116 infile = handle->fd;
00117
00118 int maxelem = 10;
00119 int n = 0;
00120 molfile_graphics_t *graphics = (molfile_graphics_t *) calloc(1, maxelem*sizeof(molfile_graphics_t));
00121
00122
00123 if (!get_line(line, buffer, 199, infile)) {
00124 fprintf(stderr, "raster3dplugin) Error reading file header (line %d)\n",
00125 line);
00126 return MOLFILE_ERROR;
00127 }
00128
00129
00130 for (i = strlen(buffer) - 1; i >= 0 &&
00131 (buffer[i] == 10 || buffer[i] == 13); i--) buffer[i] = 0;
00132 printf("raster3dplugin) scene title: '%s'\n", buffer);
00133
00134
00135
00136
00137 for (count = 0; count < 11; count++) {
00138 if (!get_line(line, buffer, 199, infile)) {
00139 fprintf(stderr,
00140 "raster3dplugin) error reading file header (line %d)\n", line);
00141 return MOLFILE_ERROR;
00142 }
00143 }
00144
00145
00146
00147
00148 for (i=0; i<4; i++) {
00149 get_line(line, buffer, 199, infile);
00150 if (sscanf(buffer, "%f %f %f %f",
00151 &mat[4*i], &mat[4*i+1], &mat[4*i+2], &mat[4*i+3])<4) {
00152 fprintf(stderr, "raster3dplugin) invalid format in file (line %d)\n",
00153 line);
00154 return MOLFILE_ERROR;
00155 }
00156 }
00157
00158 get_line(line, buffer, 199, infile);
00159 if (sscanf(buffer, "%d", &i) < 1) {
00160 fprintf(stderr,
00161 "raster3dplugin) error reading object input mode (line %d)\n",
00162 line);
00163 return MOLFILE_ERROR;
00164 }
00165
00166 if (i != 3) {
00167 fprintf(stderr, "raster3dplugin) the specified file is in an unsupported format\n");
00168 fprintf(stderr, "(object input mode %d). Aborting.\n", i);
00169 return MOLFILE_ERROR;
00170 }
00171
00172 float data[15];
00173 float normals[15];
00174 float tricolors[9];
00175 float color[9];
00176
00177
00178
00179
00180 for (count = 0; count < 3; count++) {
00181 get_line(line, buffer, 199, infile);
00182 if (buffer[0] != '*')
00183 break;
00184 }
00185
00186 if (count < 3) {
00187 fprintf(stderr, "raster3dplugin) Warning: this file contains input in a nonstandard\n");
00188 fprintf(stderr, "Fortran format. This is generally not supported, and the read may fail.\n");
00189 }
00190 count = 0;
00191
00192 while (!feof(infile) && !ferror(infile)) {
00193 int objtype = -1;
00194
00195 if (!get_line(line, buffer, 199, infile))
00196 continue;
00197
00198 if (sscanf(buffer, "%d", &objtype) != 1) {
00199 fprintf(stderr, "raster3dplugin) bad data in file (line %d)\n", line);
00200 return MOLFILE_ERROR;
00201 }
00202
00203 switch(objtype) {
00204 case 1:
00205 char buffer2[200];
00206 int have_normals;
00207 int have_tricolors;
00208 long fpos;
00209
00210 have_normals = 0;
00211 have_tricolors = 0;
00212
00213 get_line(line, buffer, 127, infile);
00214 if (feof(infile)) {
00215
00216
00217 return MOLFILE_ERROR;
00218 }
00219
00220 if (sscanf(buffer, "%f %f %f %f %f %f %f %f %f %f %f %f",
00221 data , data+1, data+2, data+3, data+4, data+5,
00222 data+6, data+7, data+8, data+9, data+10, data+11) < 12) {
00223
00224
00225 continue;
00226 }
00227
00228 while (!feof(infile) && !ferror(infile)) {
00229 fpos = ftell(infile);
00230 if (!get_line(line, buffer2, 199, infile)) {
00231 fseek(infile, fpos, SEEK_SET);
00232 break;
00233 }
00234
00235 if (sscanf(buffer2, "%d", &objtype) != 1) {
00236
00237
00238 return MOLFILE_ERROR;
00239 }
00240
00241 switch (objtype) {
00242 case 7:
00243 if (!get_line(line, buffer2, 199, infile)) {
00244
00245
00246 return MOLFILE_ERROR;
00247 }
00248
00249 if (sscanf(buffer2, "%f %f %f %f %f %f %f %f %f",
00250 normals , normals+1, normals+2,
00251 normals+3, normals+4, normals+5,
00252 normals+6, normals+7, normals+8 ) < 9) {
00253
00254
00255 continue;
00256 }
00257
00258 have_normals = 1;
00259 break;
00260
00261 case 17:
00262 if (!get_line(line, buffer2, 199, infile)) {
00263
00264
00265 return MOLFILE_ERROR;
00266 }
00267
00268 if (sscanf(buffer2, "%f %f %f %f %f %f %f %f %f",
00269 tricolors, tricolors+ 1, tricolors + 2,
00270 tricolors + 3, tricolors + 4, tricolors + 5,
00271 tricolors + 6, tricolors + 7, tricolors + 8) < 9) {
00272
00273
00274 continue;
00275 }
00276
00277 have_tricolors = 1;
00278 break;
00279
00280 default:
00281 fseek(infile, fpos, SEEK_SET);
00282 fpos = 0;
00283 break;
00284
00285 }
00286
00287 if (!fpos)
00288 break;
00289 }
00290
00291 if (ferror(infile)) {
00292
00293
00294 return MOLFILE_ERROR;
00295 }
00296
00297 graphics[n].type = MOLFILE_COLOR;
00298 graphics[n].data[0] = sqrt(data[9]);
00299 graphics[n].data[1] = sqrt(data[10]);
00300 graphics[n].data[2] = sqrt(data[11]);
00301 next_elem(n, maxelem, graphics);
00302
00303 if (have_tricolors) {
00304 for (int qq=0; qq<9; qq++) color[qq] = sqrt(tricolors[qq]);
00305 }
00306
00307 if (!have_normals && !have_tricolors) {
00308 graphics[n].type = MOLFILE_TRIANGLE;
00309 memcpy(graphics[n].data, data, 9*sizeof(float));
00310 next_elem(n, maxelem, graphics);
00311 } else if (have_normals && !have_tricolors) {
00312 graphics[n].type = MOLFILE_TRINORM;
00313 memcpy(graphics[n].data, data, 9*sizeof(float));
00314 next_elem(n, maxelem, graphics);
00315 graphics[n].type = MOLFILE_NORMS;
00316 memcpy(graphics[n].data, normals, 9*sizeof(float));
00317 next_elem(n, maxelem, graphics);
00318 } else if (have_tricolors && !have_normals) {
00319 #if 0
00320 float tmp1[3], tmp2[3], tmp3[3];
00321 int j;
00322 for (j = 0; j < 3; j++) {
00323 tmp1[j] = data[3 + j] - data[j];
00324 tmp2[j] = data[6 + j] - data[3 + j];
00325 }
00326 cross_prod(tmp3, tmp1, tmp2);
00327 vec_normalize(tmp3);
00328 triclr.putdata(data, data+3, data+6,
00329 tmp3, tmp3, tmp3,
00330 colorIndices[0], colorIndices[1], colorIndices[2],
00331 cmdList);
00332 #else
00333
00334 graphics[n].type = MOLFILE_COLOR;
00335 graphics[n].data[0] = (color[0]+color[3]+color[6])/3.0f;
00336 graphics[n].data[1] = (color[1]+color[4]+color[7])/3.0f;
00337 graphics[n].data[2] = (color[2]+color[5]+color[8])/3.0f;
00338 next_elem(n, maxelem, graphics);
00339 graphics[n].type = MOLFILE_TRIANGLE;
00340 memcpy(graphics[n].data, data, 9*sizeof(float));
00341 next_elem(n, maxelem, graphics);
00342 #endif
00343 } else {
00344 #if 0
00345 triclr.putdata(data, data+3, data+6,
00346 normals, normals+3, normals+6,
00347 colorIndices[0], colorIndices[1], colorIndices[2],
00348 cmdList);
00349 #else
00350 graphics[n].type = MOLFILE_TRICOLOR;
00351 memcpy(graphics[n].data, data, 9*sizeof(float));
00352 next_elem(n, maxelem, graphics);
00353 graphics[n].type = MOLFILE_NORMS;
00354 memcpy(graphics[n].data, normals, 9*sizeof(float));
00355 next_elem(n, maxelem, graphics);
00356 graphics[n].type = MOLFILE_COLOR;
00357 memcpy(graphics[n].data, color, 9*sizeof(float));
00358 next_elem(n, maxelem, graphics);
00359 #endif
00360 }
00361 break;
00362
00363 case 2:
00364 if (!get_line(line, buffer, 199, infile)) {
00365
00366
00367 return MOLFILE_ERROR;
00368 }
00369
00370 if (sscanf(buffer, "%f %f %f %f %f %f %f",
00371 data, data + 1, data + 2, data + 3,
00372 data + 4, data + 5, data + 6) != 7) {
00373
00374
00375 continue;
00376 }
00377 graphics[n].type = MOLFILE_COLOR;
00378 color[0] = sqrt(data[4]);
00379 color[1] = sqrt(data[5]);
00380 color[2] = sqrt(data[6]);
00381 memcpy(graphics[n].data, color, 3*sizeof(float));
00382 next_elem(n, maxelem, graphics);
00383 graphics[n].type = MOLFILE_SPHERE;
00384 graphics[n].size = data[3];
00385 graphics[n].style = 12;
00386 memcpy(graphics[n].data, data, 3*sizeof(float));
00387 next_elem(n, maxelem, graphics);
00388 break;
00389
00390 case 3:
00391 case 5:
00392 if (!get_line(line, buffer, 199, infile)) {
00393
00394
00395 return MOLFILE_ERROR;
00396 }
00397
00398 if (sscanf(buffer, "%f %f %f %f %f %f %f %f %f %f %f",
00399 data, data + 1, data + 2, data + 3, data + 4,
00400 data + 5, data + 6, data + 7, data + 8, data + 9,
00401 data + 10) != 11) {
00402
00403
00404 continue;
00405 }
00406 graphics[n].type = MOLFILE_COLOR;
00407 color[0] = sqrt(data[8]);
00408 color[1] = sqrt(data[9]);
00409 color[2] = sqrt(data[10]);
00410 memcpy(graphics[n].data, color, 3*sizeof(float));
00411 next_elem(n, maxelem, graphics);
00412 graphics[n].type = MOLFILE_CYLINDER;
00413 graphics[n].size = data[3];
00414 graphics[n].style = 12;
00415 memcpy(graphics[n].data, data, 3*sizeof(float));
00416 memcpy(graphics[n].data+3, data+4, 3*sizeof(float));
00417 next_elem(n, maxelem, graphics);
00418
00419
00420 if (objtype == 3) {
00421 graphics[n].type = MOLFILE_SPHERE;
00422 graphics[n].size = data[3];
00423 graphics[n].style = 12;
00424 memcpy(graphics[n].data, data, 3*sizeof(float));
00425 next_elem(n, maxelem, graphics);
00426 graphics[n].type = MOLFILE_SPHERE;
00427 graphics[n].size = data[3];
00428 graphics[n].style = 12;
00429 memcpy(graphics[n].data, data+4, 3*sizeof(float));
00430 next_elem(n, maxelem, graphics);
00431 }
00432 break;
00433
00434 case 9:
00435 break;
00436
00437 case 6: case 8: case 10: case 11: case 12: case 13: case 15: case 19:
00438
00439 get_line(line, buffer, 199, infile);
00440 break;
00441
00442 case 7:
00443
00444
00445
00446 break;
00447
00448 case 17:
00449
00450
00451 break;
00452
00453 case 0:
00454 break;
00455
00456
00457
00458 default:
00459 if (!futureVersion) {
00460
00461
00462
00463
00464 futureVersion = 1;
00465 }
00466 break;
00467
00468 }
00469
00470
00471 if (objtype == 0)
00472 break;
00473 }
00474
00475 if (ferror(infile)) {
00476
00477
00478 return MOLFILE_ERROR;
00479 }
00480
00481
00482 *nelem = n;
00483 handle->graphics = graphics;
00484 *gdata = graphics;
00485 return MOLFILE_SUCCESS;
00486 }
00487
00488
00489 static void close_file_read(void *v) {
00490 handle_t *handle = (handle_t *)v;
00491 fclose(handle->fd);
00492 handle->fd = NULL;
00493 free(handle->graphics);
00494 handle->graphics = NULL;
00495 delete handle;
00496 }
00497
00498
00499
00500
00501
00502 static molfile_plugin_t plugin;
00503
00504 VMDPLUGIN_API int VMDPLUGIN_init(void) {
00505 memset(&plugin, 0, sizeof(molfile_plugin_t));
00506 plugin.abiversion = vmdplugin_ABIVERSION;
00507 plugin.type = MOLFILE_PLUGIN_TYPE;
00508 plugin.name = "raster3d";
00509 plugin.prettyname = "Raster3d Scene File";
00510 plugin.author = "Justin Gullingsrud";
00511 plugin.majorv = 0;
00512 plugin.minorv = 3;
00513 plugin.is_reentrant = VMDPLUGIN_THREADSAFE;
00514 plugin.filename_extension = "r3d";
00515 plugin.open_file_read = open_file_read;
00516 plugin.read_rawgraphics = read_rawgraphics;
00517 plugin.close_file_read = close_file_read;
00518 return VMDPLUGIN_SUCCESS;
00519 }
00520
00521 VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
00522 (*cb)(v, (vmdplugin_t *)&plugin);
00523 return VMDPLUGIN_SUCCESS;
00524 }
00525
00526 VMDPLUGIN_API int VMDPLUGIN_fini(void) { return VMDPLUGIN_SUCCESS; }
00527