Main Page   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

raster3dplugin.C

Go to the documentation of this file.
00001 
00002 /***************************************************************************
00003  *cr
00004  *cr            (C) Copyright 1995-2006 The Board of Trustees of the
00005  *cr                        University of Illinois
00006  *cr                         All Rights Reserved
00007  *cr
00008  ***************************************************************************/
00009 
00010 #include <stdio.h>
00011 #include <math.h>
00012 #include <string.h>
00013 #include <stdlib.h>
00014 
00015 #include "molfile_plugin.h"
00016 
00017 typedef struct {
00018   FILE *fd;
00019   molfile_graphics_t *graphics;
00020 } handle_t;
00021 
00022 static void *open_file_read(const char *filepath, const char *filetype,
00023     int *natoms) {
00024   FILE *fd;
00025   handle_t *handle;
00026   
00027   fd = fopen(filepath, "rt");
00028   if (!fd) 
00029     return NULL;
00030   handle = new handle_t;
00031   handle->fd = fd;
00032   handle->graphics = NULL;
00033   *natoms = 0;
00034   return handle;
00035 }
00036 
00037 static void next_elem(int &n, int &max, molfile_graphics_t *& graphics) {
00038   ++n;
00039   if (n == max) {
00040     max *= 2;
00041     graphics = (molfile_graphics_t *)realloc(graphics, max*sizeof(molfile_graphics_t));
00042   }
00043 }
00044 
00045 // gets a line of text from the file, ignoring comments
00046 static int get_line(int &line, char *buf, int len, FILE *f) {
00047    do {
00048       line++;
00049       if (!fgets(buf, len - 1, f)) return 0;
00050    } while (buf[0] == '#');
00051    return 1;
00052 }
00053 
00054 static int read_rawgraphics(void *v, int *nelem, 
00055     const molfile_graphics_t **gdata) {
00056 
00057 /* TODO
00058  *
00059  * 1. doesn't properly render capped cylinders
00060  * 2. needs to handle object types 15, 19, 9 (affects coordinate system);
00061  *    needs to first understand VMD's coordinate system.
00062  * 3. doesn't properly handle object type 8 (material definitions)
00063  * 4. doesn't properly handle object type 14 (quadrics)
00064  * 5. doesn't properly support file indirection (using '@')
00065  * 6. doesn't differentiate between round-ended cylinders (obj 3)
00066  *    and flat-ended cylinders (obj 5)
00067  * 7. doesn't handle planes
00068  * 8. doesn't support text (object types 10-12)
00069  * 9. doesn't handle depth cueing and transformations in global
00070  *    properties (object 16)
00071  */
00072 
00074 // TITLE (80 chars)
00075 // NTX, NTY (number of tiles -- ignored)
00076 // NPX, NPY (number of points per tile -- ignored)
00077 // SCHEME (antialiasing scheme -- ignored)
00078 // BKGND (background color -- ignored)
00079 // SHADOW (T/F -- ignored)
00080 // IPHONG (phong power -- ignored)
00081 // STRAIT (secondary light source -- ignored)
00082 // AMBIEN (ambient illumination -- ignored)
00083 // SPECLR ignored
00084 // EYEPOS ignored
00085 // SOURCE ignored
00086 // TMAT 4x4 matrix used to view the system
00087 // object mode (1 == triangle, 2 == spheres, or 3 ==  mixed)
00088 // INFMTS  --  FORTRAN input field specifications
00089 //   for input format specifiers 1/6, 2, and 3/5
00090 //   triangle(1) or plane(6) (x1,y1,z1)-(x2,y2,z2)-(x3,y3,z3) (r,g,b)
00091 //   sphere(2)      (x,y,z) r (r,g,b)
00092 //   cylinder(3,5)  (x1,y1,z1) R1 - (x2,y2,z2) R2(is ignored) (r,g,b)
00093 //                      except if one radius is 0, a cone is made
00094 //   I ignore these lines and just read them in as "%f"
00095 
00096    int futureVersion = 0;
00097    int line = 0;
00098 
00099    int count, i;
00100    char buffer[200];
00101    float mat[16];
00102    FILE *infile;
00103 
00104    handle_t *handle = (handle_t *)v;
00105    infile = handle->fd;
00106 
00107    int maxelem = 10;
00108    int n = 0;
00109    molfile_graphics_t *graphics = (molfile_graphics_t *)malloc(
00110        maxelem*sizeof(molfile_graphics_t));
00111 
00112    // XXX This should probably be in open_file_read
00113    if (!get_line(line, buffer, 199, infile)) {
00114       fprintf(stderr, "Raster3D input: error reading file header (line %d)\n",
00115           line);
00116       return MOLFILE_ERROR;
00117    }
00118 
00119    // tell the user info about the file
00120    for (i = strlen(buffer) - 1; i >= 0 &&
00121         (buffer[i] == 10 || buffer[i] == 13); i--) buffer[i] = 0;
00122    printf("Raster3D input: scene title: '%s'\n", buffer);
00123 
00124    // The next 11 lines of text contain more header information
00125    // about lighting, anti aliasing, image size, etc. This can be
00126    // ignored.
00127    for (count = 0; count < 11; count++) {
00128       if (!get_line(line, buffer, 199, infile)) {
00129          fprintf(stderr, 
00130              "Raster3D input: error reading file header (line %d)\n", line);
00131          return MOLFILE_ERROR;
00132       }
00133    }
00134 
00135    // Now I have to get the matrix.  This is made nasty since
00136    // there could be extra text after the first four numbers on a line
00137    // as in: 1 0 0 0 This is an extra comment
00138    for (i=0; i<4; i++) {
00139       get_line(line, buffer, 199, infile);  // read the whole line into a string
00140       if (sscanf(buffer, "%f %f %f %f",
00141                  &mat[4*i], &mat[4*i+1], &mat[4*i+2], &mat[4*i+3])<4) {
00142          fprintf(stderr, "Raster3D input: invalid format in file (line %d)\n",
00143              line);
00144          return MOLFILE_ERROR;
00145       }
00146    }
00147 
00148    get_line(line, buffer, 199, infile);
00149    if (sscanf(buffer, "%d", &i) < 1) {
00150      fprintf(stderr, 
00151          "Raster3D input: error reading object input mode (line %d)\n", line);
00152      return MOLFILE_ERROR;
00153    }
00154 
00155    if (i != 3) {
00156       fprintf(stderr, 
00157           "Raster3D input: the specified file is in an unsupported format\n");
00158       fprintf(stderr, 
00159           "(object input mode %d). Aborting.\n", i);
00160       return MOLFILE_ERROR;
00161    }
00162 
00163    float data[15];
00164    float normals[15];
00165    float tricolors[9];
00166    float color[9];
00167 
00168       // INFMT/INFMTS input specifiers; these can specifiy Fortran formatted
00169       // input formats, but are usually "*" meaning free-format input. We
00170       // give a warning if it's not free-format.
00171       for (count = 0; count < 3; count++) {
00172          get_line(line, buffer, 199, infile);
00173          for (i = strlen(buffer) - 1; i >= 0 && (buffer[i] == 10 || buffer[i] == 13); i--)
00174             buffer[i] = 0;
00175          if (strcmp(buffer, "*")) break;
00176       }
00177       if (count < 3) {  
00178         fprintf(stderr, "Raster3D input: Warning: this file contains input in a nonstandard\n");
00179         fprintf(stderr, "Fortran format. This is generally not supported, and the read may fail.\n");
00180       }
00181       count = 0;
00182 
00183       while (!feof(infile) && !ferror(infile)) {
00184          int objtype = -1;
00185 
00186          if (!get_line(line, buffer, 199, infile)) continue;
00187 
00188          if (sscanf(buffer, "%d", &objtype) != 1) {
00189             fprintf(stderr, "Raster3D input: bad data in file (line %d)\n",
00190                 line);
00191             return MOLFILE_ERROR;
00192          }
00193 
00194          switch(objtype) {
00195 
00196             case 1: // triangle
00197                char buffer2[200];
00198                int have_normals;
00199                int have_tricolors;
00200                long fpos;
00201 
00202                have_normals = 0;
00203                have_tricolors = 0;
00204 
00205                get_line(line, buffer, 127, infile);
00206                if (feof(infile)) {
00207                   //msgErr << "Raster3D input: error reading triangle data (line "
00208                          //<< line << ")" << sendmsg;
00209                   return MOLFILE_ERROR;
00210                }
00211 
00212                if (sscanf(buffer, "%f %f %f %f %f %f %f %f %f %f %f %f",
00213                           data  , data+1, data+2,
00214                           data+3, data+4, data+5,
00215                           data+6, data+7, data+8,
00216                           data+9, data+10, data+11) < 12) { 
00217                   //msgErr << "Raster3D input: bad triangle data in file (line "
00218                          //<< line << "). Will try to continue." << sendmsg;
00219                   continue;
00220                }
00221 
00222                while (!feof(infile) && !ferror(infile)) {
00223 
00224                   fpos = ftell(infile);
00225                   if (!get_line(line, buffer2, 199, infile)) {
00226                      fseek(infile, fpos, SEEK_SET);
00227                      break;
00228                   }
00229 
00230                   if (sscanf(buffer2, "%d", &objtype) != 1) {
00231                      //msgErr << "Raster3D input: bad data in file (line " << line
00232                             //<< "). Aborting." << sendmsg;
00233                      return MOLFILE_ERROR;
00234                   }
00235 
00236                   switch (objtype) {
00237                      case 7: // explicit normals
00238 
00239                         if (!get_line(line, buffer2, 199, infile)) {
00240                            //msgErr << "Raster3D input: read error in file (line " << line
00241                                   //<< "). Aborting." << sendmsg;
00242                            return MOLFILE_ERROR;
00243                         }
00244 
00245                         if (sscanf(buffer2, "%f %f %f %f %f %f %f %f %f",
00246                                    normals  , normals+1, normals+2,
00247                                    normals+3, normals+4, normals+5,
00248                                    normals+6, normals+7, normals+8 ) < 9) { 
00249                            //msgErr << "Raster3D input: error reading triangle normals (line "
00250                                   //<< line << "). Will try to continue." << sendmsg;
00251                            continue;
00252                         }
00253 
00254                         have_normals = 1;
00255 
00256                         break;
00257 
00258                      case 17: // colors at vertices of a tri-color
00259 
00260                         if (!get_line(line, buffer2, 199, infile)) {
00261                            //msgErr << "Raster3D input: read error in file (line " << line
00262                                   //<< "). Aborting." << sendmsg;
00263                            return MOLFILE_ERROR;
00264                         }
00265 
00266                         if (sscanf(buffer2, "%f %f %f %f %f %f %f %f %f",
00267                                    tricolors,  tricolors+ 1, tricolors + 2,
00268                                    tricolors + 3, tricolors + 4, tricolors + 5,
00269                                    tricolors + 6, tricolors + 7, tricolors + 8) < 9) {
00270                            //msgErr << "Raster3D input: error reading vertex colors (line "
00271                                   //<< line << "). Will try to continue." << sendmsg;
00272                            continue;
00273                         }
00274 
00275                         have_tricolors = 1;
00276 
00277                         break;
00278 
00279                      default:
00280 
00281                         fseek(infile, fpos, SEEK_SET);
00282                         fpos = 0;
00283                         break;
00284 
00285                   }
00286 
00287                   if (!fpos) break;
00288                }
00289 
00290                if (ferror(infile)) {
00291                   //msgErr << "Raster3D input: read error in file (line "
00292                            //<< line << "). Aborting." << sendmsg;
00293                   return MOLFILE_ERROR;
00294                }
00295 
00296                             graphics[n].type = MOLFILE_COLOR;
00297                             graphics[n].data[0] = sqrt(data[9]);
00298                             graphics[n].data[1] = sqrt(data[10]);
00299                             graphics[n].data[2] = sqrt(data[11]);
00300                             next_elem(n, maxelem, graphics);
00301 
00302                if (have_tricolors) {
00303                  for (int qq=0; qq<9; qq++) color[qq] = sqrt(tricolors[qq]);
00304                }
00305 
00306                if (!have_normals && !have_tricolors) {
00307                  graphics[n].type = MOLFILE_TRIANGLE;
00308                  memcpy(graphics[n].data, data, 3*sizeof(float));
00309                  next_elem(n, maxelem, graphics);
00310 
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 
00321                   float tmp1[3], tmp2[3], tmp3[3];
00322                   int j;
00323                   for (j = 0; j < 3; j++) {
00324                      tmp1[j] = data[3 + j] - data[j];
00325                      tmp2[j] = data[6 + j] - data[3 + j];
00326                   }
00327                   cross_prod(tmp3, tmp1, tmp2);
00328                   vec_normalize(tmp3);
00329                   triclr.putdata(data, data+3, data+6,
00330                                  tmp3, tmp3, tmp3,
00331                                  colorIndices[0], colorIndices[1], colorIndices[2], cmdList);
00332 #else
00333                   // XXX Take the average of the color
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, 3*sizeof(float));
00341                   next_elem(n, maxelem, graphics);
00342 
00343 #endif
00344                } else {
00345 
00346 #if 0
00347                   triclr.putdata(data, data+3, data+6,
00348                                  normals, normals+3, normals+6,
00349                                  colorIndices[0], colorIndices[1], colorIndices[2], cmdList);
00350 #else
00351            graphics[n].type = MOLFILE_TRICOLOR;
00352            memcpy(graphics[n].data, data, 9*sizeof(float));
00353            next_elem(n, maxelem, graphics);
00354            graphics[n].type = MOLFILE_NORMS;
00355            memcpy(graphics[n].data, normals, 9*sizeof(float));
00356            next_elem(n, maxelem, graphics);
00357            graphics[n].type = MOLFILE_COLOR;
00358            memcpy(graphics[n].data, color, 9*sizeof(float));
00359            next_elem(n, maxelem, graphics);
00360 #endif
00361                }
00362 
00363                break;
00364 
00365             case 2: // sphere
00366 
00367                if (!get_line(line, buffer, 199, infile)) {
00368                   //msgErr << "Raster3D input: error reading sphere data (line "
00369                          //<< line << ")" << sendmsg;
00370                   return MOLFILE_ERROR;
00371                }
00372 
00373                if (sscanf(buffer, "%f %f %f %f %f %f %f",
00374                           data, data + 1, data + 2, data + 3,
00375                           data + 4, data + 5, data + 6) != 7) {
00376                   //msgErr << "Raster3D input: bad sphere data in file (line "
00377                          //<< line << "). Will try to continue." << sendmsg;
00378                   continue;
00379                }
00380                  graphics[n].type = MOLFILE_COLOR;
00381                  color[0] = sqrt(data[4]);
00382                  color[1] = sqrt(data[5]);
00383                  color[2] = sqrt(data[6]);
00384                  memcpy(graphics[n].data, color, 3*sizeof(float));
00385                  next_elem(n, maxelem, graphics);
00386                  graphics[n].type = MOLFILE_SPHERE;
00387                  graphics[n].size = data[3];
00388                  graphics[n].style = 12; // XXX hard-coded resolution
00389                  memcpy(graphics[n].data, data, 3*sizeof(float));
00390                  next_elem(n, maxelem, graphics);
00391                break;
00392 
00393             case 3: // rounded cylinder
00394             case 5: // flat cylinder
00395 
00396                if (!get_line(line, buffer, 199, infile)) {
00397                   //msgErr << "Raster3D input: error reading cylinder data (line "
00398                          //<< line << ")" << sendmsg;
00399                   return MOLFILE_ERROR;
00400                }
00401 
00402                if (sscanf(buffer, "%f %f %f %f %f %f %f %f %f %f %f",
00403                           data, data + 1, data + 2, data + 3, data + 4,
00404                           data + 5, data + 6, data + 7, data + 8, data + 9,
00405                           data + 10) != 11) {
00406                   //msgErr << "Raster3D input: bad cylinder data (line "
00407                          //<< line << "). Will try to continue." << sendmsg;
00408                   continue;
00409                }
00410                  graphics[n].type = MOLFILE_COLOR;
00411                  color[0] = sqrt(data[8]);
00412                  color[1] = sqrt(data[9]);
00413                  color[2] = sqrt(data[10]);
00414                  memcpy(graphics[n].data, color, 3*sizeof(float));
00415                  next_elem(n, maxelem, graphics);
00416                  graphics[n].type = MOLFILE_CYLINDER;
00417                  graphics[n].size = data[3];
00418                  graphics[n].style = 12; // XXX hard-coded resolution
00419                  memcpy(graphics[n].data, data, 3*sizeof(float));
00420                  memcpy(graphics[n].data+3, data+4, 3*sizeof(float));
00421                  next_elem(n, maxelem, graphics);
00422 
00423                // cap with spheres for object 3
00424                if (objtype == 3) {
00425                  graphics[n].type = MOLFILE_SPHERE;
00426                  graphics[n].size = data[3];
00427                  graphics[n].style = 12; // XXX hard-coded resolution
00428                  memcpy(graphics[n].data, data, 3*sizeof(float));
00429                  next_elem(n, maxelem, graphics);
00430                  graphics[n].type = MOLFILE_SPHERE;
00431                  graphics[n].size = data[3];
00432                  graphics[n].style = 12; // XXX hard-coded resolution
00433                  memcpy(graphics[n].data, data+4, 3*sizeof(float));
00434                  next_elem(n, maxelem, graphics);
00435                }
00436 
00437                break;
00438 
00439             case 9:
00440                break;
00441 
00442             case 6: case 8: case 10: case 11: case 12: case 13: case 15: case 19:
00443 
00444                // Ignore the next line
00445                get_line(line, buffer, 199, infile);
00446 
00447                break;
00448 
00449             case 7:
00450                //msgErr << "Raster3D input: encountered unexpected object 7 (triangle ";
00451                //msgErr << "vertex normals) (line " << line;
00452                //msgErr << "). Will try to continue." << sendmsg;
00453                break;
00454 
00455             case 17:
00456                //msgErr << "Raster3D input: encountered unexpected object 17 (triangle " << sendmsg;
00457                //msgErr << "vertex colors) (line " << line << "). Will try to continue." << sendmsg;
00458                break;
00459 
00460             case 0:  // Raster3D 'force EOF' -- checked later
00461                break;
00462 
00463             // We encountered an object that is not recognized.
00464             // Need to warn the user. Future version of R3d perhaps?
00465             default:
00466                if (!futureVersion) {
00467                   //msgErr << "Raster3D input: encountered unknown object type #"
00468                          //<< objtype << sendmsg;
00469                   //msgErr << " (line " << line << "). Future version of Raster3D maybe?"
00470                          //<< " Will try to continue." << sendmsg;
00471                   futureVersion = 1;
00472                }
00473                break;
00474 
00475          } // end of switch
00476 
00477          // If this is a Raster3d "force EOF" object, break
00478          if (objtype == 0) break;
00479 
00480       } // end of while
00481 
00482    if (ferror(infile)) {
00483       //msgErr << "Raster3D input: read error while reading input file (line "
00484              //<< line << "). Aborting." << sendmsg;
00485       return MOLFILE_ERROR;
00486    }
00487 
00488    // normal exit
00489    *nelem = n;
00490    handle->graphics = graphics;
00491    *gdata = graphics;
00492    return MOLFILE_SUCCESS;
00493 }
00494 
00495 static void close_file_read(void *v) {
00496   handle_t *handle = (handle_t *)v;
00497   fclose(handle->fd);
00498   handle->fd = NULL;
00499   delete [] handle->graphics;
00500   handle->graphics = NULL;
00501   delete handle;
00502 }
00503 
00504 
00505 /*
00506  * Initialization stuff here
00507  */
00508 static molfile_plugin_t plugin = {
00509   vmdplugin_ABIVERSION,  // ABI version
00510   MOLFILE_PLUGIN_TYPE,   // type of plugin
00511   "raster3d",            // short name of plugin
00512   "Raster3d Scene File", // pretty name of plugin
00513   "Justin Gullingsrud",  // authors
00514   0,                     // major version
00515   1,                     // minor version
00516   VMDPLUGIN_THREADSAFE,  // is reentrant
00517   "r3d"                  // filename extension
00518 };
00519 
00520 VMDPLUGIN_API int VMDPLUGIN_init(void) { return VMDPLUGIN_SUCCESS; }
00521 VMDPLUGIN_API int VMDPLUGIN_fini(void) { return VMDPLUGIN_SUCCESS; }
00522 VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
00523   plugin.open_file_read = open_file_read;
00524   plugin.read_rawgraphics = read_rawgraphics;
00525   plugin.close_file_read = close_file_read;
00526   (*cb)(v, (vmdplugin_t *)&plugin);
00527   return VMDPLUGIN_SUCCESS;
00528 }
00529 
00530 

Generated on Wed Mar 22 13:15:31 2006 for VMD Plugins (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002