Blender  V2.59
main.cpp
Go to the documentation of this file.
00001 
00029 #include "LOD_decimation.h"
00030 #include "ply/ply.h"
00031 #include "MEM_SmartPtr.h"
00032 #include "common/GlutDrawer.h"
00033 #include "GlutMeshDrawer.h"
00034 #include "MyGlutKeyHandler.h"
00035 #include "MyGlutMouseHandler.h"
00036 #include "MT_Vector3.h"
00037 #include "LOD_GhostTestApp.h"
00038 
00039 #include <memory>
00040 
00041 #define DEBUG_PRINT 0
00042 
00043 struct LoadVertex {
00044   float x,y,z;             /* the usual 3-space position of a vertex */
00045 };
00046 
00047 struct LoadFace {
00048   unsigned char intensity; /* this user attaches intensity to faces */
00049   unsigned char nverts;    /* number of vertex indices in list */
00050   int *verts;              /* vertex index list */
00051 };
00052 
00053  
00054          LOD_Decimation_InfoPtr 
00055 NewVertsFromFile(
00056         char * file_name,
00057         MT_Vector3 &min,
00058         MT_Vector3 &max
00059 ) {
00060 
00061         min = MT_Vector3(MT_INFINITY,MT_INFINITY,MT_INFINITY);
00062         max = MT_Vector3(-MT_INFINITY,-MT_INFINITY,-MT_INFINITY);
00063 
00064         
00065         PlyProperty vert_props[] = { /* list of property information for a vertex */
00066           {"x", PLY_FLOAT, PLY_FLOAT, offsetof(LoadVertex,x), 0, 0, 0, 0},
00067           {"y", PLY_FLOAT, PLY_FLOAT, offsetof(LoadVertex,y), 0, 0, 0, 0},
00068           {"z", PLY_FLOAT, PLY_FLOAT, offsetof(LoadVertex,z), 0, 0, 0, 0},
00069         };
00070 
00071         PlyProperty face_props[] = { /* list of property information for a vertex */
00072           {"intensity", PLY_UCHAR, PLY_UCHAR, offsetof(LoadFace,intensity), 0, 0, 0, 0},
00073           {"vertex_indices", PLY_INT, PLY_INT, offsetof(LoadFace,verts),
00074            1, PLY_UCHAR, PLY_UCHAR, offsetof(LoadFace,nverts)},
00075         };
00076 #if 0
00077         MEM_SmartPtr<std::vector<float> > verts = new std::vector<float>;
00078         MEM_SmartPtr<std::vector<float> > vertex_normals = new std::vector<float>;
00079 
00080         MEM_SmartPtr<std::vector<int> > faces = new std::vector<int>;
00081 #else
00082         std::vector<float>* verts = new std::vector<float>;
00083         std::vector<float>*  vertex_normals = new std::vector<float>;
00084 
00085         std::vector<int> * faces = new std::vector<int>;
00086 #endif
00087 
00088   int i,j;
00089   PlyFile *ply;
00090   int nelems;
00091   char **elist;
00092   int file_type;
00093   float version;
00094   int nprops;
00095   int num_elems;
00096   PlyProperty **plist;
00097 
00098   char *elem_name;
00099 
00100         LoadVertex load_vertex;
00101         LoadFace load_face;
00102 
00103   /* open a PLY file for reading */
00104   ply = ply_open_for_reading(file_name, &nelems, &elist, &file_type, &version);
00105 
00106  if (ply == NULL) return NULL;
00107   /* go through each kind of element that we learned is in the file */
00108   /* and read them */
00109 
00110   for (i = 0; i < nelems; i++) {
00111 
00112     /* get the description of the first element */
00113 
00114     elem_name = elist[i];
00115     plist = ply_get_element_description (ply, elem_name, &num_elems, &nprops);
00116 
00117     /* print the name of the element, for debugging */
00118 
00119     /* if we're on vertex elements, read them in */
00120     if (equal_strings ("vertex", elem_name)) {
00121 
00122       /* set up for getting vertex elements */
00123 
00124       ply_get_property (ply, elem_name, &vert_props[0]);
00125       ply_get_property (ply, elem_name, &vert_props[1]);
00126       ply_get_property (ply, elem_name, &vert_props[2]);
00127 
00128                 // make some memory for the vertices            
00129                 verts->reserve(num_elems);
00130 
00131       /* grab all the vertex elements */
00132       for (j = 0; j < num_elems; j++) {
00133 
00134         /* grab and element from the file */
00135         ply_get_element (ply, (void *)&load_vertex);
00136                 // pass the vertex into the mesh builder.
00137                         
00138         
00139                 if (load_vertex.x < min.x()) {
00140                         min.x() = load_vertex.x;
00141                 } else
00142                 if (load_vertex.x > max.x()) {
00143                         max.x()= load_vertex.x;
00144                 }
00145 
00146                 if (load_vertex.y < min.y()) {
00147                         min.y() = load_vertex.y;
00148                 } else
00149                 if (load_vertex.y > max.y()) {
00150                         max.y()= load_vertex.y;
00151                 }
00152 
00153                 if (load_vertex.z < min.z()) {
00154                         min.z() = load_vertex.z;
00155                 } else
00156                 if (load_vertex.z > max.z()) {
00157                         max.z()= load_vertex.z;
00158                 }
00159 
00160                 verts->push_back(load_vertex.x);
00161                 verts->push_back(load_vertex.y);
00162                 verts->push_back(load_vertex.z);
00163 
00164                 vertex_normals->push_back(1.0f);
00165                 vertex_normals->push_back(0.0f);
00166                 vertex_normals->push_back(0.0f);
00167 
00168 
00169       }
00170     }
00171 
00172     /* if we're on face elements, read them in */
00173     if (equal_strings ("face", elem_name)) {
00174 
00175       /* set up for getting face elements */
00176 
00177  //     ply_get_property (ply, elem_name, &face_props[0]);
00178       ply_get_property (ply, elem_name, &face_props[1]);
00179 
00180       /* grab all the face elements */
00181       for (j = 0; j < num_elems; j++) {
00182 
00183         ply_get_element (ply, (void *)&load_face);
00184 
00185                 faces->push_back(load_face.verts[0]);
00186                 faces->push_back(load_face.verts[1]);
00187                 faces->push_back(load_face.verts[2]);
00188 
00189                 // free up the memory this pile of shit used to allocate the polygon's vertices
00190 
00191                 free (load_face.verts);
00192       }
00193 
00194     }
00195   }
00196   /* close the PLY file */
00197   ply_close (ply);
00198 
00199   LOD_Decimation_InfoPtr output = new LOD_Decimation_Info;
00200 
00201   output->vertex_buffer = verts->begin();
00202   output->vertex_num = verts->size()/3;
00203 
00204   output->triangle_index_buffer = faces->begin();
00205   output->face_num = faces->size()/3;
00206   output->intern = NULL;
00207   output->vertex_normal_buffer = vertex_normals->begin();
00208 
00209   // memory leaks 'r' us        
00210 #if 0
00211   verts.Release();
00212   vertex_normals.Release();
00213   faces.Release();
00214 #endif
00215   return output;
00216 }
00217         
00218 
00219 void
00220 init(MT_Vector3 min,MT_Vector3 max)
00221 {
00222  
00223         GLfloat light_diffuse0[] = {1.0, 0.0, 0.0, 0.5};  /* Red diffuse light. */
00224         GLfloat light_position0[] = {1.0, 1.0, 1.0, 0.0};  /* Infinite light location. */
00225 
00226         GLfloat light_diffuse1[] = {1.0, 1.0, 1.0, 0.5};  /* Red diffuse light. */
00227         GLfloat light_position1[] = {1.0, 0, 0, 0.0};  /* Infinite light location. */
00228 
00229   /* Enable a single OpenGL light. */
00230   glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse0);
00231   glLightfv(GL_LIGHT0, GL_POSITION, light_position0);
00232 
00233   glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse1);
00234   glLightfv(GL_LIGHT1, GL_POSITION, light_position1);
00235 
00236   glEnable(GL_LIGHT0);
00237 //  glEnable(GL_LIGHT1);
00238   glEnable(GL_LIGHTING);
00239 
00240         // use two sided lighting model
00241         
00242         glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);
00243 
00244   /* Use depth buffering for hidden surface elimination. */
00245   glEnable(GL_DEPTH_TEST);
00246 
00247   /* Setup the view of the cube. */
00248   glMatrixMode(GL_PROJECTION);
00249 
00250         // center of the box + 3* depth of box
00251 
00252   MT_Vector3 center = (min + max) * 0.5;
00253   MT_Vector3 diag = max - min;
00254 
00255         float depth = diag.length();
00256         float distance = 2;
00257 
00258   gluPerspective( 
00259         /* field of view in degree */ 40.0,
00260     /* aspect ratio */ 1.0,
00261     /* Z near */ 1.0, 
00262         /* Z far */ distance * depth * 2
00263   );
00264   glMatrixMode(GL_MODELVIEW);   
00265 
00266 
00267   gluLookAt(
00268         center.x(), center.y(), center.z() + distance*depth,  /* eye is at (0,0,5) */
00269     center.x(), center.y(), center.z(),      /* center is at (0,0,0) */
00270     0.0, 1.0, 0.);      /* up is in positive Y direction */
00271 
00272   glPushMatrix();       
00273 
00274 
00275 }
00276 
00277 int
00278 main(int argc, char **argv)
00279 {
00280 
00281 // load in the mesh
00282 
00283         MT_Vector3 mesh_min,mesh_max;
00284 
00285         LOD_Decimation_InfoPtr LOD_info = NewVertsFromFile("beethoven.ply",mesh_min,mesh_max);
00286 
00287         // load the mesh data 
00288 
00289         int load_result = LOD_LoadMesh(LOD_info);
00290         int preprocess_result = LOD_PreprocessMesh(LOD_info);
00291 
00292         if (!(load_result && preprocess_result)) {
00293                 cout << " could not load mesh! \n";
00294                 return 0;
00295         }
00296 
00297         // make and install a mouse handler
00298 
00299         MEM_SmartPtr<MyGlutMouseHandler> mouse_handler(MyGlutMouseHandler::New());
00300         GlutMouseManager::Instance()->InstallHandler(mouse_handler);
00301 
00302         // instantiate the drawing class        
00303 
00304         MEM_SmartPtr<GlutMeshDrawer> drawer(GlutMeshDrawer::New());
00305         GlutDrawManager::Instance()->InstallDrawer(drawer);
00306         drawer->SetLODInfo(LOD_info);   
00307         drawer->SetMouseHandler(mouse_handler);
00308 
00309         // make and install a keyhandler
00310 
00311         MEM_SmartPtr<MyGlutKeyHandler> key_handler(MyGlutKeyHandler::New(LOD_info));
00312         GlutKeyboardManager::Instance()->InstallHandler(key_handler);
00313 
00314 
00315         LOD_GhostTestApp LOD_app;
00316 
00317         LOD_app.InitApp();
00318         init(mesh_min,mesh_max);
00319 
00320         LOD_app.Run();
00321 
00322 
00323         return 0;             /* ANSI C requires main to return int. */
00324 }