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