Blender V2.61 - r43446

main.cpp

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