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

stlplugin.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr
00003  *cr            (C) Copyright 1995-2006 The Board of Trustees of the
00004  *cr                        University of Illinois
00005  *cr                         All Rights Reserved
00006  *cr
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  * RCS INFORMATION:
00011  *
00012  *      $RCSfile: stlplugin.C,v $
00013  *      $Author: johns $       $Locker:  $             $State: Exp $
00014  *      $Revision: 1.11 $       $Date: 2006/02/23 19:36:45 $
00015  *
00016  ***************************************************************************/
00017 
00018 /*
00019  *  STL files are used by most Automatic Fabricators (3D printers). Only 
00020  *  triangles are used to represent the geometry. 
00021  *
00022  *  ASCII STL files follow the following format. Files are case insensitive
00023  *  and whitespace is ignored.
00024  *
00025  *  solid name                ("name" is an arbitrary label for the solid)
00026  *  facet normal ni nj nk     (<n> is a unit normal of the triangle)
00027  *  outer loop
00028  *  vertex v1x v1y v1z        (<v1> is the first vertex)
00029  *  vertex v2x v2y v2z        (vertices are given in anti-clockwise order)
00030  *  vertex v3x v3y v3z        (vertices are given as floating-point values)
00031  *  endloop                   (there is no space in the label "endloop")
00032  *  endfacet                  (likewise)
00033  *  ...                       (additional facets are given as above)
00034  *  endsolid name             (this ends the stl file, same name as above)
00035  */
00036 
00037 #include <stdlib.h>
00038 #include <stdio.h>
00039 #include <ctype.h>
00040 #include <math.h>
00041 #include <string.h>
00042 
00043 #if defined(_AIX)
00044 #include <strings.h>
00045 #endif
00046 
00047 #if defined(WIN32) || defined(WIN64)
00048 #define strcasecmp stricmp
00049 #endif
00050 
00051 #include "molfile_plugin.h"
00052 
00053 typedef struct graphics_list {
00054   molfile_graphics_t gItem;
00055   struct graphics_list *next;
00056 } molfile_graphics_list;
00057 
00058 typedef struct {
00059   FILE *fd;
00060   molfile_graphics_t *graphics;
00061 } stl_t;
00062 
00063 static void *open_file_read(const char *filepath, const char *filetype,
00064     int *natoms) {
00065   FILE *fd;
00066   stl_t *stl;
00067   
00068   fd = fopen(filepath, "rb");
00069   if (!fd) {
00070     fprintf(stderr, "Error opening file.\n");
00071     return NULL;
00072   }
00073   stl = new stl_t;
00074   stl->fd = fd;
00075   stl->graphics = NULL;
00076   *natoms = 0;
00077   return stl;
00078 }
00079 
00080 static int read_rawgraphics(void *v, int *nelem, 
00081     const molfile_graphics_t **data) {
00082     molfile_graphics_list *gListPtr=NULL, *tmpPtr=NULL;
00083     int i=0, ntriangles=0;
00084     int error=0;
00085     stl_t *stl = (stl_t *)v;
00086     FILE *infile = stl->fd;
00087     char line[81], keyWord[81];
00088 
00089     // Check your head(er)
00090     // "solid name"
00091     fgets(line, 80, infile);
00092     sscanf(line, " %s", keyWord);
00093     if (strcasecmp(keyWord, "solid") != 0)
00094     {
00095       fprintf(stderr, "STL file error: expected \"solid\".\n");
00096       error = 1;
00097     }
00098 
00099     // "facet normal ni nj nk"
00100     fgets(line, 80, infile);
00101     sscanf(line, " %s", keyWord);
00102     if (strcasecmp(keyWord, "facet") != 0)
00103     {
00104       fprintf(stderr, "STL file error: expected \"facet\".\n");
00105       error = 1;
00106     }
00107     else
00108     {
00109       gListPtr = new molfile_graphics_list;
00110       gListPtr->next = NULL;
00111       gListPtr->gItem.type = MOLFILE_TRIANGLE;
00112       ntriangles++;
00113       tmpPtr = gListPtr;
00114     }
00115 
00116     while ( !feof(infile) && (error == 0) )
00117     {
00118       // "outer loop"
00119       fgets(line, 80, infile);
00120       sscanf(line, " %s", keyWord);
00121       if (strcasecmp(keyWord, "outer") != 0)
00122       {
00123         fprintf(stderr, "STL file error: expected \"outer\".\n");
00124         error = 1;
00125         break;
00126       }
00127       else
00128       {
00129         i = 0;
00130       }
00131         
00132       // "vertex vx, vy, vz"
00133       while (i < 9)
00134       {
00135         fgets(line, 80, infile);
00136         sscanf(line, " %s", keyWord);
00137         if (strcasecmp(keyWord, "vertex") != 0)
00138         {
00139           fprintf(stderr, "STL file error: expected \"vertex\".\n");
00140           error = 1;
00141           break; 
00142         }
00143         else if ( sscanf(line, " %*s %f %f %f", &(tmpPtr->gItem.data[i++]),
00144                          &(tmpPtr->gItem.data[i++]), 
00145                          &(tmpPtr->gItem.data[i++])) != 3 )
00146         {
00147           fprintf(stderr, "STL file error: not enough vertices.\n");
00148           error = 1;
00149           break;
00150         }
00151       }
00152       if (error != 0) break;
00153 
00154       // "endloop"
00155       fgets(line, 80, infile);
00156       sscanf(line, " %s", keyWord);
00157       if (strcasecmp(keyWord, "endloop") != 0)
00158       {
00159         fprintf(stderr, "STL file error: expected \"endloop\".\n");
00160         error = 1;
00161         break;
00162       }
00163       
00164       // "endfacet"
00165       fgets(line, 80, infile);
00166       sscanf(line, " %s", keyWord);
00167       if (strcasecmp(keyWord, "endfacet") != 0)
00168       {
00169         fprintf(stderr, "STL file error: expected \"endfacet\".\n");
00170         error = 1;
00171         break;
00172       }
00173 
00174       // "endsolid" or "facet normal ni nj nk"
00175       fgets(line, 80, infile);
00176       sscanf(line, " %s", keyWord);
00177       if (strcasecmp(keyWord, "endsolid") == 0)
00178       {
00179         break;
00180       }
00181       if (strcasecmp(keyWord, "facet") == 0)
00182       {
00183         // Create a new list item and initialize it.
00184         tmpPtr->next = new molfile_graphics_list;
00185         tmpPtr = tmpPtr->next;
00186         tmpPtr->next = NULL;
00187         tmpPtr->gItem.type = MOLFILE_TRIANGLE;
00188         ntriangles++;
00189       }
00190       else
00191       {
00192         fprintf(stderr, 
00193                 "STL file error: expected \"facet\" or \"endsolid\".\n");
00194         error = 1;
00195         break;
00196       }
00197 
00198       // file error
00199       if(ferror(infile))
00200       {
00201         fprintf(stderr, "STL file error: problem reading file\n");
00202         error = 1;
00203         break;
00204       }
00205     }
00206 
00207 
00208     // If an error occurred, free the linked list and return MOLFILE_ERROR
00209     if (error != 0)
00210     {
00211       while (gListPtr != NULL)
00212       {
00213         tmpPtr = gListPtr->next;
00214         delete gListPtr;
00215         gListPtr = tmpPtr;
00216       }
00217       return MOLFILE_ERROR;
00218     }
00219 
00220     // Create the array of molfile_graphics_t, and copy the data from the
00221     // linked list into it, deleting the list as you go.
00222     stl->graphics = new molfile_graphics_t[ntriangles];
00223     i = 0;
00224     while (gListPtr != NULL)
00225     {
00226       stl->graphics[i] = gListPtr->gItem;
00227       tmpPtr = gListPtr->next;
00228       delete gListPtr;
00229       gListPtr = tmpPtr;
00230       i++;
00231     }
00232 
00233     *nelem = ntriangles;
00234     *data = stl->graphics;
00235 
00236     return MOLFILE_SUCCESS;
00237 }
00238 
00239 static void close_file_read(void *v) {
00240   stl_t *stl = (stl_t *)v;
00241   fclose(stl->fd);
00242   if (stl->graphics != NULL)
00243     delete [] stl->graphics;
00244   delete stl;
00245 }
00246 
00247 
00248 /*
00249  * Initialization stuff here
00250  */
00251 static molfile_plugin_t plugin = {
00252   vmdplugin_ABIVERSION,   // ABI version
00253   MOLFILE_PLUGIN_TYPE,    // type of plugin
00254   "stl",                  // name of plugin
00255   "STL Stereolithography Triangle Mesh", // pretty name of plugin
00256   "Eamon Caddigan",       // author
00257   0,                      // major version
00258   1,                      // minor version
00259   VMDPLUGIN_THREADSAFE,   // is reentrant
00260   "stl"                   // filename extension 
00261 };
00262 
00263 VMDPLUGIN_API int VMDPLUGIN_init(void) { return VMDPLUGIN_SUCCESS; }
00264 VMDPLUGIN_API int VMDPLUGIN_fini(void) { return VMDPLUGIN_SUCCESS; }
00265 VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
00266   plugin.open_file_read = open_file_read;
00267   plugin.read_rawgraphics = read_rawgraphics;
00268   plugin.close_file_read = close_file_read;
00269   (*cb)(v, (vmdplugin_t *)&plugin);
00270   return VMDPLUGIN_SUCCESS;
00271 }
00272 
00273 

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