|
Blender
V2.59
|
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 }