TAPs 0.7.7.3
TAPsReadOff.cpp
Go to the documentation of this file.
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----+----
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines