![]() |
TAPs 0.7.7.3
|
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