Blender  V2.59
BSP_PlyLoader.cpp
Go to the documentation of this file.
00001 
00029 #include "BSP_PlyLoader.h"
00030 
00031 #include "MT_Vector3.h"
00032 #include "ply.h"
00033 
00034 struct LoadVertex {
00035   float x,y,z;             /* the usual 3-space position of a vertex */
00036 };
00037 
00038 struct LoadFace {
00039   unsigned char intensity; /* this user attaches intensity to faces */
00040   unsigned char nverts;    /* number of vertex indices in list */
00041   int *verts;              /* vertex index list */
00042 };
00043 
00044 
00045         MEM_SmartPtr<BSP_TMesh>
00046 BSP_PlyLoader::
00047 NewMeshFromFile(
00048         char * file_name,
00049         MT_Vector3 &min,
00050         MT_Vector3 &max
00051 
00052 ) {
00053 
00054         min = MT_Vector3(MT_INFINITY,MT_INFINITY,MT_INFINITY);
00055         max = MT_Vector3(-MT_INFINITY,-MT_INFINITY,-MT_INFINITY);
00056         
00057         PlyProperty vert_props[] = { /* list of property information for a vertex */
00058           {"x", PLY_FLOAT, PLY_FLOAT, offsetof(LoadVertex,x), 0, 0, 0, 0},
00059           {"y", PLY_FLOAT, PLY_FLOAT, offsetof(LoadVertex,y), 0, 0, 0, 0},
00060           {"z", PLY_FLOAT, PLY_FLOAT, offsetof(LoadVertex,z), 0, 0, 0, 0},
00061         };
00062 
00063         PlyProperty face_props[] = { /* list of property information for a vertex */
00064           {"vertex_indices", PLY_INT, PLY_INT, offsetof(LoadFace,verts),
00065            1, PLY_UCHAR, PLY_UCHAR, offsetof(LoadFace,nverts)},
00066         };
00067 
00068         MEM_SmartPtr<BSP_TMesh> mesh = new BSP_TMesh;
00069 
00070         if (mesh == NULL) return NULL;
00071 
00072         int i,j;
00073         PlyFile *ply;
00074         int nelems;
00075         char **elist;
00076         int file_type;
00077         float version;
00078         int nprops;
00079         int num_elems;
00080         PlyProperty **plist;
00081 
00082         char *elem_name;
00083 
00084         LoadVertex load_vertex;
00085         LoadFace load_face;
00086 
00087         /* open a PLY file for reading */
00088         ply = ply_open_for_reading(
00089                 file_name,
00090                 &nelems,
00091                 &elist, 
00092                 &file_type, 
00093                 &version
00094         );
00095 
00096         if (ply == NULL) return NULL;
00097 
00098         /* go through each kind of element that we learned is in the file */
00099         /* and read them */
00100 
00101         for (i = 0; i < nelems; i++) {
00102 
00103                 /* get the description of the first element */
00104 
00105                 elem_name = elist[i];
00106                 plist = ply_get_element_description (ply, elem_name, &num_elems, &nprops);
00107 
00108                 /* print the name of the element, for debugging */
00109 
00110                 /* if we're on vertex elements, read them in */
00111 
00112                 if (equal_strings ("vertex", elem_name)) {
00113 
00114                         /* set up for getting vertex elements */
00115 
00116                         ply_get_property (ply, elem_name, &vert_props[0]);
00117                         ply_get_property (ply, elem_name, &vert_props[1]);
00118                         ply_get_property (ply, elem_name, &vert_props[2]);
00119 
00120                         // make some memory for the vertices            
00121                         mesh->VertexSet().reserve(num_elems);
00122 
00123                         /* grab all the vertex elements */
00124                         for (j = 0; j < num_elems; j++) {
00125 
00126                                 /* grab and element from the file */
00127                                 ply_get_element (ply, (void *)&load_vertex);
00128                                 // pass the vertex into the mesh builder.
00129                                         
00130                                 if (load_vertex.x < min.x()) {
00131                                         min.x() = load_vertex.x;
00132                                 } else
00133                                 if (load_vertex.x > max.x()) {
00134                                         max.x()= load_vertex.x;
00135                                 }
00136 
00137                                 if (load_vertex.y < min.y()) {
00138                                         min.y() = load_vertex.y;
00139                                 } else
00140                                 if (load_vertex.y > max.y()) {
00141                                         max.y()= load_vertex.y;
00142                                 }
00143 
00144                                 if (load_vertex.z < min.z()) {
00145                                         min.z() = load_vertex.z;
00146                                 } else
00147                                 if (load_vertex.z > max.z()) {
00148                                         max.z()= load_vertex.z;
00149                                 }
00150 
00151                                 BSP_TVertex my_vert;
00152                                 my_vert.m_pos = MT_Vector3(load_vertex.x,load_vertex.y,load_vertex.z);
00153                                 mesh->VertexSet().push_back(my_vert);
00154                         }
00155                 
00156 
00157                 }
00158 
00159                 /* if we're on face elements, read them in */
00160                 if (equal_strings ("face", elem_name)) {
00161 
00162                         /* set up for getting face elements */
00163 
00164                         ply_get_property (ply, elem_name, &face_props[0]);
00165 
00166                         /* grab all the face elements */
00167                         for (j = 0; j < num_elems; j++) {
00168 
00169                                 ply_get_element (ply, (void *)&load_face);
00170 
00171                                 int v;
00172                                 for (v = 2; v< load_face.nverts; v++) {
00173 
00174                                         BSP_TFace f;
00175 
00176                                         f.m_verts[0] = load_face.verts[0];
00177                                         f.m_verts[1] = load_face.verts[v-1];
00178                                         f.m_verts[2] = load_face.verts[v];
00179 
00180                                         mesh->BuildNormal(f);   
00181                                         mesh->FaceSet().push_back(f);
00182                                 }
00183                                 // free up the memory this pile of shit used to allocate the polygon's vertices
00184                                 free (load_face.verts);
00185                         }
00186 
00187                 }
00188         }
00189   /* close the PLY file */
00190   ply_close (ply);
00191 
00192  return mesh;
00193 }