TAPs 0.7.7.3
TAPsRead3dsMaxASC.cpp
Go to the documentation of this file.
00001 /******************************************************************************
00002 TAPsRead3dsMaxASC.cpp
00003 
00004 Create an OpenGLModel from a 3dsMax .ASC format file.
00005 
00006 SUKITTI PUNAK   (11/11/2004)
00007 UPDATE          (08/28/2005)
00008 ******************************************************************************/
00009 #include "TAPsRead3dsMaxASC.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 //-----------------------------------------------------------------------------
00015 // DEBUG ENABLE
00016 #ifdef TAPs_DEBUG_MODE
00017     #define DEBUG_MESSAGE_TAPs_READ_3DSMAX_ASC_HPP
00018 #endif
00019 
00020 BEGIN_NAMESPACE_TAPs
00021 //=============================================================================
00022 template <typename T>   FILE * Read3dsMaxASC<T>::fileIn = NULL;
00023 template <typename T>   int Read3dsMaxASC<T>::faceNo = 0;
00024 template <typename T>   int Read3dsMaxASC<T>::vertexNo = 0;
00025 //=============================================================================
00026 //-----------------------------------------------------------------------------
00027 // Read the model from the input file
00028 template <typename T>
00029 bool Read3dsMaxASC<T>::readFile( 
00030         const char *fileName, OpenGL::PolygonalModel<T> * const prModel )
00031 {
00032     // Open the input file
00033     fileIn = fopen( fileName, "r" );
00034     if ( !fileIn ) {
00035         #ifdef DEBUG_MESSAGE_TAPs_READ_3DSMAX_ASC_HPP
00036         std::perror( fileName );
00037         #endif
00038         return false;
00039     }
00040     //----------------------------------------------------------------
00041     // Initialization
00042     faceNo   = 0;
00043     vertexNo = 0;
00044     //----------------------------------------------------------------
00045     // Read in each line, check what its contents are, 
00046     // and pass it out to the relevant decoder function
00047     const char * const ALC = "Ambient light color";
00048     const char * const NO  = "Named object: ";
00049     const char * const VL  = "Vertex list";
00050     const char * const FL  = "Face list";
00051     const char * const TM  = "Tri-mesh";
00052     const char * const V   = "Vertex ";
00053     const char * const F   = "Face ";
00054     
00055     char line[256];
00056     while ( !feof( fileIn ) ) {
00057         fgets( line, 256, fileIn );
00058         if ( !strncmp( line, ALC, strlen( ALC ) ) )
00059             ProcessAmbientLight( line, prModel );
00060         else if ( !strncmp( line, NO, strlen( NO ) ) )
00061             ProcessNamedObject( line, prModel );
00062         else if ( !strncmp( line, VL, strlen( VL ) ) )
00063             ;
00064         else if ( !strncmp( line, FL, strlen( FL ) ) )
00065             ;
00066         else if ( !strncmp( line, TM, strlen( TM ) ) )
00067             ProcessTriMesh( line, prModel );
00068         else if ( !strncmp( line, V, strlen( V ) ) )
00069             ProcessVertex( line, prModel );
00070         else if ( !strncmp( line, F, strlen( F ) ) )
00071             ProcessFace( line, prModel );
00072     }
00073     fclose( fileIn );   // close the input file
00074     prModel->GetMaterial()->ApplyMaterial();
00075     return true;
00076 }
00077 //-----------------------------------------------------------------------------
00078 // Read the model from the input file
00079 template <typename T>
00080 bool Read3dsMaxASC<T>::readFile( 
00081         const char *fileName, OpenGL::XPolygonalModel<T> * const prModel )
00082 {
00083     // Open the input file
00084     fileIn = fopen( fileName, "r" );
00085     if ( !fileIn ) {
00086         #ifdef DEBUG_MESSAGE_TAPs_READ_3DSMAX_ASC_HPP
00087         std::perror( fileName );
00088         #endif
00089         return false;
00090     }
00091     //----------------------------------------------------------------
00092     // Initialization
00093     faceNo   = 0;
00094     vertexNo = 0;
00095     //----------------------------------------------------------------
00096     // Read in each line, check what its contents are, 
00097     // and pass it out to the relevant decoder function
00098     const char * const ALC = "Ambient light color";
00099     const char * const NO  = "Named object: ";
00100     const char * const VL  = "Vertex list";
00101     const char * const FL  = "Face list";
00102     const char * const TM  = "Tri-mesh";
00103     const char * const V   = "Vertex ";
00104     const char * const F   = "Face ";
00105     
00106     char line[256];
00107     while ( !feof( fileIn ) ) {
00108         fgets( line, 256, fileIn );
00109         if ( !strncmp( line, ALC, strlen( ALC ) ) )
00110             ProcessAmbientLight( line, prModel );
00111         else if ( !strncmp( line, NO, strlen( NO ) ) )
00112             ProcessNamedObject( line, prModel );
00113         else if ( !strncmp( line, VL, strlen( VL ) ) )
00114             ;
00115         else if ( !strncmp( line, FL, strlen( FL ) ) )
00116             ;
00117         else if ( !strncmp( line, TM, strlen( TM ) ) )
00118             ProcessTriMesh( line, prModel );
00119         else if ( !strncmp( line, V, strlen( V ) ) )
00120             ProcessVertex( line, prModel );
00121         else if ( !strncmp( line, F, strlen( F ) ) )
00122             ProcessFace( line, prModel );
00123         else    // skip, we don't know what it is!
00124             ;
00125     }
00126     fclose( fileIn );   // close the input file
00127     prModel->GetMaterial()->ApplyMaterial();
00128     return true;
00129 }
00130 //-----------------------------------------------------------------------------
00131 // Read the model from the input file
00132 template <typename T>
00133 bool Read3dsMaxASC<T>::readFile( 
00134         const char *fileName, OpenGL::HalfEdgeModel<T> * const prModel )
00135 {
00136     //----------------------------------------------------------------
00137     // Open the input file
00138     fileIn = fopen( fileName, "r" );
00139     if ( !fileIn ) {
00140         #ifdef DEBUG_MESSAGE_TAPs_READ_3DSMAX_ASC_HPP
00141         std::perror( fileName );
00142         #endif
00143         return false;
00144     }
00145     //----------------------------------------------------------------
00146     // Initialization
00147     faceNo   = 0;
00148     vertexNo = 0;
00149     //----------------------------------------------------------------
00150     // Read in each line, check what its contents are, 
00151     // and pass it out to the relevant decoder function
00152     const char * const ALC = "Ambient light color";
00153     const char * const NO  = "Named object: ";
00154     const char * const VL  = "Vertex list";
00155     const char * const FL  = "Face list";
00156     const char * const TM  = "Tri-mesh";
00157     const char * const V   = "Vertex ";
00158     const char * const F   = "Face ";
00159 
00160     char line[256];
00161     while ( !feof( fileIn ) ) {
00162         fgets( line, 256, fileIn );
00163         if ( !strncmp( line, ALC, strlen( ALC ) ) )
00164             ProcessAmbientLight( line, prModel );
00165         else if ( !strncmp( line, NO, strlen( NO ) ) )
00166             ProcessNamedObject( line, prModel );
00167         else if ( !strncmp( line, VL, strlen( VL ) ) )
00168             ;
00169         else if ( !strncmp( line, FL, strlen( FL ) ) )
00170             ;
00171         else if ( !strncmp( line, TM, strlen( TM ) ) )
00172             ProcessTriMesh( line, prModel );
00173         else if ( !strncmp( line, V, strlen( V ) ) )
00174             ProcessVertex( line, prModel );
00175         else if ( !strncmp( line, F, strlen( F ) ) )
00176             ProcessFace( line, prModel );
00177         else    // skip, we don't know what it is!
00178             ;
00179     }
00180     fclose( fileIn );   // close the input file
00181     //----------------------------------------------------------------
00182     HelpCreateHalfEdgeModel<T>::CreateHalfEdgeModel( prModel );
00183     //----------------------------------------------------------------
00184     prModel->GetMaterial()->ApplyMaterial();
00185     return true;
00186 }
00187 //-----------------------------------------------------------------------------
00188 //=============================================================================
00189 //-----------------------------------------------------------------------------
00190 // Convert the ambient light line
00191 template <typename T>
00192 void Read3dsMaxASC<T>::ProcessAmbientLight( char *line, OpenGL::PolygonalModel<T> * const prModel )
00193 {
00194     //Example
00195     //Ambient light color: Red=0.0000 Green=0.0000 Blue=0.0000
00196     float r, g, b;
00197     sscanf( line, "Ambient light color: Red=%f Green=%f Blue=%f", &r, &g, &b );
00198     prModel->material.SetAmbient( r, g, b, 1.0 );
00199 }
00200 //-----------------------------------------------------------------------------
00201 // Convert the ambient light line
00202 template <typename T>
00203 void Read3dsMaxASC<T>::ProcessAmbientLight( char *line, OpenGL::XPolygonalModel<T> * const prModel )
00204 {
00205     //Example
00206     //Ambient light color: Red=0.0000 Green=0.0000 Blue=0.0000
00207     float r, g, b;
00208     sscanf( line, "Ambient light color: Red=%f Green=%f Blue=%f", &r, &g, &b );
00209     prModel->material.SetAmbient( r, g, b, 1.0 );
00210 }
00211 //-----------------------------------------------------------------------------
00212 // Convert the ambient light line
00213 template <typename T>
00214 void Read3dsMaxASC<T>::ProcessAmbientLight( char *line, OpenGL::HalfEdgeModel<T> * const prModel )
00215 {
00216     //Example
00217     //Ambient light color: Red=0.0000 Green=0.0000 Blue=0.0000
00218     float r, g, b;
00219     sscanf( line, "Ambient light color: Red=%f Green=%f Blue=%f", &r, &g, &b );
00220     prModel->material.SetAmbient( r, g, b, 1.0 );
00221 }
00222 //-----------------------------------------------------------------------------
00223 //=============================================================================
00224 //-----------------------------------------------------------------------------
00225 // Convert the named object line
00226 template <typename T>
00227 void Read3dsMaxASC<T>::ProcessNamedObject( char *line, OpenGL::PolygonalModel<T> * const prModel )
00228 {
00229     //Example
00230     //Named object: "Box01"
00231     char acTmpName[256];
00232     char *pcTmpName;
00233     sscanf( line, "Named object: %s", acTmpName );
00234 
00235     // set up the object_c->m_pcObjectName
00236     pcTmpName = new char[ strlen( acTmpName ) + 1 ];    // allocate memory for the temp object name
00237     assert( pcTmpName != 0 );           // terminate if not allocated
00238     strcpy( pcTmpName, acTmpName );     // copy the string to the temp object name
00239     prModel->SetName( pcTmpName );  // set the object name to the temp object name
00240 }
00241 //-----------------------------------------------------------------------------
00242 // Convert the named object line
00243 template <typename T>
00244 void Read3dsMaxASC<T>::ProcessNamedObject( char *line, OpenGL::XPolygonalModel<T> * const prModel )
00245 {
00246     //Example
00247     //Named object: "Box01"
00248     char acTmpName[256];
00249     char *pcTmpName;
00250     sscanf( line, "Named object: %s", acTmpName );
00251 
00252     // set up the object_c->m_pcObjectName
00253     pcTmpName = new char[ strlen( acTmpName ) + 1 ];    // allocate memory for the temp object name
00254     assert( pcTmpName != 0 );           // terminate if not allocated
00255     strcpy( pcTmpName, acTmpName );     // copy the string to the temp object name
00256     prModel->SetName( pcTmpName );  // set the object name to the temp object name
00257 }
00258 //-----------------------------------------------------------------------------
00259 // Convert the named object line
00260 template <typename T>
00261 void Read3dsMaxASC<T>::ProcessNamedObject( char *line, OpenGL::HalfEdgeModel<T> * const prModel )
00262 {
00263     //Example
00264     //Named object: "Box01"
00265     char acTmpName[256];
00266     char *pcTmpName;
00267     sscanf( line, "Named object: %s", acTmpName );
00268 
00269     // set up the object_c->m_pcObjectName
00270     pcTmpName = new char[ strlen( acTmpName ) + 1 ];    // allocate memory for the temp object name
00271     assert( pcTmpName != 0 );           // terminate if not allocated
00272     strcpy( pcTmpName, acTmpName );     // copy the string to the temp object name
00273     prModel->SetName( pcTmpName );  // set the object name to the temp object name
00274     delete [] pcTmpName;
00275 }
00276 //-----------------------------------------------------------------------------
00277 //=============================================================================
00278 //-----------------------------------------------------------------------------
00279 // Convert the tri-mesh line
00280 template <typename T>
00281 void Read3dsMaxASC<T>::ProcessTriMesh( char *line, OpenGL::PolygonalModel<T> * const prModel )
00282 {
00283     // Example
00284     // Tri-mesh, Vertices: 8     Faces: 12
00285     int nv, nf;
00286     sscanf( line, "Tri-mesh, Vertices: %d     Faces: %d", &nv, &nf );
00287     prModel->SetNoVertices( nv );
00288     prModel->SetNoFaces( nf );
00289 
00290     // Allocate memory for the vertex and face data
00291     prModel->NewVertexListByNoVertices();
00292     prModel->NewFaceListByNoFaces();
00293 }
00294 //-----------------------------------------------------------------------------
00295 // Convert the tri-mesh line
00296 template <typename T>
00297 void Read3dsMaxASC<T>::ProcessTriMesh( char *line, OpenGL::XPolygonalModel<T> * const prModel )
00298 {
00299     // Example
00300     // Tri-mesh, Vertices: 8     Faces: 12
00301     int nv, nf;
00302     sscanf( line, "Tri-mesh, Vertices: %d     Faces: %d", &nv, &nf );
00303     prModel->SetNoVertices( nv );
00304     prModel->SetNoFaces( nf );
00305 
00306     // Allocate memory for the vertex and face data
00307     prModel->NewVertexListByNoVertices();
00308     prModel->NewFaceListByNoFaces();
00309 }
00310 //-----------------------------------------------------------------------------
00311 // Convert the tri-mesh line
00312 template <typename T>
00313 void Read3dsMaxASC<T>::ProcessTriMesh( char *line, OpenGL::HalfEdgeModel<T> * const prModel )
00314 {
00315     // Example
00316     // Tri-mesh, Vertices: 8     Faces: 12
00317     int nv, nf;
00318     sscanf( line, "Tri-mesh, Vertices: %d     Faces: %d", &nv, &nf );
00319     prModel->SetNoVertices( nv );
00320     prModel->SetNoFaces( nf );
00321 
00322     // Allocate memory for vertices
00323     HelpCreateHalfEdgeModel<T>::vertexList = new HEVertex<T>*[ nv ];
00324     HelpCreateHalfEdgeModel<T>::vertexRingList = new DS::HashTableBySTLVector<int>( nv );
00325     HelpCreateHalfEdgeModel<T>::halfEdgeRingList = new DS::HashTableBySTLVector< HEHalfEdge<T> * >( nv );
00326 }
00327 //-----------------------------------------------------------------------------
00328 //=============================================================================
00329 //-----------------------------------------------------------------------------
00330 // Convert a vertex line
00331 template <typename T>
00332 void Read3dsMaxASC<T>::ProcessVertex( char *line, OpenGL::PolygonalModel<T> * const prModel )
00333 {
00334     //Example
00335     //Vertex 0:  X:-2705.7974     Y:745.8893     Z:0.0000
00336     float fx, fy, fz;
00337     // fx, fy, and fz have to be float,
00338     // otherwise sscanf will not work.
00339     sscanf( line, "Vertex %*d:  X:%f     Y:%f     Z:%f", 
00340             &fx, 
00341             &fy,
00342             &fz
00343     );
00344 
00345     prModel->GetVertexList()[vertexNo  ][0] = fx;
00346     prModel->GetVertexList()[vertexNo  ][1] = fy;
00347     prModel->GetVertexList()[vertexNo++][2] = fz;
00348 }
00349 //-----------------------------------------------------------------------------
00350 // Convert a vertex line
00351 template <typename T>
00352 void Read3dsMaxASC<T>::ProcessVertex( char *line, OpenGL::XPolygonalModel<T> * const prModel )
00353 {
00354     //Example
00355     //Vertex 0:  X:-2705.7974     Y:745.8893     Z:0.0000
00356     float fx, fy, fz;
00357     // fx, fy, and fz have to be float,
00358     // otherwise sscanf will not work.
00359     sscanf( line, "Vertex %*d:  X:%f     Y:%f     Z:%f", 
00360             &fx, 
00361             &fy,
00362             &fz
00363     );
00364     prModel->GetVertexList()[vertexNo  ][0] = fx;
00365     prModel->GetVertexList()[vertexNo  ][1] = fy;
00366     prModel->GetVertexList()[vertexNo++][2] = fz;
00367 }
00368 //-----------------------------------------------------------------------------
00369 // Convert a vertex line
00370 template <typename T>
00371 void Read3dsMaxASC<T>::ProcessVertex( char *line, OpenGL::HalfEdgeModel<T> * const prModel )
00372 {
00373     //Example
00374     //Vertex 0:  X:-2705.7974     Y:745.8893     Z:0.0000
00375     float fx, fy, fz;
00376     // fx, fy, and fz have to be float,
00377     // otherwise sscanf will not work.
00378     sscanf( line, "Vertex %*d:  X:%f     Y:%f     Z:%f", 
00379             &fx, 
00380             &fy,
00381             &fz
00382     );
00383     // Put created vertex in vertexList for look up later
00384     HelpCreateHalfEdgeModel<T>::vertexList[vertexNo] = new HEVertex<T>( 
00385         fx, fy, fz, 
00386         0, 0, 0 
00387     #ifdef  TAPs_USE_DATA_POOL
00388         , prModel->GetArrayOfVertexPositions().GetAddressOfDataNumber( vertexNo )
00389         , prModel->GetArrayOfVertexNormals().GetAddressOfDataNumber( vertexNo )
00390     #endif//TAPs_USE_DATA_POOL
00391     );
00392     // Put created vertex in vertexList of the model
00393     prModel->GetVertexList()->Append( HelpCreateHalfEdgeModel<T>::vertexList[vertexNo] );
00394     ++vertexNo; // next vertex#
00395     //std::cout << "Vertex: " << vertexNo << "\n";
00396 }
00397 //-----------------------------------------------------------------------------
00398 //=============================================================================
00399 //-----------------------------------------------------------------------------
00400 // Convert a face line
00401 template <typename T>
00402 void Read3dsMaxASC<T>::ProcessFace( char *line, OpenGL::PolygonalModel<T> * const prModel )
00403 {
00404     //Example
00405     //Face 0:    A:0 B:2 C:3 AB:1 BC:1 CA:0
00406     prModel->GetFaceList()[faceNo].SetNoVertices( 3 );
00407     int e0, e1, e2;
00408     sscanf( line, "Face %*d:    A:%d B:%d C:%d", &e0, &e1, &e2 );
00409     prModel->GetFaceList()[faceNo  ].SetVertexNo( 0, e0 );
00410     prModel->GetFaceList()[faceNo  ].SetVertexNo( 1, e1 );
00411     prModel->GetFaceList()[faceNo++].SetVertexNo( 2, e2 );
00412 }
00413 //-----------------------------------------------------------------------------
00414 // Convert a face line
00415 template <typename T>
00416 void Read3dsMaxASC<T>::ProcessFace( char *line, OpenGL::XPolygonalModel<T> * const prModel )
00417 {
00418     //Example
00419     //Face 0:    A:0 B:2 C:3 AB:1 BC:1 CA:0
00420     prModel->GetFaceList()[faceNo].SetNoVertices( 3 );
00421     int e0, e1, e2;
00422     sscanf( line, "Face %*d:    A:%d B:%d C:%d", &e0, &e1, &e2 );
00423     prModel->GetFaceList()[faceNo  ].SetVertexNo( 0, e0 );
00424     prModel->GetFaceList()[faceNo  ].SetVertexNo( 1, e1 );
00425     prModel->GetFaceList()[faceNo++].SetVertexNo( 2, e2 );
00426 }
00427 //-----------------------------------------------------------------------------
00428 // Convert a face line
00429 template <typename T>
00430 void Read3dsMaxASC<T>::ProcessFace( char *line, OpenGL::HalfEdgeModel<T> * const prModel )
00431 {
00432     //Example
00433     //Face 0:    A:0 B:2 C:3 AB:1 BC:1 CA:0
00434     //----------------------------------------------------------------
00435     HEFace<T> *heFace = new HEFace<T>();
00436     prModel->GetFaceList()->Append( heFace );
00437     int v0, v1, v2;
00438     sscanf( line, "Face %*d:    A:%d B:%d C:%d", &v0, &v1, &v2 );
00439     //----------------------------------------------------------------
00440     // Create and Set all three half-edges
00441     HEHalfEdge<T> *heHalfEdge0 = HelpCreateHalfEdgeModel<T>::CreateHalfEdgeFrom( 
00442         HelpCreateHalfEdgeModel<T>::vertexList[v0], 
00443         HelpCreateHalfEdgeModel<T>::vertexList[v1], 
00444         heFace );
00445     HEHalfEdge<T> *heHalfEdge1 = HelpCreateHalfEdgeModel<T>::CreateHalfEdgeFrom( 
00446         HelpCreateHalfEdgeModel<T>::vertexList[v1], 
00447         HelpCreateHalfEdgeModel<T>::vertexList[v2], 
00448         heFace, heHalfEdge0 );                  // w/ prev ptr
00449     HEHalfEdge<T> *heHalfEdge2 = HelpCreateHalfEdgeModel<T>::CreateHalfEdgeFrom( 
00450         HelpCreateHalfEdgeModel<T>::vertexList[v2], 
00451         HelpCreateHalfEdgeModel<T>::vertexList[v0], 
00452         heFace, heHalfEdge1, heHalfEdge0 );     // w/ prev and next ptrs
00453     //----------------------------------------------------------------
00454     // Set incident half-edge of this face
00455     heFace->IncidentHalfEdge( heHalfEdge0 );
00456     //----------------------------------------------------------------
00457     // (CCW) Record v0 to v1, v1 to v2, and v2 to v0 in vertexRingList
00458     HelpCreateHalfEdgeModel<T>::vertexRingList->Insert( v1, v0 );   // put v1 in bucket v0
00459     HelpCreateHalfEdgeModel<T>::vertexRingList->Insert( v2, v1 );   // put v2 in bucket v1
00460     HelpCreateHalfEdgeModel<T>::vertexRingList->Insert( v0, v2 );   // put v0 in bucket v2
00461     //----------------------------------------------------------------
00462     // Record half-edges in halfEdgeRingList
00463     HelpCreateHalfEdgeModel<T>::halfEdgeRingList->Insert( heHalfEdge0, v0 );    // put in bucket v0
00464     HelpCreateHalfEdgeModel<T>::halfEdgeRingList->Insert( heHalfEdge1, v1 );    // put in bucket v1
00465     HelpCreateHalfEdgeModel<T>::halfEdgeRingList->Insert( heHalfEdge2, v2 );    // put in bucket v2
00466 }
00467 //-----------------------------------------------------------------------------
00468 //=============================================================================
00469 END_NAMESPACE_TAPs
00470 //-----------------------------------------------------------------------------
00471 //345678901234567890123456789012345678901234567890123456789012345678901234567890
00472 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines