00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
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
00090
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
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
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
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
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
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
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
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
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
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
00221
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
00250
00251 static molfile_plugin_t plugin = {
00252 vmdplugin_ABIVERSION,
00253 MOLFILE_PLUGIN_TYPE,
00254 "stl",
00255 "STL Stereolithography Triangle Mesh",
00256 "Eamon Caddigan",
00257 0,
00258 1,
00259 VMDPLUGIN_THREADSAFE,
00260 "stl"
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