![]() |
TAPs 0.7.7.3
|
00001 /****************************************************************************** 00002 TAPsReadOff.cpp 00003 00004 Create an OpenGL Polygonal Model Object from a 3ds Max .ASE file 00005 00006 SUKITTI PUNAK (05/24/2006) 00007 UPDATE (06/01/2006) 00008 ******************************************************************************/ 00009 #include "TAPsReadOff.hpp" 00010 // Using Inclusion Model (i.e. definitions are included in declarations) 00011 // (this name.cpp is included in name.hpp) 00012 // Each friend is defined directly inside its declaration. 00013 00014 BEGIN_NAMESPACE_TAPs 00015 //============================================================================= 00016 //template <typename T> 00017 //FILE * ReadOff<T>::fileIn = NULL; 00018 template <typename T> int ReadOff<T>::halfEdgeCounter = 0; 00019 template <typename T> int ReadOff<T>::vertexNo = 0; 00020 /* 00021 template <typename T> 00022 HEVertex<T> ** ReadOff<T>::vertexList = NULL; 00023 template <typename T> 00024 HashTableBySTLVector<int> * ReadOff<T>::vertexRingList = NULL; 00025 template <typename T> 00026 HashTableBySTLVector< HEHalfEdge<T>* > * ReadOff<T>::halfEdgeRingList = NULL; 00027 template <typename T> 00028 HEHalfEdge<T> * ReadOff<T>::boundaryHalfEdgePtr = NULL; 00029 //*/ 00030 //============================================================================= 00031 //----------------------------------------------------------------------------- 00032 // Read an input file 00033 template <typename T> 00034 bool ReadOff<T>::readFile ( 00035 const char *fileName, OpenGL::PolygonalModel<T> * const prModel ) 00036 { 00037 //---------------------------------------------------------------- 00038 // Open the input file 00039 FILE * fileIn = fopen( fileName, "r" ); 00040 if ( !fileIn ) { 00041 std::perror( fileName ); 00042 return false; 00043 } 00044 //---------------------------------------------------------------- 00045 #ifdef TAPs_DEBUG_MODE 00046 std::cout << "START READING " << fileName << "\n"; 00047 #endif 00048 //---------------------------------------------------------------- 00049 if ( ProcessHEADER( fileIn, prModel ) == false ) return false; 00050 if ( prModel->GetNoVertices() > 0 ) ProcessVERTEX_LIST( fileIn, prModel ); 00051 if ( prModel->GetNoFaces() > 0 ) ProcessFACE_LIST( fileIn, prModel ); 00052 //---------------------------------------------------------------- 00053 fclose(fileIn); 00054 #ifdef TAPs_DEBUG_MODE 00055 std::cout << "END READING " << fileName << "\n"; 00056 #endif 00057 prModel->GetMaterial()->ApplyMaterial(); 00058 return true; 00059 } 00060 //----------------------------------------------------------------------------- 00061 // Read an input file 00062 template <typename T> 00063 bool ReadOff<T>::readFile ( 00064 const char *fileName, OpenGL::XPolygonalModel<T> * const prModel ) 00065 { 00066 //---------------------------------------------------------------- 00067 // Open the input file 00068 FILE * fileIn = fopen( fileName, "r" ); 00069 if ( !fileIn ) { 00070 std::perror( fileName ); 00071 return false; 00072 } 00073 //---------------------------------------------------------------- 00074 #ifdef TAPs_DEBUG_MODE 00075 std::cout << "START READING " << fileName << "\n"; 00076 #endif 00077 //---------------------------------------------------------------- 00078 if ( ProcessHEADER( fileIn, prModel ) == false ) return false; 00079 if ( prModel->GetNoVertices() > 0 ) ProcessVERTEX_LIST( fileIn, prModel ); 00080 if ( prModel->GetNoFaces() > 0 ) ProcessFACE_LIST( fileIn, prModel ); 00081 //---------------------------------------------------------------- 00082 fclose(fileIn); 00083 #ifdef TAPs_DEBUG_MODE 00084 std::cout << "END READING " << fileName << "\n"; 00085 #endif 00086 prModel->GetMaterial()->ApplyMaterial(); 00087 return true; 00088 } 00089 //----------------------------------------------------------------------------- 00090 // Read an input file 00091 template <typename T> 00092 bool ReadOff<T>::readFile ( 00093 const char *fileName, OpenGL::HalfEdgeModel<T> * const prModel ) 00094 { 00095 //---------------------------------------------------------------- 00096 // Initialization 00097 halfEdgeCounter = 0; 00098 vertexNo = 0; 00099 //---------------------------------------------------------------- 00100 // Open the input file 00101 FILE * fileIn = fopen( fileName, "r" ); 00102 if ( !fileIn ) { 00103 std::perror( fileName ); 00104 return false; 00105 } 00106 //---------------------------------------------------------------- 00107 #ifdef TAPs_DEBUG_MODE 00108 std::cout << "START READING " << fileName << "\n"; 00109 #endif 00110 //---------------------------------------------------------------- 00111 if ( ProcessHEADER( fileIn, prModel ) == false ) return false; 00112 if ( prModel->GetNoVertices() > 0 ) 00113 ProcessVERTEX_LIST( fileIn, prModel ); 00114 if ( prModel->GetNoFaces() > 0 ) 00115 ProcessFACE_LIST( fileIn, prModel ); 00116 //---------------------------------------------------------------- 00117 fclose(fileIn); 00118 //---------------------------------------------------------------- 00119 HelpCreateHalfEdgeModel<T>::CreateHalfEdgeModel( prModel ); 00120 //---------------------------------------------------------------- 00121 #ifdef TAPs_DEBUG_MODE 00122 std::cout << "END READING " << fileName << "\n"; 00123 std::cout << "Number of Half-Edges: " << halfEdgeCounter << "\n"; 00124 #endif 00125 prModel->GetMaterial()->ApplyMaterial(); 00126 return true; 00127 } 00128 //----------------------------------------------------------------------------- 00129 //============================================================================= 00130 //----------------------------------------------------------------------------- 00131 // Process HEADER 00132 template <typename T> 00133 bool ReadOff<T>::ProcessHEADER ( 00134 FILE * inputFile, OpenGL::MeshModel<T> * const prModel ) 00135 { 00136 //--------------------------------------------------------------- 00137 //m_iNumOfVertices = 0; 00138 //m_iNumOfFaces = 0; 00139 //--------------------------------------------------------------- 00140 char line[256]; 00141 char node[128]; 00142 // while ( !feof(fileIn) ) { 00143 do { 00144 fgets( line, 256, inputFile ); // read the first line 00145 } while ( strlen( line ) < 3 || line[0] == '#' ); 00146 sscanf( line, "%s", node ); 00147 //------------------------------------------- 00148 // Example: 00149 // OFF 00150 // 9995 20000 0 // #Vertex #Faces #Edges 00151 //------------------------------------------- 00152 // Check for OFF format 00153 if ( strncmp( node, "OFF", strlen("OFF") ) ) { 00154 return false; 00155 } 00156 //------------------------------------------- 00157 char *delimiters = "\t "; 00158 char *token = NULL; 00159 char *end; 00160 //------------------------------------------- 00161 fgets( line, 256, inputFile ); // read the next line 00162 //------------------------------------------- 00163 // Number of Vertices 00164 token = strtok( line, delimiters ); 00165 if ( token != NULL ) { 00166 prModel->SetNoVertices( static_cast<int>( strtol( token, &end, 10 ) ) ); 00167 } 00168 //------------------------------------------- 00169 // Number of Faces 00170 token = strtok( '\0', delimiters ); 00171 if ( token != NULL ) { 00172 prModel->SetNoFaces( static_cast<int>( strtol( token, &end, 10 ) ) ); 00173 } 00174 //------------------------------------------- 00175 // Number of Edges 00176 token = strtok( '\0', delimiters ); 00177 if ( token != NULL ) { 00178 //prModel->SetNoEdges( static_cast<int>( strtol( token, &end, 10 ) ) ); 00179 } 00180 //------------------------------------------- 00181 #ifdef TAPs_DEBUG_MODE 00182 std::cout << "Number of Vertices: " << prModel->GetNoVertices() << "\n"; 00183 std::cout << "Number of Faces: " << prModel->GetNoFaces() << "\n"; 00184 //std::cout << "Number of Edges: " << prModel->GetNoEdges() << "\n"; 00185 #endif 00186 return true; 00187 } 00188 //----------------------------------------------------------------------------- 00189 //============================================================================= 00190 //----------------------------------------------------------------------------- 00191 // Process VERTEX LIST 00192 template <typename T> 00193 void ReadOff<T>::ProcessVERTEX_LIST ( 00194 FILE * inputFile, OpenGL::PolygonalModel<T> * const prModel ) 00195 { 00196 #ifdef TAPs_DEBUG_MODE 00197 std::cout << "Processing VERTEX LIST\n"; 00198 #endif 00199 //------------------------------------------------------------------- 00200 // Example: x y z values 00201 // 0 0 0 00202 // ... 00203 // 0 0 1 00204 //------------------------------------------------------------------- 00205 char vertexStr[128]; 00206 int vertexNumber = 0; 00207 float x, y, z; // since sscanf does not work for T (template) 00208 //------------------------------------------------------------------- 00209 prModel->NewVertexListByNoVertices(); 00210 do { 00211 do { 00212 fgets( vertexStr, 128, inputFile ); 00213 } while ( strlen( vertexStr ) < 3 || vertexStr[0] == '#' ); 00214 sscanf( vertexStr, "%g %g %g", &x, &y, &z ); 00215 prModel->GetVertexList()[vertexNumber][0] = x; 00216 prModel->GetVertexList()[vertexNumber][1] = y; 00217 prModel->GetVertexList()[vertexNumber][2] = z; 00218 ++vertexNumber; 00219 } while ( vertexNumber < prModel->GetNoVertices() ); 00220 } 00221 //----------------------------------------------------------------------------- 00222 // Process VERTEX LIST 00223 template <typename T> 00224 void ReadOff<T>::ProcessVERTEX_LIST ( 00225 FILE * inputFile, OpenGL::XPolygonalModel<T> * const prModel ) 00226 { 00227 #ifdef TAPs_DEBUG_MODE 00228 std::cout << "Processing VERTEX LIST\n"; 00229 #endif 00230 //------------------------------------------------------------------- 00231 // Example: x y z values 00232 // 0 0 0 00233 // ... 00234 // 0 0 1 00235 //------------------------------------------------------------------- 00236 char vertexStr[128]; 00237 int vertexNumber = 0; 00238 float x, y, z; // since sscanf does not work for T (template) 00239 //------------------------------------------------------------------- 00240 prModel->NewVertexListByNoVertices(); 00241 do { 00242 do { 00243 fgets( vertexStr, 128, inputFile ); 00244 } while ( strlen( vertexStr ) < 3 || vertexStr[0] == '#' ); 00245 sscanf( vertexStr, "%g %g %g", &x, &y, &z ); 00246 prModel->GetVertexList()[vertexNumber][0] = x; 00247 prModel->GetVertexList()[vertexNumber][1] = y; 00248 prModel->GetVertexList()[vertexNumber][2] = z; 00249 ++vertexNumber; 00250 } while ( vertexNumber < prModel->GetNoVertices() ); 00251 } 00252 //----------------------------------------------------------------------------- 00253 // Process VERTEX LIST 00254 template <typename T> 00255 void ReadOff<T>::ProcessVERTEX_LIST ( 00256 FILE * inputFile, OpenGL::HalfEdgeModel<T> * const prModel ) 00257 { 00258 #ifdef TAPs_DEBUG_MODE 00259 std::cout << "Processing VERTEX LIST\n"; 00260 #endif 00261 //------------------------------------------------------------------- 00262 // Example: 00263 // *MESH_VERTEX_LIST { 00264 // *MESH_VERTEX 0 -10.000000 -5.000000 0.000000 00265 // *MESH_VERTEX 1 10.000000 -5.000000 0.000000 00266 // *MESH_VERTEX 2 -10.000000 5.000000 0.000000 00267 // ... 00268 // } 00269 //------------------------------------------------------------------- 00270 char node[128]; 00271 int n; 00272 float x, y, z; 00273 fgets( line, 128, inputFile ); 00274 sscanf( line, "%s %d %g %g %g", node, &n, &x, &y, &z ); 00275 while ( node[0] != '}' ) { 00276 //------------------------------------------------------ 00277 // Put created vertex in vertexList for look up later 00278 HelpCreateHalfEdgeModel<T>::vertexList[vertexNo] = new HEVertex<T>( x, y, z ); 00279 // Put created vertex in vertexList of the model 00280 prModel->GetVertexList()->Append( HelpCreateHalfEdgeModel<T>::vertexList[vertexNo] ); 00281 ++vertexNo; // next vertex# 00282 //std::cout << "Vertex: " << vertexNo << "\n"; 00283 //------------------------------------------------------ 00284 fgets( line, 128, fileIn ); 00285 sscanf( line, "%s %d %g %g %g", node, &n, &x, &y, &z ); 00286 } 00287 } 00288 //----------------------------------------------------------------------------- 00289 //============================================================================= 00290 //----------------------------------------------------------------------------- 00291 // Process FACE LIST 00292 template <typename T> 00293 void ReadOff<T>::ProcessFACE_LIST ( 00294 FILE * inputFile, OpenGL::PolygonalModel<T> * const prModel ) 00295 { 00296 #ifdef TAPs_DEBUG_MODE 00297 std::cout << "Processing FACE LIST\n"; 00298 #endif 00299 //--------------------------------------------------------------- 00300 // Example: number of vertices for this face followed by vertex numbers 00301 // 4 0 1 2 3 00302 // ... 00303 // 3 10 11 12 00304 //--------------------------------------------------------------- 00305 char line[128]; 00306 char *delimiters = "\t "; 00307 char *token = NULL; 00308 char *end; 00309 int numberOfVertices; 00310 int vertexNo; 00311 int faceNo = 0; 00312 //--------------------------------------------------------------- 00313 prModel->NewFaceListByNoFaces(); 00314 do { 00315 do { 00316 fgets( line, 128, inputFile ); 00317 } while ( strlen( line ) < 3 || line[0] == '#' ); 00318 token = strtok( line, delimiters ); // number of vertices 00319 numberOfVertices = static_cast<int>( strtol( token, &end, 10 ) ); 00320 prModel->GetFaceList()[faceNo].SetNoVertices( numberOfVertices ); 00321 for ( int i = 0; i < numberOfVertices; ++i ) { 00322 token = strtok( '\0', delimiters ); // vertex number 00323 vertexNo = static_cast<int>( strtol( token, &end, 10 ) ); 00324 prModel->GetFaceList()[faceNo].SetVertexNo( i, vertexNo ); 00325 } 00326 ++faceNo; 00327 } while ( faceNo < prModel->GetNoFaces() ); 00328 //--------------------------------------------------------------- 00329 } 00330 //----------------------------------------------------------------------------- 00331 // Process FACE LIST 00332 template <typename T> 00333 void ReadOff<T>::ProcessFACE_LIST ( 00334 FILE * inputFile, OpenGL::XPolygonalModel<T> * const prModel ) 00335 { 00336 #ifdef TAPs_DEBUG_MODE 00337 std::cout << "Processing FACE LIST\n"; 00338 #endif 00339 //--------------------------------------------------------------- 00340 // Example: number of vertices for this face followed by vertex numbers 00341 // 4 0 1 2 3 00342 // ... 00343 // 3 10 11 12 00344 //--------------------------------------------------------------- 00345 char line[128]; 00346 char *delimiters = "\t "; 00347 char *token = NULL; 00348 char *end; 00349 int numberOfVertices; 00350 int vertexNo; 00351 int faceNo = 0; 00352 //--------------------------------------------------------------- 00353 prModel->NewFaceListByNoFaces(); 00354 do { 00355 do { 00356 fgets( line, 128, inputFile ); 00357 } while ( strlen( line ) < 3 || line[0] == '#' ); 00358 token = strtok( line, delimiters ); // number of vertices 00359 numberOfVertices = static_cast<int>( strtol( token, &end, 10 ) ); 00360 prModel->GetFaceList()[faceNo].SetNoVertices( numberOfVertices ); 00361 // DEBUG 00362 prModel->GetFaceList()[faceNo].ID = faceNo; 00363 for ( int i = 0; i < numberOfVertices; ++i ) { 00364 token = strtok( '\0', delimiters ); // vertex number 00365 vertexNo = static_cast<int>( strtol( token, &end, 10 ) ); 00366 prModel->GetFaceList()[faceNo].SetVertexNo( i, vertexNo ); 00367 } 00368 ++faceNo; 00369 } while ( faceNo < prModel->GetNoFaces() ); 00370 //--------------------------------------------------------------- 00371 } 00372 //----------------------------------------------------------------------------- 00373 // Process FACE LIST 00374 template <typename T> 00375 void ReadOff<T>::ProcessFACE_LIST ( 00376 FILE * inputFile, OpenGL::HalfEdgeModel<T> * const prModel ) 00377 { 00378 std::cout << "Processing Node MESH_FACE_LIST\n"; 00379 //------------------------------------------------------------------- 00380 // Example: 00381 // *MESH_FACE_LIST { 00382 // *MESH_FACE 0: A: 0 B: 2 C: 3 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 2 *MESH_MTLID 1 00383 // *MESH_FACE 1: A: 3 B: 1 C: 0 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 2 *MESH_MTLID 1 00384 // *MESH_FACE 2: A: 4 B: 5 C: 7 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 3 *MESH_MTLID 0 00385 // ... 00386 // } 00387 //------------------------------------------------------------------- 00388 HEFace<T> *heFace; 00389 char node[128]; 00390 char N[16], A[4], B[4], C[4]; 00391 int v0, v1, v2; 00392 fgets( line, 128, fileIn ); 00393 sscanf( line, "%s %s %s %d %s %d %s %d", node, N, A, &v0, B, &v1, C, &v2 ); 00394 while ( node[0] != '}' ) { 00395 heFace = new HEFace<T>(); 00396 prModel->GetFaceList()->Append( heFace ); 00397 //---------------------------------------------------------------- 00398 // Create and Set all three half-edges 00399 HEHalfEdge<T> *heHalfEdge0 = HelpCreateHalfEdgeModel<T>::CreateHalfEdgeFrom( 00400 HelpCreateHalfEdgeModel<T>::vertexList[v0], 00401 HelpCreateHalfEdgeModel<T>::vertexList[v1], 00402 heFace ); 00403 HEHalfEdge<T> *heHalfEdge1 = HelpCreateHalfEdgeModel<T>::CreateHalfEdgeFrom( 00404 HelpCreateHalfEdgeModel<T>::vertexList[v1], 00405 HelpCreateHalfEdgeModel<T>::vertexList[v2], 00406 heFace, heHalfEdge0 ); 00407 HEHalfEdge<T> *heHalfEdge2 = HelpCreateHalfEdgeModel<T>::CreateHalfEdgeFrom( 00408 HelpCreateHalfEdgeModel<T>::vertexList[v2], 00409 HelpCreateHalfEdgeModel<T>::vertexList[v0], 00410 heFace, heHalfEdge1, heHalfEdge0 ); 00411 halfEdgeCounter += 3; 00412 //---------------------------------------------------------------- 00413 // Set incident half-edge of this face 00414 heFace->IncidentHalfEdge( heHalfEdge0 ); 00415 //---------------------------------------------------------------- 00416 // (CCW) Record v0 to v1, v1 to v2, and v2 to v0 in vertexRingList 00417 HelpCreateHalfEdgeModel<T>::vertexRingList->Insert( v1, v0 ); // put v1 in bucket v0 00418 HelpCreateHalfEdgeModel<T>::vertexRingList->Insert( v2, v1 ); // put v2 in bucket v1 00419 HelpCreateHalfEdgeModel<T>::vertexRingList->Insert( v0, v2 ); // put v0 in bucket v2 00420 //---------------------------------------------------------------- 00421 // Record half-edges in halfEdgeRingList 00422 HelpCreateHalfEdgeModel<T>::halfEdgeRingList->Insert( heHalfEdge0, v0 ); // put in bucket v0 00423 HelpCreateHalfEdgeModel<T>::halfEdgeRingList->Insert( heHalfEdge1, v1 ); // put in bucket v1 00424 HelpCreateHalfEdgeModel<T>::halfEdgeRingList->Insert( heHalfEdge2, v2 ); // put in bucket v2 00425 //---------------------------------------------------------------- 00426 fgets( line, 128, fileIn ); 00427 sscanf( line, "%s %s %s %d %s %d %s %d", node, N, A, &v0, B, &v1, C, &v2 ); 00428 } 00429 } 00430 //----------------------------------------------------------------------------- 00431 //============================================================================= 00432 END_NAMESPACE_TAPs 00433 //----------------------------------------------------------------------------- 00434 //34567890123456789012345678901234567890123456789012345678901234567890123456789 00435 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----