00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00026
00027
00028 #include "glc_objtoworld.h"
00029 #include "../sceneGraph/glc_world.h"
00030 #include "glc_objmtlloader.h"
00031 #include "../glc_fileformatexception.h"
00032 #include "../maths/glc_geomtools.h"
00033 #include "../sceneGraph/glc_structreference.h"
00034 #include "../sceneGraph/glc_structinstance.h"
00035 #include "../sceneGraph/glc_structoccurence.h"
00036 #include <QTextStream>
00037 #include <QFileInfo>
00038 #include <QGLContext>
00039
00041
00043 GLC_ObjToWorld::GLC_ObjToWorld()
00044 : m_pWorld(NULL)
00045 , m_FileName()
00046 , m_pMtlLoader(NULL)
00047 , m_CurrentLineNumber(0)
00048 , m_pCurrentObjMesh(NULL)
00049 , m_FaceType(notSet)
00050 , m_CurrentMeshMaterials()
00051 , m_CurrentMaterialName("GLC_Default")
00052 , m_ListOfAttachedFileName()
00053 , m_Positions()
00054 , m_Normals()
00055 , m_Texels()
00056 {
00057 }
00058
00059 GLC_ObjToWorld::~GLC_ObjToWorld()
00060 {
00061 clear();
00062 }
00063
00065
00067
00068
00069 GLC_World* GLC_ObjToWorld::CreateWorldFromObj(QFile &file)
00070 {
00071 m_ListOfAttachedFileName.clear();
00072 m_FileName= file.fileName();
00074
00076 if (!file.open(QIODevice::ReadOnly))
00077 {
00078 QString message(QString("GLC_ObjToWorld::CreateWorldFromObj File ") + m_FileName + QString(" doesn't exist"));
00079
00080 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotFound);
00081 throw(fileFormatException);
00082 }
00083
00085
00087 m_pWorld= new GLC_World;
00088
00089
00090 int currentQuantumValue= 0;
00091 int previousQuantumValue= 0;
00092 int numberOfLine= 0;
00093
00094
00095 QTextStream objStream(&file);
00096
00097
00098 QString lineBuff;
00099
00100 QString mtlLibLine;
00101
00103
00105 while (!objStream.atEnd() && !lineBuff.contains("mtllib"))
00106 {
00107 ++numberOfLine;
00108 lineBuff= objStream.readLine();
00109 if (lineBuff.contains("mtllib")) mtlLibLine= lineBuff;
00110 }
00111
00113
00115 while (!objStream.atEnd())
00116 {
00117 ++numberOfLine;
00118 objStream.readLine();
00119 }
00120
00122
00124 objStream.resetStatus();
00125 objStream.seek(0);
00126
00128
00130 QString mtlLibFileName(getMtlLibFileName(mtlLibLine));
00131 if (!mtlLibFileName.isEmpty())
00132 {
00133 m_pMtlLoader= new GLC_ObjMtlLoader(mtlLibFileName);
00134 if (!m_pMtlLoader->loadMaterials())
00135 {
00136 delete m_pMtlLoader;
00137 m_pMtlLoader= NULL;
00138 if (!mtlLibLine.isEmpty())
00139 {
00140 QStringList stringList(m_FileName);
00141 stringList.append("Open Material File : " + mtlLibFileName + " failed");
00142 GLC_ErrorLog::addError(stringList);
00143 }
00144 }
00145 else
00146 {
00147
00148 m_ListOfAttachedFileName << mtlLibFileName;
00149 m_ListOfAttachedFileName << m_pMtlLoader->listOfAttachedFileName();
00150 }
00151 }
00152 else
00153 {
00154
00155 }
00156
00158
00160 emit currentQuantum(currentQuantumValue);
00161 m_CurrentLineNumber= 0;
00162 while (!objStream.atEnd())
00163 {
00164 ++m_CurrentLineNumber;
00165 lineBuff= objStream.readLine();
00166
00167 mergeLines(&lineBuff, &objStream);
00168
00169 scanLigne(lineBuff);
00170 currentQuantumValue = static_cast<int>((static_cast<double>(m_CurrentLineNumber) / numberOfLine) * 100);
00171 if (currentQuantumValue > previousQuantumValue)
00172 {
00173 emit currentQuantum(currentQuantumValue);
00174 }
00175 previousQuantumValue= currentQuantumValue;
00176
00177 }
00178 file.close();
00179
00180 addCurrentObjMeshToWorld();
00181
00183 if (m_pWorld->rootOccurence()->childCount() == 0)
00184 {
00185 QString message= "GLC_ObjToWorld::CreateWorldFromObj " + m_FileName + " No mesh found!";
00186 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::NoMeshFound);
00187 clear();
00188 throw(fileFormatException);
00189 }
00190 return m_pWorld;
00191
00192 }
00193
00195
00197
00198
00199 QString GLC_ObjToWorld::getMtlLibFileName(QString line)
00200 {
00201
00202 QString mtlFileName(m_FileName);
00203 mtlFileName.replace(m_FileName.size() - 3, 3, "mtl");
00204 QFile mtlFile(mtlFileName);
00205 if (!mtlFile.exists())
00206 {
00207 QTextStream stream(&line);
00208 QString header;
00209 if ((stream >> header >> mtlFileName).status() == QTextStream::Ok)
00210 {
00211
00212 QString valueString2;
00213 while ((stream >> valueString2).status() == QTextStream::Ok)
00214 {
00215 mtlFileName.append(" ");
00216 mtlFileName.append(valueString2);
00217 }
00218 QFileInfo fileInfo(m_FileName);
00219 mtlFileName= fileInfo.absolutePath() + QDir::separator() + mtlFileName;
00220 }
00221 else
00222 {
00223
00224 mtlFileName.clear();
00225 }
00226 }
00227 return mtlFileName;
00228 }
00229
00230
00231 void GLC_ObjToWorld::scanLigne(QString &line)
00232 {
00233 line= line.trimmed();
00234
00235 if (line.startsWith("v ")|| line.startsWith(QString("v") + QString(QChar(9))))
00236 {
00237 line.remove(0,2);
00238 m_Positions.append(extract3dVect(line));
00239 m_FaceType = notSet;
00240 }
00241
00242
00243 else if (line.startsWith("vt ")|| line.startsWith(QString("vt") + QString(QChar(9))))
00244 {
00245 line.remove(0,3);
00246 m_Texels.append(extract2dVect(line));
00247 m_FaceType = notSet;
00248 }
00249
00250
00251 else if (line.startsWith("vn ") || line.startsWith(QString("vn") + QString(QChar(9))))
00252 {
00253 line.remove(0,3);
00254 m_Normals.append(extract3dVect(line));
00255 m_FaceType = notSet;
00256 }
00257
00258
00259 else if (line.startsWith("f ") || line.startsWith(QString("f") + QString(QChar(9))))
00260 {
00261
00262 if (NULL == m_pCurrentObjMesh)
00263 {
00264 changeGroup("GLC_Default");
00265
00266 }
00267 line.remove(0,2);
00268 extractFaceIndex(line);
00269 }
00270
00271
00272 else if (line.startsWith("usemtl ") || line.startsWith(QString("usemtl") + QString(QChar(9))))
00273 {
00274 line.remove(0,7);
00275 setCurrentMaterial(line);
00276 m_FaceType = notSet;
00277 }
00278
00279
00280 else if (line.startsWith("g ") || line.startsWith("o ") || line.startsWith(QString("g") + QString(QChar(9)))
00281 || line.startsWith(QString("o") + QString(QChar(9))))
00282 {
00283 m_FaceType = notSet;
00284 line.remove(0,2);
00285 changeGroup(line);
00286 }
00287
00288 }
00289
00290 void GLC_ObjToWorld::changeGroup(QString line)
00291 {
00292
00294
00296 QTextStream stream(&line);
00297 QString groupName;
00298 if ((stream >> groupName).status() == QTextStream::Ok)
00299 {
00300
00301 QString valueString2;
00302 while ((stream >> valueString2).status() == QTextStream::Ok)
00303 {
00304 groupName.append(" ");
00305 groupName.append(valueString2);
00306 }
00308
00310 if("default" != groupName)
00311 {
00312 addCurrentObjMeshToWorld();
00313 m_pCurrentObjMesh= new CurrentObjMesh(m_CurrentMaterialName);
00314 m_pCurrentObjMesh->m_pMesh->setName(groupName);
00315
00316 }
00317 }
00318 else
00319 {
00320 QString message= "GLC_ObjToWorld::changeGroup " + m_FileName + " something is wrong!!";
00321 message.append("\nAt line : ");
00322 message.append(QString::number(m_CurrentLineNumber));
00323 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotSupported);
00324 clear();
00325 throw(fileFormatException);
00326 }
00327
00328 }
00329
00330
00331 QList<float> GLC_ObjToWorld::extract3dVect(QString &line)
00332 {
00333 float x=0.0f;
00334 float y=0.0f;
00335 float z=0.0f;
00336
00337 QList<float> vectResult;
00338 QTextStream stringVecteur(&line);
00339
00340 QString xString, yString, zString;
00341
00342 if (((stringVecteur >> xString >> yString >> zString).status() == QTextStream::Ok))
00343 {
00344 bool xOk, yOk, zOk;
00345 x= xString.toFloat(&xOk);
00346 y= yString.toFloat(&yOk);
00347 z= zString.toFloat(&zOk);
00348 if (!(xOk && yOk && zOk))
00349 {
00350 QString message= "GLC_ObjToWorld::extract3dVect " + m_FileName + " failed to convert vector component to float";
00351 message.append("\nAt ligne : ");
00352 message.append(QString::number(m_CurrentLineNumber));
00353 QStringList stringList(m_FileName);
00354 stringList.append(message);
00355 GLC_ErrorLog::addError(stringList);
00356
00357
00358
00359
00360 }
00361 else
00362 {
00363 vectResult << x << y << z;
00364 }
00365 }
00366
00367 return vectResult;
00368
00369 }
00370
00371
00372 QList<float> GLC_ObjToWorld::extract2dVect(QString &line)
00373 {
00374 float x=0.0f;
00375 float y=0.0f;
00376 QList<float> vectResult;
00377 QTextStream stringVecteur(&line);
00378
00379 QString xString, yString;
00380
00381 if (((stringVecteur >> xString >> yString).status() == QTextStream::Ok))
00382 {
00383 bool xOk, yOk;
00384 x= xString.toFloat(&xOk);
00385 y= yString.toFloat(&yOk);
00386 if (!(xOk && yOk))
00387 {
00388 QString message= "GLC_ObjToWorld::extract2dVect " + m_FileName + " failed to convert vector component to double";
00389 message.append("\nAt ligne : ");
00390 message.append(QString::number(m_CurrentLineNumber));
00391 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
00392 clear();
00393 throw(fileFormatException);
00394 }
00395 vectResult << x << y;
00396 }
00397
00398 return vectResult;
00399 }
00400
00401
00402 void GLC_ObjToWorld::extractFaceIndex(QString &line)
00403 {
00404 QString buff;
00405
00406 int coordinateIndex;
00407 int normalIndex;
00408 int textureCoordinateIndex;
00409
00410 QList<GLuint> currentFaceIndex;
00412
00414 QTextStream streamFace(&line);
00415 while ((!streamFace.atEnd()))
00416 {
00417 streamFace >> buff;
00418 extractVertexIndex(buff, coordinateIndex, normalIndex, textureCoordinateIndex);
00419
00420 ObjVertice currentVertice(coordinateIndex, normalIndex, textureCoordinateIndex);
00421 if (m_pCurrentObjMesh->m_ObjVerticeIndexMap.contains(currentVertice))
00422 {
00423 currentFaceIndex.append(m_pCurrentObjMesh->m_ObjVerticeIndexMap.value(currentVertice));
00424 }
00425 else
00426 {
00427
00428 m_pCurrentObjMesh->m_Positions.append(m_Positions.value(coordinateIndex * 3));
00429 m_pCurrentObjMesh->m_Positions.append(m_Positions.value(coordinateIndex * 3 + 1));
00430 m_pCurrentObjMesh->m_Positions.append(m_Positions.value(coordinateIndex * 3 + 2));
00431 if (-1 != normalIndex)
00432 {
00433
00434 m_pCurrentObjMesh->m_Normals.append(m_Normals.value(normalIndex * 3));
00435 m_pCurrentObjMesh->m_Normals.append(m_Normals.value(normalIndex * 3 + 1));
00436 m_pCurrentObjMesh->m_Normals.append(m_Normals.value(normalIndex * 3 + 2));
00437 }
00438 else
00439 {
00440
00441 m_pCurrentObjMesh->m_Normals.append(0.0f);
00442 m_pCurrentObjMesh->m_Normals.append(0.0f);
00443 m_pCurrentObjMesh->m_Normals.append(0.0f);
00444 }
00445 if (-1 != textureCoordinateIndex)
00446 {
00447
00448 m_pCurrentObjMesh->m_Texels.append(m_Texels.value(textureCoordinateIndex * 2));
00449 m_pCurrentObjMesh->m_Texels.append(m_Texels.value(textureCoordinateIndex * 2 + 1));
00450 }
00451 else if (!m_pCurrentObjMesh->m_Texels.isEmpty())
00452 {
00453
00454 m_pCurrentObjMesh->m_Texels.append(0.0f);
00455 m_pCurrentObjMesh->m_Texels.append(0.0f);
00456 }
00457
00458 currentFaceIndex.append(m_pCurrentObjMesh->m_NextFreeIndex);
00459
00460 m_pCurrentObjMesh->m_ObjVerticeIndexMap.insert(currentVertice, m_pCurrentObjMesh->m_NextFreeIndex);
00461
00462 ++(m_pCurrentObjMesh->m_NextFreeIndex);
00463 }
00464
00465 }
00467
00469 const int size= currentFaceIndex.size();
00470 if (size < 3)
00471 {
00472 QStringList stringList(m_FileName);
00473 stringList.append("GLC_ObjToWorld::extractFaceIndex Face with less than 3 vertex found");
00474 GLC_ErrorLog::addError(stringList);
00475 return;
00476 }
00478
00480 if ((m_FaceType == coordinateAndNormal) || (m_FaceType == coordinateAndTextureAndNormal))
00481 {
00482 if (size > 3)
00483 {
00484 glc::triangulatePolygon(¤tFaceIndex, m_pCurrentObjMesh->m_Positions);
00485 }
00486 m_pCurrentObjMesh->m_Index.append(currentFaceIndex);
00487 }
00488 else if (m_FaceType != notSet)
00489 {
00490 if (size > 3)
00491 {
00492 glc::triangulatePolygon(¤tFaceIndex, m_pCurrentObjMesh->m_Positions);
00493 }
00494
00495 if (currentFaceIndex.size() < 3) return;
00496 GLC_Vector3df normal= computeNormal(currentFaceIndex.at(0), currentFaceIndex.at(1), currentFaceIndex.at(2));
00497
00498
00499 QSet<GLuint> indexSet= currentFaceIndex.toSet();
00500 QSet<GLuint>::iterator iIndexSet= indexSet.begin();
00501 while (indexSet.constEnd() != iIndexSet)
00502 {
00503 m_pCurrentObjMesh->m_Normals[*iIndexSet * 3]= normal.x();
00504 m_pCurrentObjMesh->m_Normals[*iIndexSet * 3 + 1]= normal.y();
00505 m_pCurrentObjMesh->m_Normals[*iIndexSet * 3 + 2]= normal.z();
00506
00507 ++iIndexSet;
00508 }
00509
00510 m_pCurrentObjMesh->m_Index.append(currentFaceIndex);
00511
00512 }
00513 else
00514 {
00515 QString message= "GLC_ObjToWorld::extractFaceIndex " + m_FileName + " unknow face type";
00516 message.append("\nAt line : ");
00517 message.append(QString::number(m_CurrentLineNumber));
00518 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotSupported);
00519 clear();
00520 throw(fileFormatException);
00521 }
00522 }
00524 void GLC_ObjToWorld::setCurrentMaterial(QString &line)
00525 {
00526 QTextStream streamString(&line);
00527 QString materialName;
00528
00529 if (!((streamString >> materialName).status() == QTextStream::Ok))
00530 {
00531 QString message= "GLC_ObjToWorld::SetCurrentMaterial " + m_FileName + " : failed to extract materialName";
00532 message.append("\nAt line : ");
00533 message.append(QString::number(m_CurrentLineNumber));
00534 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
00535 clear();
00536 throw(fileFormatException);
00537 }
00539
00541 if ((NULL != m_pMtlLoader) && m_pMtlLoader->contains(materialName))
00542 {
00543 if (NULL == m_pCurrentObjMesh)
00544 {
00545 changeGroup("GLC_Default");
00546 }
00547 Q_ASSERT(NULL != m_pCurrentObjMesh->m_pLastOffsetSize);
00548
00549 if (m_pCurrentObjMesh->m_Index.size() != m_pCurrentObjMesh->m_pLastOffsetSize->m_Offset)
00550 {
00551
00552 m_pCurrentObjMesh->m_pLastOffsetSize->m_size= m_pCurrentObjMesh->m_Index.size() - m_pCurrentObjMesh->m_pLastOffsetSize->m_Offset;
00553 }
00554 else
00555 {
00556 QHash<QString, MatOffsetSize*>::iterator iMat= m_pCurrentObjMesh->m_Materials.begin();
00557 while (m_pCurrentObjMesh->m_Materials.constEnd() != iMat)
00558 {
00559 if (iMat.value() == m_pCurrentObjMesh->m_pLastOffsetSize)
00560 {
00561 iMat= m_pCurrentObjMesh->m_Materials.erase(iMat);
00562 }
00563 else
00564 {
00565 ++iMat;
00566 }
00567 }
00568 }
00569
00570 MatOffsetSize* pMatOffsetSize= new MatOffsetSize();
00571 pMatOffsetSize->m_Offset= m_pCurrentObjMesh->m_Index.size();
00572
00573 m_pCurrentObjMesh->m_pLastOffsetSize= pMatOffsetSize;
00574 m_pCurrentObjMesh->m_Materials.insertMulti(materialName, pMatOffsetSize);
00575
00576 m_CurrentMaterialName= materialName;
00577 }
00578
00579 }
00580
00581 void GLC_ObjToWorld::extractVertexIndex(QString line, int &Coordinate, int &Normal, int &TextureCoordinate)
00582 {
00583 if (m_FaceType == notSet)
00584 {
00585 setObjType(line);
00586 }
00587
00588 if (m_FaceType == coordinateAndTextureAndNormal)
00589 {
00590
00591 line.replace('/', ' ');
00592 QTextStream streamVertex(&line);
00593 QString coordinateString, textureCoordinateString, normalString;
00594 if ((streamVertex >> coordinateString >> textureCoordinateString >> normalString).status() == QTextStream::Ok)
00595 {
00596 bool coordinateOk, textureCoordinateOk, normalOk;
00597 Coordinate= coordinateString.toInt(&coordinateOk);
00598 --Coordinate;
00599 TextureCoordinate= textureCoordinateString.toInt(&textureCoordinateOk);
00600 --TextureCoordinate;
00601 Normal= normalString.toInt(&normalOk);
00602 --Normal;
00603 if (!(coordinateOk && textureCoordinateOk && normalOk))
00604 {
00605 QString message= "GLC_ObjToWorld::extractVertexIndex " + m_FileName + " failed to convert String to int";
00606 message.append("\nAt line : ");
00607 message.append(QString::number(m_CurrentLineNumber));
00608 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
00609 clear();
00610 throw(fileFormatException);
00611 }
00612 }
00613 else
00614 {
00615 QString message= "GLC_ObjToWorld::extractVertexIndex Obj file " + m_FileName + " type is not supported";
00616 message.append("\nAt line : ");
00617 message.append(QString::number(m_CurrentLineNumber));
00618 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotSupported);
00619 clear();
00620 throw(fileFormatException);
00621 }
00622
00623 }
00624 else if (m_FaceType == coordinateAndTexture)
00625 {
00626
00627 line.replace('/', ' ');
00628 QTextStream streamVertex(&line);
00629 QString coordinateString, textureCoordinateString;
00630 if ((streamVertex >> coordinateString >> textureCoordinateString).status() == QTextStream::Ok)
00631 {
00632 bool coordinateOk, textureCoordinateOk;
00633 Coordinate= coordinateString.toInt(&coordinateOk);
00634 --Coordinate;
00635 TextureCoordinate= textureCoordinateString.toInt(&textureCoordinateOk);
00636 --TextureCoordinate;
00637 Normal= -1;
00638 if (!(coordinateOk && textureCoordinateOk))
00639 {
00640 QString message= "GLC_ObjToWorld::extractVertexIndex " + m_FileName + "failed to convert String to int";
00641 message.append("\nAt line : ");
00642 message.append(QString::number(m_CurrentLineNumber));
00643 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
00644 clear();
00645 throw(fileFormatException);
00646 }
00647 }
00648 else
00649 {
00650 QString message= "GLC_ObjToWorld::extractVertexIndex " + m_FileName + " this Obj file type is not supported";
00651 message.append("\nAt line : ");
00652 message.append(QString::number(m_CurrentLineNumber));
00653 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotSupported);
00654 clear();
00655 throw(fileFormatException);
00656 }
00657 }
00658 else if (m_FaceType == coordinateAndNormal)
00659 {
00660
00661 line.replace('/', ' ');
00662 QTextStream streamVertex(&line);
00663 QString coordinateString, normalString;
00664 if ((streamVertex >> coordinateString >> normalString).status() == QTextStream::Ok)
00665 {
00666 bool coordinateOk, normalOk;
00667 Coordinate= coordinateString.toInt(&coordinateOk);
00668 --Coordinate;
00669 TextureCoordinate= -1;
00670 Normal= normalString.toInt(&normalOk);
00671 --Normal;
00672 if (!(coordinateOk && normalOk))
00673 {
00674 QString message= "GLC_ObjToWorld::extractVertexIndex " + m_FileName + " failed to convert String to int";
00675 message.append("\nAt line : ");
00676 message.append(QString::number(m_CurrentLineNumber));
00677 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
00678 clear();
00679 throw(fileFormatException);
00680 }
00681 }
00682 else
00683 {
00684 QString message= "GLC_ObjToWorld::extractVertexIndex " + m_FileName + " this Obj file type is not supported";
00685 message.append("\nAt line : ");
00686 message.append(QString::number(m_CurrentLineNumber));
00687 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotSupported);
00688 clear();
00689 throw(fileFormatException);
00690 }
00691 }
00692 else if (m_FaceType == coordinate)
00693 {
00694 QTextStream streamVertex(&line);
00695 QString coordinateString;
00696 if ((streamVertex >> coordinateString).status() == QTextStream::Ok)
00697 {
00698 bool coordinateOk;
00699 Coordinate= coordinateString.toInt(&coordinateOk);
00700 --Coordinate;
00701 TextureCoordinate= -1;
00702 Normal= -1;
00703 if (!coordinateOk)
00704 {
00705 QString message= "GLC_ObjToWorld::extractVertexIndex " + m_FileName + " failed to convert String to int";
00706 message.append("\nAt line : ");
00707 message.append(QString::number(m_CurrentLineNumber));
00708 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
00709 clear();
00710 throw(fileFormatException);
00711 }
00712 }
00713 else
00714 {
00715 QString message= "GLC_ObjToWorld::extractVertexIndex Obj " + m_FileName + " file type is not supported";
00716 message.append("\nAt line : ");
00717 message.append(QString::number(m_CurrentLineNumber));
00718 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotSupported);
00719 clear();
00720 throw(fileFormatException);
00721 }
00722 }
00723 else
00724 {
00725 QString message= "GLC_ObjToWorld::extractVertexIndex OBJ file " + m_FileName + " not reconize";
00726 message.append("\nAt line : ");
00727 message.append(QString::number(m_CurrentLineNumber));
00728 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotSupported);
00729 clear();
00730 throw(fileFormatException);
00731 }
00732 }
00733
00734
00735 void GLC_ObjToWorld::setObjType(QString& ligne)
00736 {
00737 const QRegExp coordinateOnlyRegExp("^\\d{1,}$");
00738 const QRegExp coordinateTextureNormalRegExp("^\\d{1,}/\\d{1,}/\\d{1,}$");
00739 const QRegExp coordinateNormalRegExp("^\\d{1,}//\\d{1,}$");
00740 const QRegExp coordinateTextureRegExp("^\\d{1,}/\\d{1,}$");
00741
00742 if (coordinateTextureNormalRegExp.exactMatch(ligne))
00743 {
00744 m_FaceType= coordinateAndTextureAndNormal;
00745 }
00746 else if (coordinateTextureRegExp.exactMatch(ligne))
00747 {
00748 m_FaceType= coordinateAndTexture;
00749 }
00750 else if (coordinateNormalRegExp.exactMatch(ligne))
00751 {
00752 m_FaceType= coordinateAndNormal;
00753 }
00754 else if (coordinateOnlyRegExp.exactMatch(ligne))
00755 {
00756 m_FaceType= coordinate;
00757 }
00758 else
00759 {
00760 QString message= "GLC_ObjToWorld::setObjType OBJ file " + m_FileName + " not reconize";
00761 message.append("\nAt line : ");
00762 message.append(QString::number(m_CurrentLineNumber));
00763 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotSupported);
00764 clear();
00765 throw(fileFormatException);
00766 }
00767 }
00768
00769
00770 GLC_Vector3df GLC_ObjToWorld::computeNormal(GLuint index1, GLuint index2, GLuint index3)
00771 {
00772 double xn, yn, zn;
00773
00774
00775 xn= m_pCurrentObjMesh->m_Positions.at(index1 * 3);
00776 yn= m_pCurrentObjMesh->m_Positions.at(index1 * 3 + 1);
00777 zn= m_pCurrentObjMesh->m_Positions.at(index1 * 3 + 2);
00778 const GLC_Vector3d vect1(xn, yn, zn);
00779
00780
00781 xn= m_pCurrentObjMesh->m_Positions.at(index2 * 3);
00782 yn= m_pCurrentObjMesh->m_Positions.at(index2 * 3 + 1);
00783 zn= m_pCurrentObjMesh->m_Positions.at(index2 * 3 + 2);
00784 const GLC_Vector3d vect2(xn, yn, zn);
00785
00786
00787 xn= m_pCurrentObjMesh->m_Positions.at(index3 * 3);
00788 yn= m_pCurrentObjMesh->m_Positions.at(index3 * 3 + 1);
00789 zn= m_pCurrentObjMesh->m_Positions.at(index3 * 3 + 2);
00790 const GLC_Vector3d vect3(xn, yn, zn);
00791
00792 const GLC_Vector3d edge1(vect3 - vect2);
00793 const GLC_Vector3d edge2(vect1 - vect2);
00794
00795 GLC_Vector3d normal(edge1 ^ edge2);
00796 normal.normalize();
00797
00798 return normal.toVector3df();
00799 }
00800
00801
00802 void GLC_ObjToWorld::clear()
00803 {
00804 m_CurrentMeshMaterials.clear();
00805 m_ListOfAttachedFileName.clear();
00806
00807 if (NULL != m_pMtlLoader)
00808 {
00809 delete m_pMtlLoader;
00810 m_pMtlLoader= NULL;
00811 }
00812 if (NULL != m_pCurrentObjMesh)
00813 {
00814 delete m_pCurrentObjMesh;
00815 m_pCurrentObjMesh= NULL;
00816 }
00817
00818 }
00819
00820 void GLC_ObjToWorld::mergeLines(QString* pLineBuff, QTextStream* p0bjStream)
00821 {
00822 if (pLineBuff->endsWith(QChar('\\')))
00823 {
00824 pLineBuff->replace(QChar('\\'), QChar(' '));
00825 pLineBuff->append(p0bjStream->readLine());
00826 ++m_CurrentLineNumber;
00827 mergeLines(pLineBuff, p0bjStream);
00828 }
00829 }
00830
00831
00832 void GLC_ObjToWorld::addCurrentObjMeshToWorld()
00833 {
00834 if (NULL != m_pCurrentObjMesh)
00835 {
00836 if (!m_pCurrentObjMesh->m_Positions.isEmpty())
00837 {
00838 m_pCurrentObjMesh->m_pMesh->addVertice(m_pCurrentObjMesh->m_Positions.toVector());
00839 m_pCurrentObjMesh->m_Positions.clear();
00840 m_pCurrentObjMesh->m_pMesh->addNormals(m_pCurrentObjMesh->m_Normals.toVector());
00841 m_pCurrentObjMesh->m_Normals.clear();
00842 if (!m_pCurrentObjMesh->m_Texels.isEmpty())
00843 {
00844 m_pCurrentObjMesh->m_pMesh->addTexels(m_pCurrentObjMesh->m_Texels.toVector());
00845 m_pCurrentObjMesh->m_Texels.clear();
00846 }
00847 QHash<QString, MatOffsetSize*>::iterator iMat= m_pCurrentObjMesh->m_Materials.begin();
00848 while (m_pCurrentObjMesh->m_Materials.constEnd() != iMat)
00849 {
00850 GLC_Material* pCurrentMaterial= NULL;
00851 if ((NULL != m_pMtlLoader) && (m_pMtlLoader->contains(iMat.key())))
00852 {
00853 pCurrentMaterial= m_pMtlLoader->material(iMat.key());
00854 }
00855
00856 const int offset= iMat.value()->m_Offset;
00857 int size= iMat.value()->m_size;
00858 if (0 == size)
00859 {
00860 size= m_pCurrentObjMesh->m_Index.size() - offset;
00861 }
00862
00863 QList<GLuint> triangles;
00864 for (int i= offset; i < (offset + size); ++i)
00865 {
00866 triangles.append(m_pCurrentObjMesh->m_Index.at(i));
00867 }
00868
00869 if (!triangles.isEmpty())
00870 {
00871 m_pCurrentObjMesh->m_pMesh->addTriangles(pCurrentMaterial, triangles);
00872 }
00873
00874 ++iMat;
00875 }
00876 if (m_pCurrentObjMesh->m_pMesh->faceCount(0) > 0)
00877 {
00878 m_pCurrentObjMesh->m_pMesh->finish();
00879 GLC_3DRep* pRep= new GLC_3DRep(m_pCurrentObjMesh->m_pMesh);
00880 m_pWorld->rootOccurence()->addChild((new GLC_StructInstance(pRep)));
00881 }
00882 else
00883 {
00884 delete m_pCurrentObjMesh->m_pMesh;
00885 }
00886
00887 }
00888 else
00889 {
00890 delete m_pCurrentObjMesh->m_pMesh;
00891 }
00892
00893 delete m_pCurrentObjMesh;
00894 m_pCurrentObjMesh= NULL;
00895 }
00896 }
00897
00898