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, "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
00090
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
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
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
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
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
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
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
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
00187 if(ferror(infile)) {
00188 fprintf(stderr, "stlplugin) error: problem reading file\n");
00189 error = 1;
00190 break;
00191 }
00192 }
00193
00194
00195
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
00206
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
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