Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

stlplugin.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr
00003  *cr            (C) Copyright 1995-2016 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.16 $       $Date: 2016/11/28 05:01:54 $
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, "stlplugin) 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       fprintf(stderr, "stlplugin) error: expected \"solid\".\n");
00095       error = 1;
00096     }
00097 
00098     // "facet normal ni nj nk"
00099     fgets(line, 80, infile);
00100     sscanf(line, " %s", keyWord);
00101     if (strcasecmp(keyWord, "facet") != 0) {
00102       fprintf(stderr, "stlplugin) error: expected \"facet\".\n");
00103       error = 1;
00104     } else {
00105       gListPtr = new molfile_graphics_list;
00106       gListPtr->next = NULL;
00107       gListPtr->gItem.type = MOLFILE_TRIANGLE;
00108       ntriangles++;
00109       tmpPtr = gListPtr;
00110     }
00111 
00112     while ( !feof(infile) && (error == 0) ) {
00113       // "outer loop"
00114       fgets(line, 80, infile);
00115       sscanf(line, " %s", keyWord);
00116       if (strcasecmp(keyWord, "outer") != 0) {
00117         fprintf(stderr, "stlplugin) error: expected \"outer\".\n");
00118         error = 1;
00119         break;
00120       } else {
00121         i = 0;
00122       }
00123         
00124       // "vertex vx, vy, vz"
00125       while (i < 9) {
00126         fgets(line, 80, infile);
00127         sscanf(line, " %s", keyWord);
00128         if (strcasecmp(keyWord, "vertex") != 0) {
00129           fprintf(stderr, "stlplugin) error: expected \"vertex\".\n");
00130           error = 1;
00131           break; 
00132         } else {
00133           float t1=0.0f, t2=0.0f, t3=0.0f;
00134           if ( sscanf(line, " %*s %f %f %f", &t1, &t2, &t3) == 3 ) {
00135             tmpPtr->gItem.data[i++] = t1;
00136             tmpPtr->gItem.data[i++] = t2;
00137             tmpPtr->gItem.data[i++] = t3;
00138           } else {
00139             fprintf(stderr, "stlplugin) error: not enough vertices.\n");
00140             error = 1;
00141             break;
00142           }
00143         }
00144       }
00145       if (error != 0) break;
00146 
00147       // "endloop"
00148       fgets(line, 80, infile);
00149       sscanf(line, " %s", keyWord);
00150       if (strcasecmp(keyWord, "endloop") != 0) {
00151         fprintf(stderr, "stlplugin) error: expected \"endloop\".\n");
00152         error = 1;
00153         break;
00154       }
00155       
00156       // "endfacet"
00157       fgets(line, 80, infile);
00158       sscanf(line, " %s", keyWord);
00159       if (strcasecmp(keyWord, "endfacet") != 0) {
00160         fprintf(stderr, "stlplugin) error: expected \"endfacet\".\n");
00161         error = 1;
00162         break;
00163       }
00164 
00165       // "endsolid" or "facet normal ni nj nk"
00166       fgets(line, 80, infile);
00167       sscanf(line, " %s", keyWord);
00168       if (strcasecmp(keyWord, "endsolid") == 0) {
00169         break;
00170       }
00171 
00172       if (strcasecmp(keyWord, "facet") == 0) {
00173         // Create a new list item and initialize it.
00174         tmpPtr->next = new molfile_graphics_list;
00175         tmpPtr = tmpPtr->next;
00176         tmpPtr->next = NULL;
00177         tmpPtr->gItem.type = MOLFILE_TRIANGLE;
00178         ntriangles++;
00179       } else {
00180         fprintf(stderr, 
00181                 "stlplugin) error: expected \"facet\" or \"endsolid\".\n");
00182         error = 1;
00183         break;
00184       }
00185 
00186       // file error
00187       if(ferror(infile)) {
00188         fprintf(stderr, "stlplugin) error: problem reading file\n");
00189         error = 1;
00190         break;
00191       }
00192     }
00193 
00194 
00195     // If an error occurred, free the linked list and return MOLFILE_ERROR
00196     if (error != 0) {
00197       while (gListPtr != NULL) {
00198         tmpPtr = gListPtr->next;
00199         delete gListPtr;
00200         gListPtr = tmpPtr;
00201       }
00202       return MOLFILE_ERROR;
00203     }
00204 
00205     // Create the array of molfile_graphics_t, and copy the data from the
00206     // linked list into it, deleting the list as you go.
00207     stl->graphics = new molfile_graphics_t[ntriangles];
00208     i = 0;
00209     while (gListPtr != NULL) {
00210       stl->graphics[i] = gListPtr->gItem;
00211       tmpPtr = gListPtr->next;
00212       delete gListPtr;
00213       gListPtr = tmpPtr;
00214       i++;
00215     }
00216 
00217     *nelem = ntriangles;
00218     *data = stl->graphics;
00219 
00220     return MOLFILE_SUCCESS;
00221 }
00222 
00223 static void close_file_read(void *v) {
00224   stl_t *stl = (stl_t *)v;
00225   fclose(stl->fd);
00226   if (stl->graphics != NULL)
00227     delete [] stl->graphics;
00228   delete stl;
00229 }
00230 
00231 
00232 /*
00233  * Initialization stuff here
00234  */
00235 static molfile_plugin_t plugin;
00236 
00237 VMDPLUGIN_API int VMDPLUGIN_init(void) {
00238   memset(&plugin, 0, sizeof(molfile_plugin_t));
00239   plugin.abiversion = vmdplugin_ABIVERSION;
00240   plugin.type = MOLFILE_PLUGIN_TYPE;
00241   plugin.name = "stl";
00242   plugin.prettyname = "STL Stereolithography Triangle Mesh";
00243   plugin.author = "Eamon Caddigan";
00244   plugin.minorv = 0;
00245   plugin.majorv = 3;
00246   plugin.is_reentrant = VMDPLUGIN_THREADSAFE;
00247   plugin.filename_extension = "stl";
00248   plugin.open_file_read = open_file_read;
00249   plugin.read_rawgraphics = read_rawgraphics;
00250   plugin.close_file_read = close_file_read;
00251   return VMDPLUGIN_SUCCESS;
00252 }
00253 
00254 VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
00255   (*cb)(v, (vmdplugin_t *)&plugin);
00256   return VMDPLUGIN_SUCCESS;
00257 }
00258 
00259 VMDPLUGIN_API int VMDPLUGIN_fini(void) { return VMDPLUGIN_SUCCESS; }
00260 

Generated on Tue Aug 11 03:06:42 2020 for VMD Plugins (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002