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 "../geometry/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 (not 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) or (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 Q_ASSERT(NULL != m_pCurrentObjMesh);
00538 Q_ASSERT(NULL != m_pCurrentObjMesh->m_pLastOffsetSize);
00539
00540 if (m_pCurrentObjMesh->m_Index.size() != m_pCurrentObjMesh->m_pLastOffsetSize->m_Offset)
00541 {
00542
00543 m_pCurrentObjMesh->m_pLastOffsetSize->m_size= m_pCurrentObjMesh->m_Index.size() - m_pCurrentObjMesh->m_pLastOffsetSize->m_Offset;
00544 }
00545 else
00546 {
00547 QHash<QString, MatOffsetSize*>::iterator iMat= m_pCurrentObjMesh->m_Materials.begin();
00548 while (m_pCurrentObjMesh->m_Materials.constEnd() != iMat)
00549 {
00550 if (iMat.value() == m_pCurrentObjMesh->m_pLastOffsetSize)
00551 {
00552 iMat= m_pCurrentObjMesh->m_Materials.erase(iMat);
00553 }
00554 else
00555 {
00556 ++iMat;
00557 }
00558 }
00559 }
00560
00561 MatOffsetSize* pMatOffsetSize= new MatOffsetSize();
00562 pMatOffsetSize->m_Offset= m_pCurrentObjMesh->m_Index.size();
00563
00564 m_pCurrentObjMesh->m_pLastOffsetSize= pMatOffsetSize;
00565 m_pCurrentObjMesh->m_Materials.insertMulti(materialName, pMatOffsetSize);
00566
00567 m_CurrentMaterialName= materialName;
00568 }
00569
00570 }
00571
00572 void GLC_ObjToWorld::extractVertexIndex(QString ligne, int &Coordinate, int &Normal, int &TextureCoordinate)
00573 {
00574 if (m_FaceType == notSet)
00575 {
00576 setObjType(ligne);
00577 }
00578
00579 if (m_FaceType == coordinateAndTextureAndNormal)
00580 {
00581
00582 ligne.replace('/', ' ');
00583 QTextStream streamVertex(&ligne);
00584 QString coordinateString, textureCoordinateString, normalString;
00585 if ((streamVertex >> coordinateString >> textureCoordinateString >> normalString).status() == QTextStream::Ok)
00586 {
00587 bool coordinateOk, textureCoordinateOk, normalOk;
00588 Coordinate= coordinateString.toInt(&coordinateOk);
00589 --Coordinate;
00590 TextureCoordinate= textureCoordinateString.toInt(&textureCoordinateOk);
00591 --TextureCoordinate;
00592 Normal= normalString.toInt(&normalOk);
00593 --Normal;
00594 if (!(coordinateOk && textureCoordinateOk && normalOk))
00595 {
00596 QString message= "GLC_ObjToWorld::extractVertexIndex failed to convert String to int";
00597 message.append("\nAt line : ");
00598 message.append(QString::number(m_CurrentLineNumber));
00599 qDebug() << message;
00600 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
00601 clear();
00602 throw(fileFormatException);
00603 }
00604 }
00605 else
00606 {
00607 QString message= "GLC_ObjToWorld::extractVertexIndex this Obj file type is not supported";
00608 message.append("\nAt line : ");
00609 message.append(QString::number(m_CurrentLineNumber));
00610 qDebug() << message;
00611 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotSupported);
00612 clear();
00613 throw(fileFormatException);
00614 }
00615
00616 }
00617 else if (m_FaceType == coordinateAndTexture)
00618 {
00619
00620 ligne.replace('/', ' ');
00621 QTextStream streamVertex(&ligne);
00622 QString coordinateString, textureCoordinateString;
00623 if ((streamVertex >> coordinateString >> textureCoordinateString).status() == QTextStream::Ok)
00624 {
00625 bool coordinateOk, textureCoordinateOk;
00626 Coordinate= coordinateString.toInt(&coordinateOk);
00627 --Coordinate;
00628 TextureCoordinate= textureCoordinateString.toInt(&textureCoordinateOk);
00629 --TextureCoordinate;
00630 Normal= -1;
00631 if (!(coordinateOk && textureCoordinateOk))
00632 {
00633 QString message= "GLC_ObjToWorld::extractVertexIndex failed to convert String to int";
00634 message.append("\nAt line : ");
00635 message.append(QString::number(m_CurrentLineNumber));
00636 qDebug() << message;
00637 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
00638 clear();
00639 throw(fileFormatException);
00640 }
00641 }
00642 else
00643 {
00644 QString message= "GLC_ObjToWorld::extractVertexIndex this Obj file type is not supported";
00645 message.append("\nAt line : ");
00646 message.append(QString::number(m_CurrentLineNumber));
00647 qDebug() << message;
00648 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotSupported);
00649 clear();
00650 throw(fileFormatException);
00651 }
00652 }
00653 else if (m_FaceType == coordinateAndNormal)
00654 {
00655
00656 ligne.replace('/', ' ');
00657 QTextStream streamVertex(&ligne);
00658 QString coordinateString, normalString;
00659 if ((streamVertex >> coordinateString >> normalString).status() == QTextStream::Ok)
00660 {
00661 bool coordinateOk, normalOk;
00662 Coordinate= coordinateString.toInt(&coordinateOk);
00663 --Coordinate;
00664 TextureCoordinate= -1;
00665 Normal= normalString.toInt(&normalOk);
00666 --Normal;
00667 if (!(coordinateOk && normalOk))
00668 {
00669 QString message= "GLC_ObjToWorld::extractVertexIndex failed to convert String to int";
00670 message.append("\nAt line : ");
00671 message.append(QString::number(m_CurrentLineNumber));
00672 qDebug() << message;
00673 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
00674 clear();
00675 throw(fileFormatException);
00676 }
00677 }
00678 else
00679 {
00680 QString message= "GLC_ObjToWorld::extractVertexIndex this Obj file type is not supported";
00681 message.append("\nAt line : ");
00682 message.append(QString::number(m_CurrentLineNumber));
00683 qDebug() << message;
00684 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotSupported);
00685 clear();
00686 throw(fileFormatException);
00687 }
00688 }
00689 else if (m_FaceType == coordinate)
00690 {
00691 QTextStream streamVertex(&ligne);
00692 QString coordinateString;
00693 if ((streamVertex >> coordinateString).status() == QTextStream::Ok)
00694 {
00695 bool coordinateOk;
00696 Coordinate= coordinateString.toInt(&coordinateOk);
00697 --Coordinate;
00698 TextureCoordinate= -1;
00699 Normal= -1;
00700 if (!coordinateOk)
00701 {
00702 QString message= "GLC_ObjToWorld::extractVertexIndex failed to convert String to int";
00703 message.append("\nAt line : ");
00704 message.append(QString::number(m_CurrentLineNumber));
00705 qDebug() << message;
00706 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
00707 clear();
00708 throw(fileFormatException);
00709 }
00710 }
00711 else
00712 {
00713 QString message= "GLC_ObjToWorld::extractVertexIndex this Obj file type is not supported";
00714 message.append("\nAt line : ");
00715 message.append(QString::number(m_CurrentLineNumber));
00716 qDebug() << message;
00717 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotSupported);
00718 clear();
00719 throw(fileFormatException);
00720 }
00721 }
00722 else
00723 {
00724 QString message= "GLC_ObjToWorld::extractVertexIndex OBJ file not reconize";
00725 message.append("\nAt line : ");
00726 message.append(QString::number(m_CurrentLineNumber));
00727 qDebug() << message;
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 not reconize";
00761 message.append("\nAt line : ");
00762 message.append(QString::number(m_CurrentLineNumber));
00763 qDebug() << message;
00764 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotSupported);
00765 clear();
00766 throw(fileFormatException);
00767 }
00768 }
00769
00770
00771 GLC_Vector3df GLC_ObjToWorld::computeNormal(GLuint index1, GLuint index2, GLuint index3)
00772 {
00773 double xn, yn, zn;
00774
00775
00776 xn= m_pCurrentObjMesh->m_Positions.at(index1 * 3);
00777 yn= m_pCurrentObjMesh->m_Positions.at(index1 * 3 + 1);
00778 zn= m_pCurrentObjMesh->m_Positions.at(index1 * 3 + 2);
00779 const GLC_Vector4d vect1(xn, yn, zn);
00780
00781
00782 xn= m_pCurrentObjMesh->m_Positions.at(index2 * 3);
00783 yn= m_pCurrentObjMesh->m_Positions.at(index2 * 3 + 1);
00784 zn= m_pCurrentObjMesh->m_Positions.at(index2 * 3 + 2);
00785 const GLC_Vector4d vect2(xn, yn, zn);
00786
00787
00788 xn= m_pCurrentObjMesh->m_Positions.at(index3 * 3);
00789 yn= m_pCurrentObjMesh->m_Positions.at(index3 * 3 + 1);
00790 zn= m_pCurrentObjMesh->m_Positions.at(index3 * 3 + 2);
00791 const GLC_Vector4d vect3(xn, yn, zn);
00792
00793 const GLC_Vector4d edge1(vect3 - vect2);
00794 const GLC_Vector4d edge2(vect1 - vect2);
00795
00796 GLC_Vector4d normal(edge1 ^ edge2);
00797 normal.setNormal(1);
00798
00799 return normal.toVector3df();
00800 }
00801
00802
00803 void GLC_ObjToWorld::clear()
00804 {
00805 m_CurrentMeshMaterials.clear();
00806 m_ListOfAttachedFileName.clear();
00807
00808 if (NULL != m_pMtlLoader)
00809 {
00810 delete m_pMtlLoader;
00811 m_pMtlLoader= NULL;
00812 }
00813 if (NULL != m_pCurrentObjMesh)
00814 {
00815 delete m_pCurrentObjMesh;
00816 m_pCurrentObjMesh= NULL;
00817 }
00818
00819 }
00820
00821 void GLC_ObjToWorld::mergeLines(QString* pLineBuff, QTextStream* p0bjStream)
00822 {
00823 if (pLineBuff->endsWith(QChar('\\')))
00824 {
00825 pLineBuff->replace(QChar('\\'), QChar(' '));
00826 pLineBuff->append(p0bjStream->readLine());
00827 ++m_CurrentLineNumber;
00828 mergeLines(pLineBuff, p0bjStream);
00829 }
00830 }
00831
00832
00833 void GLC_ObjToWorld::addCurrentObjMeshToWorld()
00834 {
00835 if (NULL != m_pCurrentObjMesh)
00836 {
00837 if (not m_pCurrentObjMesh->m_Positions.isEmpty())
00838 {
00839 m_pCurrentObjMesh->m_pMesh->addVertices(m_pCurrentObjMesh->m_Positions.toVector());
00840 m_pCurrentObjMesh->m_Positions.clear();
00841 m_pCurrentObjMesh->m_pMesh->addNormals(m_pCurrentObjMesh->m_Normals.toVector());
00842 m_pCurrentObjMesh->m_Normals.clear();
00843 if (not m_pCurrentObjMesh->m_Texels.isEmpty())
00844 {
00845 m_pCurrentObjMesh->m_pMesh->addTexels(m_pCurrentObjMesh->m_Texels.toVector());
00846 m_pCurrentObjMesh->m_Texels.clear();
00847 }
00848 QHash<QString, MatOffsetSize*>::iterator iMat= m_pCurrentObjMesh->m_Materials.begin();
00849 while (m_pCurrentObjMesh->m_Materials.constEnd() != iMat)
00850 {
00851 GLC_Material* pCurrentMaterial= NULL;
00852 if ((NULL != m_pMtlLoader) and (m_pMtlLoader->contains(iMat.key())))
00853 {
00854 pCurrentMaterial= m_pMtlLoader->material(iMat.key());
00855 }
00856
00857 const int offset= iMat.value()->m_Offset;
00858 int size= iMat.value()->m_size;
00859 if (0 == size)
00860 {
00861 size= m_pCurrentObjMesh->m_Index.size() - offset;
00862 }
00863
00864 QList<GLuint> triangles;
00865 for (int i= offset; i < (offset + size); ++i)
00866 {
00867 triangles.append(m_pCurrentObjMesh->m_Index.at(i));
00868 }
00869
00870 if (not triangles.isEmpty())
00871 {
00872 m_pCurrentObjMesh->m_pMesh->addTriangles(pCurrentMaterial, triangles);
00873 }
00874
00875 ++iMat;
00876 }
00877 if (m_pCurrentObjMesh->m_pMesh->numberOfFaces() > 0)
00878 {
00879 m_pCurrentObjMesh->m_pMesh->finished();
00880 GLC_3DRep* pRep= new GLC_3DRep(m_pCurrentObjMesh->m_pMesh);
00881 m_pWorld->rootOccurence()->addChild((new GLC_StructReference(pRep))->createStructInstance());
00882 }
00883 else
00884 {
00885 delete m_pCurrentObjMesh->m_pMesh;
00886 }
00887
00888 }
00889 else
00890 {
00891 delete m_pCurrentObjMesh->m_pMesh;
00892 }
00893
00894 delete m_pCurrentObjMesh;
00895 m_pCurrentObjMesh= NULL;
00896 }
00897 }
00898
00899