[37] | 1 | /* |
---|
| 2 | |
---|
| 3 | Sample code showing how to read and write PLY polygon files. |
---|
| 4 | |
---|
| 5 | Greg Turk, March 1994 |
---|
| 6 | |
---|
| 7 | */ |
---|
| 8 | |
---|
| 9 | #include <stdio.h> |
---|
| 10 | #include <math.h> |
---|
| 11 | #include <ply.h> |
---|
| 12 | #include <malloc.h> |
---|
| 13 | |
---|
| 14 | /* user's vertex and face definitions for a polygonal object */ |
---|
| 15 | |
---|
| 16 | typedef struct Vertex { |
---|
| 17 | float x,y,z; /* the usual 3-space position of a vertex */ |
---|
| 18 | } Vertex; |
---|
| 19 | |
---|
| 20 | typedef struct Face { |
---|
| 21 | unsigned char intensity; /* this user attaches intensity to faces */ |
---|
| 22 | unsigned char nverts; /* number of vertex indices in list */ |
---|
| 23 | int *verts; /* vertex index list */ |
---|
| 24 | } Face; |
---|
| 25 | |
---|
| 26 | /* polygon description of an object (a cube) */ |
---|
| 27 | |
---|
| 28 | Vertex verts[] = { /* vertices */ |
---|
| 29 | { 0.0, 0.0, 0.0}, |
---|
| 30 | { 1.0, 0.0, 0.0}, |
---|
| 31 | { 1.0, 1.0, 0.0}, |
---|
| 32 | { 0.0, 1.0, 0.0}, |
---|
| 33 | { 0.0, 0.0, 1.0}, |
---|
| 34 | { 1.0, 0.0, 1.0}, |
---|
| 35 | { 1.0, 1.0, 1.0}, |
---|
| 36 | { 0.0, 1.0, 1.0}, |
---|
| 37 | }; |
---|
| 38 | |
---|
| 39 | Face faces[] = { /* faces */ |
---|
| 40 | { '\001', 4, NULL }, /* intensity, vertex list count, vertex list (empty) */ |
---|
| 41 | { '\004', 4, NULL }, |
---|
| 42 | { '\010', 4, NULL }, |
---|
| 43 | { '\020', 4, NULL }, |
---|
| 44 | { '\144', 4, NULL }, |
---|
| 45 | { '\377', 4, NULL }, |
---|
| 46 | }; |
---|
| 47 | |
---|
| 48 | /* list of vertices for each face */ |
---|
| 49 | /* (notice that indices begin at zero) */ |
---|
| 50 | |
---|
| 51 | typedef int Vertex_Indices[4]; |
---|
| 52 | Vertex_Indices vert_ptrs[] = { |
---|
| 53 | { 0, 1, 2, 3 }, |
---|
| 54 | { 7, 6, 5, 4 }, |
---|
| 55 | { 0, 4, 5, 1 }, |
---|
| 56 | { 1, 5, 6, 2 }, |
---|
| 57 | { 2, 6, 7, 3 }, |
---|
| 58 | { 3, 7, 4, 0 }, |
---|
| 59 | }; |
---|
| 60 | |
---|
| 61 | /* information needed to describe the user's data to the PLY routines */ |
---|
| 62 | |
---|
| 63 | char *elem_names[] = { /* list of the kinds of elements in the user's object */ |
---|
| 64 | "vertex", "face" |
---|
| 65 | }; |
---|
| 66 | |
---|
| 67 | PlyProperty vert_props[] = { /* list of property information for a vertex */ |
---|
| 68 | {"x", PLY_FLOAT, PLY_FLOAT, offsetof(Vertex,x), 0, 0, 0, 0}, |
---|
| 69 | {"y", PLY_FLOAT, PLY_FLOAT, offsetof(Vertex,y), 0, 0, 0, 0}, |
---|
| 70 | {"z", PLY_FLOAT, PLY_FLOAT, offsetof(Vertex,z), 0, 0, 0, 0}, |
---|
| 71 | }; |
---|
| 72 | |
---|
| 73 | PlyProperty face_props[] = { /* list of property information for a vertex */ |
---|
| 74 | {"intensity", PLY_UCHAR, PLY_UCHAR, offsetof(Face,intensity), 0, 0, 0, 0}, |
---|
| 75 | {"vertex_indices", PLY_INT, PLY_INT, offsetof(Face,verts), |
---|
| 76 | 1, PLY_UCHAR, PLY_UCHAR, offsetof(Face,nverts)}, |
---|
| 77 | }; |
---|
| 78 | |
---|
| 79 | |
---|
| 80 | |
---|
| 81 | /****************************************************************************** |
---|
| 82 | The main routine just creates and then reads a PLY file. |
---|
| 83 | ******************************************************************************/ |
---|
| 84 | |
---|
| 85 | main() |
---|
| 86 | { |
---|
| 87 | |
---|
| 88 | #if 1 |
---|
| 89 | /* write a PLY file */ |
---|
| 90 | write_test(); |
---|
| 91 | #endif |
---|
| 92 | |
---|
| 93 | #if 1 |
---|
| 94 | /* read a PLY file */ |
---|
| 95 | read_test(); |
---|
| 96 | #endif |
---|
| 97 | |
---|
| 98 | } |
---|
| 99 | |
---|
| 100 | |
---|
| 101 | /****************************************************************************** |
---|
| 102 | Write out a PLY file. |
---|
| 103 | ******************************************************************************/ |
---|
| 104 | |
---|
| 105 | int write_test() |
---|
| 106 | { |
---|
| 107 | int i,j; |
---|
| 108 | PlyFile *ply; |
---|
| 109 | int nelems; |
---|
| 110 | char **elist; |
---|
| 111 | int file_type; |
---|
| 112 | float version; |
---|
| 113 | int nverts = sizeof (verts) / sizeof (Vertex); |
---|
| 114 | int nfaces = sizeof (faces) / sizeof (Face); |
---|
| 115 | |
---|
| 116 | /* create the vertex index lists for the faces */ |
---|
| 117 | for (i = 0; i < nfaces; i++) |
---|
| 118 | faces[i].verts = vert_ptrs[i]; |
---|
| 119 | |
---|
| 120 | /* open either a binary or ascii PLY file for writing */ |
---|
| 121 | /* (the file will be called "test.ply" because the routines */ |
---|
| 122 | /* enforce the .ply filename extension) */ |
---|
| 123 | |
---|
| 124 | #if 1 |
---|
| 125 | ply = ply_open_for_writing("test", 2, elem_names, PLY_ASCII, &version); |
---|
| 126 | #else |
---|
| 127 | ply = ply_open_for_writing("test", 2, elem_names, PLY_BINARY_BE, &version); |
---|
| 128 | #endif |
---|
| 129 | |
---|
| 130 | /* describe what properties go into the vertex and face elements */ |
---|
| 131 | |
---|
| 132 | ply_element_count (ply, "vertex", nverts); |
---|
| 133 | ply_describe_property (ply, "vertex", &vert_props[0]); |
---|
| 134 | ply_describe_property (ply, "vertex", &vert_props[1]); |
---|
| 135 | ply_describe_property (ply, "vertex", &vert_props[2]); |
---|
| 136 | |
---|
| 137 | ply_element_count (ply, "face", nfaces); |
---|
| 138 | ply_describe_property (ply, "face", &face_props[0]); |
---|
| 139 | ply_describe_property (ply, "face", &face_props[1]); |
---|
| 140 | |
---|
| 141 | /* write a comment and an object information field */ |
---|
| 142 | ply_put_comment (ply, "author: Greg Turk"); |
---|
| 143 | ply_put_obj_info (ply, "random information"); |
---|
| 144 | |
---|
| 145 | /* we have described exactly what we will put in the file, so */ |
---|
| 146 | /* we are now done with the header info */ |
---|
| 147 | ply_header_complete (ply); |
---|
| 148 | |
---|
| 149 | /* set up and write the vertex elements */ |
---|
| 150 | ply_put_element_setup (ply, "vertex"); |
---|
| 151 | for (i = 0; i < nverts; i++) |
---|
| 152 | ply_put_element (ply, (void *) &verts[i]); |
---|
| 153 | |
---|
| 154 | /* set up and write the face elements */ |
---|
| 155 | ply_put_element_setup (ply, "face"); |
---|
| 156 | for (i = 0; i < nfaces; i++) |
---|
| 157 | ply_put_element (ply, (void *) &faces[i]); |
---|
| 158 | |
---|
| 159 | /* close the PLY file */ |
---|
| 160 | ply_close (ply); |
---|
| 161 | |
---|
| 162 | return(0); |
---|
| 163 | } |
---|
| 164 | |
---|
| 165 | |
---|
| 166 | /****************************************************************************** |
---|
| 167 | Read in a PLY file. |
---|
| 168 | ******************************************************************************/ |
---|
| 169 | |
---|
| 170 | int read_test() |
---|
| 171 | { |
---|
| 172 | int i,j,k; |
---|
| 173 | PlyFile *ply; |
---|
| 174 | int nelems; |
---|
| 175 | char **elist; |
---|
| 176 | int file_type; |
---|
| 177 | float version; |
---|
| 178 | int nprops; |
---|
| 179 | int num_elems; |
---|
| 180 | PlyProperty **plist; |
---|
| 181 | Vertex **vlist; |
---|
| 182 | Face **flist; |
---|
| 183 | char *elem_name; |
---|
| 184 | int num_comments; |
---|
| 185 | char **comments; |
---|
| 186 | int num_obj_info; |
---|
| 187 | char **obj_info; |
---|
| 188 | |
---|
| 189 | /* open a PLY file for reading */ |
---|
| 190 | ply = ply_open_for_reading("test", &nelems, &elist, &file_type, &version); |
---|
| 191 | |
---|
| 192 | /* print what we found out about the file */ |
---|
| 193 | printf ("version %f\n", version); |
---|
| 194 | printf ("type %d\n", file_type); |
---|
| 195 | |
---|
| 196 | /* go through each kind of element that we learned is in the file */ |
---|
| 197 | /* and read them */ |
---|
| 198 | |
---|
| 199 | for (i = 0; i < nelems; i++) { |
---|
| 200 | |
---|
| 201 | /* get the description of the first element */ |
---|
| 202 | elem_name = elist[i]; |
---|
| 203 | plist = ply_get_element_description (ply, elem_name, &num_elems, &nprops); |
---|
| 204 | |
---|
| 205 | /* print the name of the element, for debugging */ |
---|
| 206 | printf ("element %s %d\n", elem_name, num_elems); |
---|
| 207 | |
---|
| 208 | /* if we're on vertex elements, read them in */ |
---|
| 209 | if (equal_strings ("vertex", elem_name)) { |
---|
| 210 | |
---|
| 211 | /* create a vertex list to hold all the vertices */ |
---|
| 212 | vlist = (Vertex **) malloc (sizeof (Vertex *) * num_elems); |
---|
| 213 | |
---|
| 214 | /* set up for getting vertex elements */ |
---|
| 215 | |
---|
| 216 | ply_get_property (ply, elem_name, &vert_props[0]); |
---|
| 217 | ply_get_property (ply, elem_name, &vert_props[1]); |
---|
| 218 | ply_get_property (ply, elem_name, &vert_props[2]); |
---|
| 219 | |
---|
| 220 | /* grab all the vertex elements */ |
---|
| 221 | for (j = 0; j < num_elems; j++) { |
---|
| 222 | |
---|
| 223 | /* grab and element from the file */ |
---|
| 224 | vlist[j] = (Vertex *) malloc (sizeof (Vertex)); |
---|
| 225 | ply_get_element (ply, (void *) vlist[j]); |
---|
| 226 | |
---|
| 227 | /* print out vertex x,y,z for debugging */ |
---|
| 228 | printf ("vertex: %g %g %g\n", vlist[j]->x, vlist[j]->y, vlist[j]->z); |
---|
| 229 | } |
---|
| 230 | } |
---|
| 231 | |
---|
| 232 | /* if we're on face elements, read them in */ |
---|
| 233 | if (equal_strings ("face", elem_name)) { |
---|
| 234 | |
---|
| 235 | /* create a list to hold all the face elements */ |
---|
| 236 | flist = (Face **) malloc (sizeof (Face *) * num_elems); |
---|
| 237 | |
---|
| 238 | /* set up for getting face elements */ |
---|
| 239 | |
---|
| 240 | ply_get_property (ply, elem_name, &face_props[0]); |
---|
| 241 | ply_get_property (ply, elem_name, &face_props[1]); |
---|
| 242 | |
---|
| 243 | /* grab all the face elements */ |
---|
| 244 | for (j = 0; j < num_elems; j++) { |
---|
| 245 | |
---|
| 246 | /* grab and element from the file */ |
---|
| 247 | flist[j] = (Face *) malloc (sizeof (Face)); |
---|
| 248 | ply_get_element (ply, (void *) flist[j]); |
---|
| 249 | |
---|
| 250 | /* print out face info, for debugging */ |
---|
| 251 | printf ("face: %d, list = ", flist[j]->intensity); |
---|
| 252 | for (k = 0; k < flist[j]->nverts; k++) |
---|
| 253 | printf ("%d ", flist[j]->verts[k]); |
---|
| 254 | printf ("\n"); |
---|
| 255 | } |
---|
| 256 | } |
---|
| 257 | |
---|
| 258 | /* print out the properties we got, for debugging */ |
---|
| 259 | for (j = 0; j < nprops; j++) |
---|
| 260 | printf ("property %s\n", plist[j]->name); |
---|
| 261 | } |
---|
| 262 | |
---|
| 263 | /* grab and print out the comments in the file */ |
---|
| 264 | comments = ply_get_comments (ply, &num_comments); |
---|
| 265 | for (i = 0; i < num_comments; i++) |
---|
| 266 | printf ("comment = '%s'\n", comments[i]); |
---|
| 267 | |
---|
| 268 | /* grab and print out the object information */ |
---|
| 269 | obj_info = ply_get_obj_info (ply, &num_obj_info); |
---|
| 270 | for (i = 0; i < num_obj_info; i++) |
---|
| 271 | printf ("obj_info = '%s'\n", obj_info[i]); |
---|
| 272 | |
---|
| 273 | /* close the PLY file */ |
---|
| 274 | ply_close (ply); |
---|
| 275 | |
---|
| 276 | return(0); |
---|
| 277 | } |
---|
| 278 | |
---|