00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00027
00028 #include "glc_offtoworld.h"
00029 #include "../sceneGraph/glc_world.h"
00030 #include "../glc_fileformatexception.h"
00031 #include "../sceneGraph/glc_structreference.h"
00032 #include "../sceneGraph/glc_structinstance.h"
00033 #include "../sceneGraph/glc_structoccurence.h"
00034
00035 #include <QTextStream>
00036 #include <QFileInfo>
00037 #include <QGLContext>
00038
00039 GLC_OffToWorld::GLC_OffToWorld()
00040 : m_pWorld(NULL)
00041 , m_FileName()
00042 , m_CurrentLineNumber(0)
00043 , m_pCurrentMesh(NULL)
00044 , m_CurVertexIndex(0)
00045 , m_NbrOfVertexs(0)
00046 , m_NbrOfFaces(0)
00047 , m_IsCoff(false)
00048 , m_Is4off(false)
00049 , m_PositionBulk()
00050 , m_NormalBulk()
00051 , m_ColorBulk()
00052 , m_IndexList()
00053 {
00054
00055 }
00056
00057 GLC_OffToWorld::~GLC_OffToWorld()
00058 {
00059 clear();
00060 }
00061
00063
00065
00066
00067 GLC_World* GLC_OffToWorld::CreateWorldFromOff(QFile &file)
00068 {
00069 clear();
00070 m_FileName= file.fileName();
00072
00074 if (!file.open(QIODevice::ReadOnly))
00075 {
00076 QString message(QString("GLC_OffToWorld::CreateWorldFromOff File ") + m_FileName + QString(" doesn't exist"));
00077 qDebug() << message;
00078 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotFound);
00079 throw(fileFormatException);
00080 }
00081
00083
00085 m_pWorld= new GLC_World;
00086
00087
00088 int currentQuantumValue= 0;
00089 int previousQuantumValue= 0;
00090
00091
00092 QTextStream offStream(&file);
00093
00094
00095 QString lineBuff;
00096
00098
00100
00101 ++m_CurrentLineNumber;
00102 lineBuff= offStream.readLine();
00103 lineBuff= lineBuff.trimmed();
00104 if(offStream.atEnd() || (!lineBuff.startsWith("OFF") && !lineBuff.startsWith("COFF") && !lineBuff.startsWith("4OFF")))
00105 {
00106 QString message= "GLC_OffToWorld::CreateWorldFromOff : OFF or COFF header not found";
00107 qDebug() << message;
00108 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotSupported);
00109 clear();
00110 throw(fileFormatException);
00111 }
00112
00113
00114 m_IsCoff= lineBuff.startsWith("COFF");
00115
00116
00117 m_Is4off= lineBuff.startsWith("4OFF");
00118
00119
00120 m_pCurrentMesh= new GLC_Mesh();
00121
00122
00123 if (m_IsCoff)
00124 {
00125 m_pCurrentMesh->setColorPearVertex(true);
00126 }
00127
00128 ++m_CurrentLineNumber;
00129 lineBuff= offStream.readLine();
00130 lineBuff= lineBuff.trimmed();
00131 while(!offStream.atEnd() && lineBuff.startsWith(QChar('#')))
00132 {
00133 ++m_CurrentLineNumber;
00134 lineBuff= offStream.readLine();
00135 lineBuff= lineBuff.trimmed();
00136 }
00137 extractNbrVertexsAndNbrFaces(lineBuff);
00138
00140
00142 emit currentQuantum(currentQuantumValue);
00143
00144 for (int currentVertex= 0; currentVertex < m_NbrOfVertexs; ++currentVertex)
00145 {
00146
00147 if(offStream.atEnd())
00148 {
00149 QString message= "GLC_OffToWorld::CreateWorldFromOff : This file seems to be incomplete";
00150 message.append("\nAt ligne : ");
00151 message.append(QString::number(m_CurrentLineNumber));
00152 qDebug() << message;
00153 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotSupported);
00154 clear();
00155 throw(fileFormatException);
00156 }
00157
00158 ++m_CurrentLineNumber;
00159 lineBuff= offStream.readLine();
00160
00161 while (lineBuff.isEmpty())
00162 {
00163 ++m_CurrentLineNumber;
00164 lineBuff= offStream.readLine();
00165 }
00166
00167 extractVertex(lineBuff);
00168
00169
00170 currentQuantumValue = static_cast<int>((static_cast<double>(currentVertex) / (m_NbrOfVertexs + m_NbrOfFaces)) * 100);
00171 if (currentQuantumValue > previousQuantumValue)
00172 {
00173 emit currentQuantum(currentQuantumValue);
00174 }
00175 previousQuantumValue= currentQuantumValue;
00176 }
00177
00179
00181 for (int currentFace= 0; currentFace < m_NbrOfFaces; ++currentFace)
00182 {
00183
00184 if(offStream.atEnd())
00185 {
00186 QString message= "GLC_OffToWorld::CreateWorldFromOff : This file seems to be incomplete";
00187 message.append("\nAt ligne : ");
00188 message.append(QString::number(m_CurrentLineNumber));
00189 qDebug() << message;
00190 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotSupported);
00191 clear();
00192 throw(fileFormatException);
00193 }
00194
00195 ++m_CurrentLineNumber;
00196 lineBuff= offStream.readLine();
00197 while (lineBuff.isEmpty())
00198 {
00199 ++m_CurrentLineNumber;
00200 lineBuff= offStream.readLine();
00201 }
00202
00203
00204 extractFaceIndex(lineBuff);
00205
00206
00207 currentQuantumValue = static_cast<int>((static_cast<double>(currentFace + m_NbrOfVertexs + 1) / (m_NbrOfVertexs + m_NbrOfFaces)) * 100);
00208 if (currentQuantumValue > previousQuantumValue)
00209 {
00210 emit currentQuantum(currentQuantumValue);
00211 }
00212 previousQuantumValue= currentQuantumValue;
00213
00214 }
00215
00216 file.close();
00217
00218 computeNormal();
00219
00220 m_pCurrentMesh->addVertice(m_PositionBulk.toVector());
00221 m_pCurrentMesh->addNormals(m_NormalBulk.toVector());
00222 if (!m_ColorBulk.isEmpty())
00223 {
00224 m_pCurrentMesh->addColors(m_ColorBulk.toVector());
00225 }
00226 m_pCurrentMesh->addTriangles(NULL, m_IndexList);
00227
00228 m_pCurrentMesh->finish();
00229 GLC_3DRep* pRep= new GLC_3DRep(m_pCurrentMesh);
00230 m_pCurrentMesh= NULL;
00231 m_pWorld->rootOccurence()->addChild(new GLC_StructOccurence(pRep));
00232
00233 return m_pWorld;
00234 }
00235
00237
00239
00240
00241 void GLC_OffToWorld::clear()
00242 {
00243 if (NULL != m_pCurrentMesh)
00244 {
00245 delete m_pCurrentMesh;
00246 m_pCurrentMesh= NULL;
00247 }
00248 m_pWorld= NULL;
00249 m_FileName.clear();
00250 m_CurrentLineNumber= 0;
00251 m_pCurrentMesh= NULL;
00252 m_CurVertexIndex= 0;
00253 m_NbrOfVertexs= 0;
00254 m_NbrOfFaces= 0;
00255 m_IsCoff= false;
00256 m_Is4off= false;
00257 m_PositionBulk.clear();
00258 m_NormalBulk.clear();
00259 m_ColorBulk.clear();
00260 }
00261
00262
00263 void GLC_OffToWorld::extractVertex(QString &line)
00264 {
00265
00266 QTextStream stringVecteur(&line);
00267
00268 QString xString, yString, zString;
00269
00270 if (((stringVecteur >> xString >> yString >> zString).status() == QTextStream::Ok))
00271 {
00272 bool xOk, yOk, zOk;
00273 m_PositionBulk.append(xString.toFloat(&xOk));
00274 m_PositionBulk.append(yString.toFloat(&yOk));
00275 m_PositionBulk.append(zString.toFloat(&zOk));
00276 if (!(xOk && yOk && zOk))
00277 {
00278 QString message= "GLC_OffToWorld::extractVertex : failed to convert vertex component to float";
00279 message.append("\nAt ligne : ");
00280 message.append(QString::number(m_CurrentLineNumber));
00281 qDebug() << message;
00282 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
00283 clear();
00284 throw(fileFormatException);
00285 }
00286 if (m_Is4off)
00287 {
00288 QString wString;
00289 if (((stringVecteur >> wString).status() == QTextStream::Ok))
00290 {
00291 float w;
00292 bool wOk;
00293 w= wString.toFloat(&wOk);
00294 if (!wOk)
00295 {
00296 QString message= "GLC_OffToWorld::extractVertex : failed to convert vertex fourth component to float";
00297 message.append("\nAt ligne : ");
00298 message.append(QString::number(m_CurrentLineNumber));
00299 qDebug() << message;
00300 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
00301 clear();
00302 throw(fileFormatException);
00303 }
00304 const int lastValue= m_PositionBulk.size() - 1;
00305 m_PositionBulk[lastValue - 2]= m_PositionBulk.at(lastValue - 2) / w;
00306 m_PositionBulk[lastValue - 1]= m_PositionBulk.at(lastValue - 1) / w;
00307 m_PositionBulk[lastValue]= m_PositionBulk.at(lastValue) / w;
00308 }
00309 else
00310 {
00311 QString message= "GLC_OffToWorld::extractVertex : failed to read vector fourth component";
00312 message.append("\nAt ligne : ");
00313 message.append(QString::number(m_CurrentLineNumber));
00314 qDebug() << message;
00315 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
00316 clear();
00317 throw(fileFormatException);
00318 }
00319 }
00320
00321
00322 if (m_IsCoff)
00323 {
00324 QString rString, gString, bString, aString;
00325
00326 if (((stringVecteur >> rString >> gString >> bString >> aString).status() == QTextStream::Ok))
00327 {
00328 bool rOk, gOk, bOk, aOk;
00329 m_ColorBulk.append(rString.toFloat(&rOk));
00330 m_ColorBulk.append(gString.toFloat(&gOk));
00331 m_ColorBulk.append(bString.toFloat(&bOk));
00332 m_ColorBulk.append(aString.toFloat(&aOk));
00333 if (!(rOk && gOk && bOk && aOk))
00334 {
00335 QString message= "GLC_OffToWorld::extractVertex : failed to convert color component to float";
00336 message.append("\nAt ligne : ");
00337 message.append(QString::number(m_CurrentLineNumber));
00338 qDebug() << message;
00339 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
00340 clear();
00341 throw(fileFormatException);
00342 }
00343 }
00344 else
00345 {
00346 QString message= "GLC_OffToWorld::extractVertex : failed to read vertex color";
00347 message.append("\nAt ligne : ");
00348 message.append(QString::number(m_CurrentLineNumber));
00349 qDebug() << message;
00350 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
00351 clear();
00352 throw(fileFormatException);
00353 }
00354 }
00355
00356 }
00357 else
00358 {
00359 QString message= "GLC_OffToWorld::extractVertex : failed to read vector component";
00360 message.append("\nAt ligne : ");
00361 message.append(QString::number(m_CurrentLineNumber));
00362 qDebug() << message;
00363 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
00364 clear();
00365 throw(fileFormatException);
00366 }
00367
00368 }
00369
00370
00371 void GLC_OffToWorld::extractNbrVertexsAndNbrFaces(QString &line)
00372 {
00373 QTextStream stringVecteur(&line);
00374
00375 QString xString, yString;
00376
00377 if (((stringVecteur >> xString >> yString).status() == QTextStream::Ok))
00378 {
00379 bool xOk, yOk;
00380 m_NbrOfVertexs= xString.toInt(&xOk);
00381 m_NbrOfFaces= yString.toInt(&yOk);
00382 if (!(xOk && yOk))
00383 {
00384 QString message= "GLC_OffToWorld::extractNbrVertexsAndNbrFaces : failed to convert text to int";
00385 message.append("\nAt ligne : ");
00386 message.append(QString::number(m_CurrentLineNumber));
00387 qDebug() << message;
00388 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
00389 clear();
00390 throw(fileFormatException);
00391 }
00392 }
00393 else
00394 {
00395 QString message= "GLC_OffToWorld::extractNbrVertexsAndNbrFaces : failed to extract nbr of vertexs/faces";
00396 message.append("\nAt ligne : ");
00397 message.append(QString::number(m_CurrentLineNumber));
00398 qDebug() << message;
00399 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
00400 clear();
00401 throw(fileFormatException);
00402
00403 }
00404 }
00405
00406
00407 void GLC_OffToWorld::extractFaceIndex(QString &line)
00408 {
00409 QString buff;
00410
00411 QList<GLuint> indexList;
00412
00414
00416 QTextStream streamFace(&line);
00417
00418 if((streamFace >> buff).status() != QTextStream::Ok)
00419 {
00420 QString message= "GLC_OffToWorld::extractFaceIndex failed to extract number of vertex index";
00421 message.append("\nAt line : ");
00422 message.append(QString::number(m_CurrentLineNumber));
00423 message.append(QString("\n") + line);
00424 qDebug() << message;
00425 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
00426 clear();
00427 throw(fileFormatException);
00428 }
00429 bool conversionOk;
00430
00431 int numberOfVertex= buff.toInt(&conversionOk);
00432 if (!conversionOk)
00433 {
00434 QString message= "GLC_OffToWorld::extractFaceIndex failed to convert String to int";
00435 message.append("\nAt line : ");
00436 message.append(QString::number(m_CurrentLineNumber));
00437 qDebug() << message;
00438 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
00439 clear();
00440 throw(fileFormatException);
00441 }
00442
00443 for (int i= 0; i < numberOfVertex; ++i)
00444 {
00445
00446 if((streamFace >> buff).status() != QTextStream::Ok)
00447 {
00448 QString message= "GLC_OffToWorld::extractFaceIndex failed to extract vertex index";
00449 message.append("\nAt line : ");
00450 message.append(QString::number(m_CurrentLineNumber));
00451 qDebug() << message;
00452 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
00453 clear();
00454 throw(fileFormatException);
00455 }
00456
00457 int index= buff.toInt(&conversionOk);
00458 if (conversionOk)
00459 {
00460 indexList.append(index);
00461 }
00462 else
00463 {
00464 QString message= "GLC_ObjToWorld::extractFaceIndex failed to convert String to int";
00465 message.append("\nAt line : ");
00466 message.append(QString::number(m_CurrentLineNumber));
00467 qDebug() << message;
00468 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
00469 clear();
00470 throw(fileFormatException);
00471 }
00472 }
00473
00474
00475 QString rString, gString, bString;
00476 if((streamFace >> rString >> gString >> bString).status() == QTextStream::Ok)
00477 {
00478
00479 if (m_ColorBulk.isEmpty())
00480 {
00481 const int size= m_PositionBulk.size() / 3 * 4;
00482 for (int i= 0; i < size; ++i)
00483 {
00484 m_PositionBulk.append(0.0);
00485 }
00486 }
00487 float r, g, b;
00488 bool rOk, gOk, bOk;
00489 r= rString.toFloat(&rOk);
00490 g= gString.toFloat(&gOk);
00491 b= bString.toFloat(&bOk);
00492 if (!rOk || !gOk || !bOk)
00493 {
00494 QString message= "GLC_ObjToWorld::extractFaceIndex failed to convert String to float";
00495 message.append("\nAt line : ");
00496 message.append(QString::number(m_CurrentLineNumber));
00497 qDebug() << message;
00498 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
00499 clear();
00500 throw(fileFormatException);
00501 }
00502 for (int i= 0; i < numberOfVertex; ++i)
00503 {
00504 m_ColorBulk[indexList[i] * 4]= r;
00505 m_ColorBulk[indexList[i] * 4 + 1]= g;
00506 m_ColorBulk[indexList[i] * 4 + 2]= b;
00507 m_ColorBulk[indexList[i] * 4 + 3]= 1.0f;
00508 }
00509 }
00510
00511
00512 m_IndexList.append(indexList);
00513 }
00514
00515
00516 void GLC_OffToWorld::computeNormal()
00517 {
00518 qDebug() << "GLC_OffToWorld::computeNormal";
00519 qDebug() << "Position size= " << m_PositionBulk.size();
00520 qDebug() << "Normal size= " << m_NormalBulk.size();
00521 const QList<float>* pData= &m_PositionBulk;
00522
00523 QList<float>* pNormal= &m_NormalBulk;
00524 const int normalCount= pData->size();
00525 for (int i= 0; i < normalCount; ++i)
00526 {
00527 pNormal->append(0.0f);
00528 }
00529
00530 const int size= m_IndexList.size();
00531 double xn, yn, zn;
00532
00533
00534 for (int i= 0; i < size; i+=3)
00535 {
00536
00537 xn= pData->at(m_IndexList.at(i) * 3);
00538 yn= pData->at(m_IndexList.at(i) * 3 + 1);
00539 zn= pData->at(m_IndexList.at(i) * 3 + 2);
00540 const GLC_Vector3d vect1(xn, yn, zn);
00541
00542
00543 xn= pData->at(m_IndexList.at(i + 1) * 3);
00544 yn= pData->at(m_IndexList.at(i + 1) * 3 + 1);
00545 zn= pData->at(m_IndexList.at(i + 1) * 3 + 2);
00546 const GLC_Vector3d vect2(xn, yn, zn);
00547
00548
00549 xn= pData->at(m_IndexList.at(i + 2) * 3);
00550 yn= pData->at(m_IndexList.at(i + 2) * 3 + 1);
00551 zn= pData->at(m_IndexList.at(i + 2) * 3 + 2);
00552 const GLC_Vector3d vect3(xn, yn, zn);
00553
00554 const GLC_Vector3d edge1(vect3 - vect2);
00555 const GLC_Vector3d edge2(vect1 - vect2);
00556
00557 GLC_Vector3d normal(edge1 ^ edge2);
00558 normal.normalize();
00559
00560 GLC_Vector3df curNormal= normal.toVector3df();
00561 for (int curVertex= 0; curVertex < 3; ++curVertex)
00562 {
00563 (*pNormal)[m_IndexList.at(i + curVertex) * 3]= curNormal.X();
00564 (*pNormal)[m_IndexList.at(i + curVertex) * 3 + 1]= curNormal.Y();
00565 (*pNormal)[m_IndexList.at(i + curVertex) * 3 + 2]= curNormal.Z();
00566 }
00567 }
00568
00569 }
00570