00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <stdio.h>
00019 #include <math.h>
00020 #include <string.h>
00021 #include "molfile_plugin.h"
00022 #include "endianswap.h"
00023
00024 #include "ply.h"
00025 #include "ply.c"
00026
00027
00028
00029 typedef struct Vertex {
00030 float x,y,z;
00031 float r,g,b;
00032 float nx,ny,nz;
00033 void *other_props;
00034 } Vertex;
00035
00036 typedef struct Face {
00037 unsigned char nverts;
00038 int *verts;
00039 void *other_props;
00040 } Face;
00041
00042 PlyProperty vert_props[] = {
00043 {"x", Float32, Float32, offsetof(Vertex,x), 0, 0, 0, 0},
00044 {"y", Float32, Float32, offsetof(Vertex,y), 0, 0, 0, 0},
00045 {"z", Float32, Float32, offsetof(Vertex,z), 0, 0, 0, 0},
00046 {"r", Float32, Float32, offsetof(Vertex,r), 0, 0, 0, 0},
00047 {"g", Float32, Float32, offsetof(Vertex,g), 0, 0, 0, 0},
00048 {"b", Float32, Float32, offsetof(Vertex,b), 0, 0, 0, 0},
00049 {"nx", Float32, Float32, offsetof(Vertex,nx), 0, 0, 0, 0},
00050 {"ny", Float32, Float32, offsetof(Vertex,ny), 0, 0, 0, 0},
00051 {"nz", Float32, Float32, offsetof(Vertex,nz), 0, 0, 0, 0},
00052 };
00053
00054 PlyProperty face_props[] = {
00055 {"vertex_indices", Int32, Int32, offsetof(Face,verts),
00056 1, Uint8, Uint8, offsetof(Face,nverts)},
00057 {"vertex_index", Int32, Int32, offsetof(Face,verts),
00058 1, Uint8, Uint8, offsetof(Face,nverts)},
00059 };
00060
00061
00062
00064 typedef struct {
00065 FILE *fd;
00066 molfile_graphics_t *graphics;
00067
00068 int per_vertex_color;
00069 int has_normals;
00070 } ply_t;
00071
00072
00073 static void *open_file_read(const char *filepath, const char *filetype,
00074 int *natoms) {
00075 FILE *fd;
00076 ply_t *ply;
00077
00078 printf("plyplugin) Opening PLY file '%s'\n", filepath);
00079 fd = fopen(filepath, "rb");
00080 if (!fd)
00081 return NULL;
00082 ply = new ply_t;
00083 ply->fd = fd;
00084 ply->graphics = NULL;
00085 *natoms = 0;
00086 return ply;
00087 }
00088
00089
00090 static int read_rawgraphics(void *v, int *nelem,
00091 const molfile_graphics_t **data) {
00092 ply_t *ply = (ply_t *)v;
00093 ply->per_vertex_color = 0;
00094 ply->has_normals = 0;
00095
00096 int i=0;
00097 int nverts=0;
00098 int nfaces=0;
00099 char *elem_name=NULL;
00100 Vertex **vlist=NULL;
00101 Face **flist=NULL;
00102 PlyOtherProp *vert_other=NULL;
00103 PlyOtherProp *face_other=NULL;
00104
00105 printf("plyplugin) Reading PLY file header...\n");
00106 PlyFile *in_ply = read_ply(ply->fd);
00107
00108 printf("plyplugin) Processing PLY contents...\n");
00109 printf("plyplugin) num_elem_types: %d\n", in_ply->num_elem_types);
00110
00111 for (i=0; i<in_ply->num_elem_types; i++) {
00112 int elem_count = 0;
00113
00114
00115 elem_name = setup_element_read_ply (in_ply, i, &elem_count);
00116
00117 if (equal_strings ("vertex", elem_name)) {
00118 int j=0;
00119 nverts = elem_count;
00120 printf("plyplugin) reading %d vertex elements...\n", nverts);
00121
00122
00123 vlist = (Vertex **) calloc (1, sizeof(Vertex *)*nverts);
00124
00125
00126 setup_property_ply(in_ply, &vert_props[0]);
00127 setup_property_ply(in_ply, &vert_props[1]);
00128 setup_property_ply(in_ply, &vert_props[2]);
00129
00130 for (j=0; j<in_ply->elems[i]->nprops; j++) {
00131 PlyProperty *prop;
00132 prop = in_ply->elems[i]->props[j];
00133 if (equal_strings ("r", prop->name)) {
00134 setup_property_ply(in_ply, &vert_props[3]);
00135 ply->per_vertex_color = 1;
00136 }
00137 if (equal_strings ("g", prop->name)) {
00138 setup_property_ply(in_ply, &vert_props[4]);
00139 ply->per_vertex_color = 1;
00140 }
00141 if (equal_strings ("b", prop->name)) {
00142 setup_property_ply(in_ply, &vert_props[5]);
00143 ply->per_vertex_color = 1;
00144 }
00145 if (equal_strings ("nx", prop->name)) {
00146 setup_property_ply(in_ply, &vert_props[6]);
00147 ply->has_normals = 1;
00148 }
00149 if (equal_strings ("ny", prop->name)) {
00150 setup_property_ply(in_ply, &vert_props[7]);
00151 ply->has_normals = 1;
00152 }
00153 if (equal_strings ("nz", prop->name)) {
00154 setup_property_ply(in_ply, &vert_props[8]);
00155 ply->has_normals = 1;
00156 }
00157 }
00158
00159 vert_other = get_other_properties_ply(in_ply,
00160 offsetof(Vertex,other_props));
00161
00162
00163 for (j=0; j<nverts; j++) {
00164 vlist[j] = (Vertex *) calloc(1, sizeof(Vertex));
00165 vlist[j]->r = 1;
00166 vlist[j]->g = 1;
00167 vlist[j]->b = 1;
00168 get_element_ply (in_ply, (void *) vlist[j]);
00169 }
00170
00171 } else if (equal_strings ("face", elem_name)) {
00172 int j=0;
00173 nfaces = elem_count;
00174 printf("plyplugin) reading %d face elements...\n", nfaces);
00175
00176
00177 flist = (Face **) calloc(1, sizeof(Face *)*nfaces);
00178
00179
00180 for (j=0; j<in_ply->elems[i]->nprops; j++) {
00181 PlyProperty *prop;
00182 prop = in_ply->elems[i]->props[j];
00183 if (equal_strings ("vertex_indices", prop->name)) {
00184 setup_property_ply(in_ply, &face_props[0]);
00185 }
00186 if (equal_strings ("vertex_index", prop->name)) {
00187 setup_property_ply(in_ply, &face_props[1]);
00188 }
00189 }
00190
00191 face_other = get_other_properties_ply (in_ply,
00192 offsetof(Face,other_props));
00193
00194
00195 for (j=0; j<nfaces; j++) {
00196 flist[j] = (Face *) calloc(1, sizeof(Face));
00197 get_element_ply(in_ply, (void *) flist[j]);
00198 }
00199 } else {
00200 printf("plyplugin) reading other elements...\n");
00201 get_other_element_ply(in_ply);
00202 }
00203 }
00204
00205 printf("plyplugin) freeing PLY structures\n");
00206 free_ply(in_ply);
00207 in_ply = NULL;
00208
00209 printf("plyplugin) generating %d graphics primitives...\n", nfaces);
00210 ply->graphics = new molfile_graphics_t[2*nfaces];
00211 int vert1, vert2, vert3;
00212
00213 for (i=0; i<nfaces; i++) {
00214 if (flist[i]->nverts != 3) {
00215 printf("plyplugin) Found non-triangle facet, aborting.\n");
00216 return MOLFILE_ERROR;
00217 }
00218 vert1 = flist[i]->verts[0];
00219 vert2 = flist[i]->verts[1];
00220 vert3 = flist[i]->verts[2];
00221
00222 if (vert1 < 0 || vert2 < 0 || vert3 < 0 ||
00223 vert1 >= nverts || vert2 >= nverts || vert3 >= nverts) {
00224 printf("plyplugin) Error, out-of-range vertex index, aborting.\n");
00225 return MOLFILE_ERROR;
00226 }
00227
00228 ply->graphics[i].type = MOLFILE_TRIANGLE;
00229 float *tridata = ply->graphics[i].data;
00230 tridata[0] = vlist[vert1]->x;
00231 tridata[1] = vlist[vert1]->y;
00232 tridata[2] = vlist[vert1]->z;
00233 tridata[3] = vlist[vert2]->x;
00234 tridata[4] = vlist[vert2]->y;
00235 tridata[5] = vlist[vert2]->z;
00236 tridata[6] = vlist[vert3]->x;
00237 tridata[7] = vlist[vert3]->y;
00238 tridata[8] = vlist[vert3]->z;
00239 }
00240
00241 *nelem = nfaces;
00242 *data = ply->graphics;
00243
00244 printf("plyplugin) freeing ply face list\n");
00245 for (i=0; i<nfaces; i++) {
00246 free(flist[i]);
00247 }
00248 memset(flist, 0, sizeof(Face *)*nfaces);
00249 free(flist);
00250 flist = NULL;
00251
00252 printf("plyplugin) freeing ply vertex list\n");
00253 for (i=0; i<nverts; i++) {
00254 free(vlist[i]);
00255 }
00256 memset(vlist, 0, sizeof(float *)*nverts);
00257 free(vlist);
00258 vlist=NULL;
00259
00260 return MOLFILE_SUCCESS;
00261 }
00262
00263
00264 static void close_file_read(void *v) {
00265 ply_t *ply = (ply_t *)v;
00266
00267 fclose(ply->fd);
00268
00269 delete [] ply->graphics;
00270 delete ply;
00271 }
00272
00273
00274
00275
00276
00277 static molfile_plugin_t plugin;
00278
00279 VMDPLUGIN_API int VMDPLUGIN_init(void) {
00280 memset(&plugin, 0, sizeof(molfile_plugin_t));
00281 plugin.abiversion = vmdplugin_ABIVERSION;
00282 plugin.type = MOLFILE_PLUGIN_TYPE;
00283 plugin.name = "ply";
00284 plugin.prettyname = "PLY";
00285 plugin.author = "John Stone";
00286 plugin.majorv = 0;
00287 plugin.minorv = 2;
00288 plugin.is_reentrant = VMDPLUGIN_THREADSAFE;
00289 plugin.filename_extension = "ply";
00290 plugin.open_file_read = open_file_read;
00291 plugin.read_rawgraphics = read_rawgraphics;
00292 plugin.close_file_read = close_file_read;
00293 return VMDPLUGIN_SUCCESS;
00294 }
00295
00296 VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
00297 (*cb)(v, (vmdplugin_t *)&plugin);
00298 return VMDPLUGIN_SUCCESS;
00299 }
00300
00301 VMDPLUGIN_API int VMDPLUGIN_fini(void) { return VMDPLUGIN_SUCCESS; }
00302
00303
00304