00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00024
00025 #include "glc_3dxmltoworld.h"
00026 #include "../sceneGraph/glc_world.h"
00027 #include "../glc_fileformatexception.h"
00028 #include "../geometry/glc_mesh.h"
00029 #include "../geometry/glc_3drep.h"
00030 #include "glc_xmlutil.h"
00031
00032
00033 #include "../3rdparty/quazip/quazip.h"
00034 #include "../3rdparty/quazip/quazipfile.h"
00035
00036 #include <QString>
00037 #include <QGLContext>
00038 #include <QFileInfo>
00039 #include <QSet>
00040 #include <QMutexLocker>
00041
00042
00043
00044 QMutex GLC_3dxmlToWorld::m_ZipMutex;
00045
00046 static qint64 chunckSize= 10000000;
00047
00048 GLC_3dxmlToWorld::GLC_3dxmlToWorld()
00049 : QObject()
00050 , m_pStreamReader(NULL)
00051 , m_FileName()
00052 , m_p3dxmlArchive(NULL)
00053 , m_pCurrentFile(NULL)
00054 , m_RootName()
00055 , m_pWorld(NULL)
00056 , m_ReferenceHash()
00057 , m_AssyLinkList()
00058 , m_InstanceOf()
00059 , m_SetOfExtRef()
00060 , m_InstanceOfExtRefHash()
00061 , m_ExternalReferenceHash()
00062 , m_MaterialHash()
00063 , m_IsInArchive(false)
00064 , m_ReferenceRepHash()
00065 , m_LocalRepLinkList()
00066 , m_ExternRepLinkList()
00067 , m_SetOfExtRep()
00068 , m_pCurrentMaterial(NULL)
00069 , m_TextureImagesHash()
00070 , m_LoadStructureOnly(false)
00071 , m_SetOfAttachedFileName()
00072 , m_CurrentFileName()
00073 , m_CurrentDateTime()
00074 , m_OccurenceAttrib()
00075 , m_GetExternalRef3DName(false)
00076 , m_ByteArrayList()
00077 {
00078
00079 }
00080
00081 GLC_3dxmlToWorld::~GLC_3dxmlToWorld()
00082 {
00083 delete m_pStreamReader;
00084 m_pStreamReader= NULL;
00085
00086 delete m_pCurrentFile;
00087 delete m_p3dxmlArchive;
00088
00089 clearMaterialHash();
00090
00091
00092 QHash<unsigned int, OccurenceAttrib*>::iterator iAttrib= m_OccurenceAttrib.begin();
00093 while (m_OccurenceAttrib.constEnd() != iAttrib)
00094 {
00095 delete iAttrib.value();
00096 ++iAttrib;
00097 }
00098 m_OccurenceAttrib.clear();
00099 }
00100
00102
00104
00105
00106 GLC_World* GLC_3dxmlToWorld::createWorldFrom3dxml(QFile &file, bool structureOnly, bool getExternalRef)
00107 {
00108 clear();
00109 m_pWorld= new GLC_World();
00110 m_GetExternalRef3DName= getExternalRef;
00111 m_LoadStructureOnly= structureOnly;
00112 m_FileName= file.fileName();
00113
00114
00115 m_p3dxmlArchive= new QuaZip(m_FileName);
00116
00117 if(!m_p3dxmlArchive->open(QuaZip::mdUnzip))
00118 {
00119
00120 m_RootName= m_FileName;
00121 delete m_p3dxmlArchive;
00122 m_p3dxmlArchive= NULL;
00123 }
00124 else
00125 {
00126
00127 m_CurrentDateTime= QFileInfo(m_FileName).lastModified();
00128
00129 m_IsInArchive= true;
00130
00131
00132
00133
00134 loadManifest();
00135 }
00136
00137 if (!m_LoadStructureOnly)
00138 {
00139
00140 loadCatRepImage();
00141
00142
00143 loadCatMaterialRef();
00144 }
00145
00146
00147 loadProductStructure();
00148
00149
00150 emit currentQuantum(100);
00151 return m_pWorld;
00152 }
00153
00154
00155 GLC_3DRep GLC_3dxmlToWorld::create3DrepFrom3dxmlRep(const QString& fileName)
00156 {
00157 GLC_3DRep resultRep;
00158 if (glc::isArchiveString(fileName))
00159 {
00160 m_FileName= glc::archiveFileName(fileName);
00161
00162
00163 m_ZipMutex.lock();
00164 m_p3dxmlArchive= new QuaZip(m_FileName);
00165
00166 if(!m_p3dxmlArchive->open(QuaZip::mdUnzip))
00167 {
00168 delete m_p3dxmlArchive;
00169 return GLC_3DRep();
00170 }
00171 else
00172 {
00173 m_IsInArchive= true;
00174
00175
00176 }
00177 m_ZipMutex.unlock();
00178 m_CurrentFileName= glc::archiveEntryFileName(fileName);
00179
00180
00181 m_CurrentDateTime= QFileInfo(QFileInfo(m_FileName).absolutePath() + QDir::separator() + QFileInfo(fileName).fileName()).lastModified();
00182 }
00183 else if (glc::isFileString(fileName))
00184 {
00185 m_FileName= glc::archiveFileName(fileName);
00186 m_CurrentFileName= glc::archiveEntryFileName(fileName);
00187
00188
00189 m_CurrentDateTime= QFileInfo(m_CurrentFileName).lastModified();
00190
00191
00192 QDir structureDir(QFileInfo(m_FileName).absolutePath() + QDir::separator());
00193 m_CurrentFileName= structureDir.relativeFilePath(m_CurrentFileName);
00194
00195 }
00196 else
00197 {
00198 return resultRep;
00199 }
00200
00201
00202 setRepresentationFileName(&resultRep);
00203
00204 if (QFileInfo(m_CurrentFileName).suffix().toLower() == "3dxml")
00205 {
00206 if (GLC_State::cacheIsUsed() && GLC_State::currentCacheManager().isUsable(m_CurrentDateTime, QFileInfo(m_FileName).baseName(), QFileInfo(m_CurrentFileName).fileName()))
00207 {
00208 GLC_CacheManager cacheManager = GLC_State::currentCacheManager();
00209
00210 GLC_BSRep binaryRep = cacheManager.binary3DRep(QFileInfo(m_FileName).baseName(), QFileInfo(m_CurrentFileName).fileName());
00211 resultRep = binaryRep.loadRep();
00212 }
00213 else
00214 {
00215 if (setStreamReaderToFile(m_CurrentFileName, true))
00216 {
00217 GLC_StructReference* pStructRef = createReferenceRep(QString(), NULL);
00218 GLC_3DRep* pRep = NULL;
00219 if ((NULL != pStructRef) && pStructRef->hasRepresentation())
00220 {
00221 pRep= dynamic_cast<GLC_3DRep*> (pStructRef->representationHandle());
00222
00223 if (NULL != pRep)
00224 {
00225 resultRep = GLC_3DRep(*pRep);
00226 resultRep.setName(pStructRef->name());
00227 }
00228 }
00229 delete pStructRef;
00230 }
00231 }
00232 }
00233 else if (QFileInfo(m_CurrentFileName).suffix().toLower() == "3drep")
00234 {
00235 if (GLC_State::cacheIsUsed() && GLC_State::currentCacheManager().isUsable(m_CurrentDateTime, QFileInfo(m_FileName).baseName(), QFileInfo(m_CurrentFileName).fileName()))
00236 {
00237 GLC_CacheManager cacheManager = GLC_State::currentCacheManager();
00238 GLC_BSRep binaryRep = cacheManager.binary3DRep(QFileInfo(m_FileName).baseName(), QFileInfo(m_CurrentFileName).fileName());
00239 resultRep = binaryRep.loadRep();
00240 }
00241 else
00242 {
00243 if (setStreamReaderToFile(m_CurrentFileName, true))
00244 {
00245 resultRep = loadCurrentExtRep();
00246 }
00247 }
00248 }
00249 resultRep.clean();
00250
00251 return resultRep;
00252 }
00253
00255
00257
00258 void GLC_3dxmlToWorld::loadManifest()
00259 {
00260 setStreamReaderToFile("Manifest.xml");
00261 m_RootName= getContent(m_pStreamReader, "Root");
00262
00263 if (m_pStreamReader->atEnd() || m_pStreamReader->hasError())
00264 {
00265 QString message(QString("GLC_3dxmlToWorld::loadManifest Manifest file ") + m_FileName + " doesn't contains Root Element");
00266 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
00267 clear();
00268 throw(fileFormatException);
00269 }
00270
00271 delete m_pStreamReader;
00272 m_pStreamReader= NULL;
00273 }
00274
00276 void GLC_3dxmlToWorld::clear()
00277 {
00278 delete m_pWorld;
00279 m_pWorld= NULL;
00280
00281 delete m_pStreamReader;
00282 m_pStreamReader= NULL;
00283
00284 m_ByteArrayList.clear();
00285
00286 if (NULL != m_pCurrentFile)
00287 {
00288 m_pCurrentFile->close();
00289 delete m_pCurrentFile;
00290 m_pCurrentFile= NULL;
00291 }
00292
00293
00294 if (NULL != m_p3dxmlArchive)
00295 {
00296 m_p3dxmlArchive->close();
00297 delete m_p3dxmlArchive;
00298 m_p3dxmlArchive= NULL;
00299 }
00300
00301 m_SetOfAttachedFileName.clear();
00302
00303 clearMaterialHash();
00304 }
00305
00306
00307 void GLC_3dxmlToWorld::goToRepId(const QString& id)
00308 {
00309 while(!m_pStreamReader->atEnd() && !((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "Representation")
00310 && (m_pStreamReader->attributes().value("id").toString() == id)))
00311 {
00312 readNext();;
00313 }
00314
00315 }
00316
00317
00318 void GLC_3dxmlToWorld::gotToPolygonalRepType()
00319 {
00320 while(endElementNotReached(m_pStreamReader, "Representation") && !m_pStreamReader->atEnd() && !((QXmlStreamReader::StartElement == m_pStreamReader->tokenType())
00321 && ((m_pStreamReader->name() == "Rep") || (m_pStreamReader->name() == "Root"))
00322 && (m_pStreamReader->attributes().value("xsi:type").toString() == "PolygonalRepType")))
00323 {
00324
00325
00326 readNext();;
00327 }
00328
00329 }
00330
00331
00332 QString GLC_3dxmlToWorld::readAttribute(const QString& name, bool required)
00333 {
00334 QString attributeValue;
00335 if (required && !m_pStreamReader->attributes().hasAttribute(name))
00336 {
00337 QString message(QString("required attribute ") + name + QString(" Not found"));
00338 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
00339 clear();
00340 throw(fileFormatException);
00341 }
00342 else
00343 {
00344 attributeValue= m_pStreamReader->attributes().value(name).toString();
00345 }
00346 return attributeValue;
00347 }
00348
00349
00350 void GLC_3dxmlToWorld::loadProductStructure()
00351 {
00352 setStreamReaderToFile(m_RootName);
00353 goToElement(m_pStreamReader, "ProductStructure");
00354 if (m_pStreamReader->atEnd() || m_pStreamReader->hasError())
00355 {
00356 QString message(QString("GLC_3dxmlToWorld::loadProductStructure Element ProctStructure Not found in ") + m_FileName);
00357 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
00358 clear();
00359 throw(fileFormatException);
00360 }
00361
00362
00363 while(endElementNotReached(m_pStreamReader, "ProductStructure"))
00364 {
00365 if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType())
00366 && ((m_pStreamReader->name() == "Reference3D") || (m_pStreamReader->name() == "Instance3D")
00367 || (m_pStreamReader->name() == "ReferenceRep") || (m_pStreamReader->name() == "InstanceRep")))
00368 {
00369 if (m_pStreamReader->name() == "Reference3D") loadReference3D();
00370 else if (m_pStreamReader->name() == "Instance3D") loadInstance3D();
00371 else if (m_pStreamReader->name() == "ReferenceRep") loadReferenceRep();
00372 else loadInstanceRep();
00373 }
00374
00375 readNext();;
00376 }
00377
00378
00379 while(endElementNotReached(m_pStreamReader, "Model_3dxml"))
00380 {
00381 if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType())
00382 && ((m_pStreamReader->name() == "DefaultView") || (m_pStreamReader->name() == "GeometricRepresentationSet")))
00383 {
00384 if (m_pStreamReader->name() == "DefaultView") loadGraphicsProperties();
00385 else if (m_pStreamReader->name() == "GeometricRepresentationSet") loadLocalRepresentations();
00386
00387 }
00388 readNext();;
00389 }
00390
00391
00392 if (m_pStreamReader->hasError())
00393 {
00394 QString message(QString("GLC_3dxmlToWorld::loadProductStructure An error occur in ") + m_FileName);
00395 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
00396 clear();
00397 throw(fileFormatException);
00398 }
00399
00400
00401 loadExternalRef3D();
00402
00403
00404 loadExternRepresentations();
00405
00406 {
00407 InstanceOfHash::iterator iInstance= m_InstanceOf.begin();
00408 while (iInstance != m_InstanceOf.constEnd())
00409 {
00410 GLC_StructInstance* pInstance= iInstance.key();
00411 GLC_StructReference* pRef= m_ReferenceHash.value(iInstance.value());
00412 if (NULL == pRef)
00413 {
00414 QString message(QString("GLC_3dxmlToWorld::loadProductStructure a instance reference a non existing reference"));
00415 message.append(" Instance name " + pInstance->name());
00416 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
00417 clear();
00418 throw(fileFormatException);
00419 }
00420 pInstance->setReference(pRef);
00421
00422 ++iInstance;
00423 }
00424 m_InstanceOf.clear();
00425
00426 }
00427
00428
00429 {
00430
00431 InstanceOfExtRefHash::iterator iInstance= m_InstanceOfExtRefHash.begin();
00432 while (iInstance != m_InstanceOfExtRefHash.constEnd())
00433 {
00434 GLC_StructInstance* pInstance= iInstance.key();
00435 GLC_StructReference* pRef;
00436 if (m_ExternalReferenceHash.contains(iInstance.value()))
00437 {
00438 pRef= m_ExternalReferenceHash.value(iInstance.value());
00439 }
00440 else
00441 {
00442 QString referenceName= pInstance->name();
00443 referenceName= referenceName.left(pInstance->name().lastIndexOf('.'));
00444 QStringList stringList(m_FileName);
00445 stringList.append("Reference not found : " + referenceName);
00446 GLC_ErrorLog::addError(stringList);
00447 pRef= new GLC_StructReference(referenceName);
00448 }
00449
00450 pInstance->setReference(pRef);
00451
00452 ++iInstance;
00453 }
00454
00455
00456 ExternalReferenceHash::const_iterator iRef= m_ExternalReferenceHash.constBegin();
00457 while (m_ExternalReferenceHash.constEnd() != iRef)
00458 {
00459 GLC_StructReference* pRef= iRef.value();
00460 if (! pRef->hasStructInstance())
00461 {
00462 QStringList stringList(m_FileName);
00463 stringList.append("Orphan reference : " + pRef->name());
00464 GLC_ErrorLog::addError(stringList);
00465 delete pRef;
00466 }
00467 ++iRef;
00468 }
00469 m_ExternalReferenceHash.clear();
00470
00471 }
00472
00473
00474
00475 createUnfoldedTree();
00476
00477
00478 m_pWorld->rootOccurence()->updateOccurenceNumber(1);
00479
00480
00481 if (! m_OccurenceAttrib.isEmpty())
00482 {
00483
00484 QList<GLC_StructOccurence*> occurenceList= m_pWorld->listOfOccurence();
00485 const int size= occurenceList.size();
00486 for (int i= 0; i < size; ++i)
00487 {
00488 if (m_OccurenceAttrib.contains(occurenceList.at(i)->occurenceNumber()))
00489 {
00490 OccurenceAttrib* pOccurenceAttrib= m_OccurenceAttrib.value(occurenceList.at(i)->occurenceNumber());
00491 occurenceList.at(i)->setVisibility(pOccurenceAttrib->m_IsVisible);
00492 if (NULL != pOccurenceAttrib->m_pRenderProperties)
00493 {
00494 occurenceList.at(i)->setRenderProperties(*(pOccurenceAttrib->m_pRenderProperties));
00495 }
00496 }
00497 }
00498 }
00499
00500 InstanceOfExtRefHash::const_iterator iInstance= m_InstanceOfExtRefHash.constBegin();
00501 while (m_InstanceOfExtRefHash.constEnd() != iInstance)
00502 {
00503 GLC_StructInstance* pInstance= iInstance.key();
00504 if (!pInstance->hasStructOccurence())
00505 {
00506 QStringList stringList(m_FileName);
00507 stringList.append("Orphan Instance : " + pInstance->name());
00508 GLC_ErrorLog::addError(stringList);
00509 delete pInstance;
00510 }
00511 else
00512 {
00513 QList<GLC_StructOccurence*> occurences= pInstance->listOfStructOccurences();
00514 const int size= occurences.size();
00515 for (int i= 0; i < size; ++i)
00516 {
00517 const GLC_StructOccurence* pOccurence= occurences.at(i);
00518 if (pOccurence->isOrphan())
00519 {
00520 QStringList stringList(m_FileName);
00521 stringList.append("Orphan occurence : " + pOccurence->name());
00522 GLC_ErrorLog::addError(stringList);
00523 delete pOccurence;
00524 }
00525 }
00526 }
00527 ++iInstance;
00528 }
00529
00530 m_InstanceOfExtRefHash.clear();
00531
00532
00533
00534
00535 }
00536
00537
00538 void GLC_3dxmlToWorld::loadReference3D()
00539 {
00540 const unsigned int id= readAttribute("id", true).toUInt();
00541 const QString refName(readAttribute("name", true));
00542 GLC_StructReference* pStructReference;
00543
00544 if (id == 1)
00545 {
00546 m_pWorld->setRootName(refName);
00547 pStructReference= m_pWorld->rootOccurence()->structInstance()->structReference();
00548 pStructReference->setName(refName);
00549 }
00550 else
00551 {
00552 pStructReference= new GLC_StructReference(refName);
00553 }
00554
00555 GLC_Attributes userAttributes;
00556 while (endElementNotReached(m_pStreamReader, "Reference3D"))
00557 {
00558 if (m_pStreamReader->isStartElement() && (m_pStreamReader->name() == "Reference3DExtensionType"))
00559 {
00560 while (endElementNotReached(m_pStreamReader, "Reference3DExtensionType"))
00561 {
00562 if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "Attribute"))
00563 {
00564 QString name= readAttribute("name", true);
00565 QString value= readAttribute("value", true);
00566 if (name == "FILEPATH" && QDir(value).isRelative())
00567 {
00568 value= QFileInfo(m_FileName).absolutePath() + QDir::separator() + value;
00569 }
00570 userAttributes.insert(name, value);
00571 }
00572 readNext();;
00573 }
00574 }
00575 readNext();;
00576 }
00577 if (!userAttributes.isEmpty())
00578 {
00579 pStructReference->setAttributes(userAttributes);
00580 }
00581
00582 m_ReferenceHash.insert(id, pStructReference);
00583 }
00584
00585
00586 void GLC_3dxmlToWorld::loadInstance3D()
00587 {
00588 const QString local= "urn:3DXML:Reference:loc:";
00589 const QString externRef= "urn:3DXML:Reference:ext:";
00590
00591 const unsigned int instanceId= readAttribute("id", true).toUInt();
00592 const QString instName(readAttribute("name", false));
00593 const unsigned int aggregatedById= getContent(m_pStreamReader, "IsAggregatedBy").toUInt();
00594 QString instanceOf= getContent(m_pStreamReader, "IsInstanceOf");
00595 const QString matrixString= getContent(m_pStreamReader, "RelativeMatrix");
00596 GLC_Matrix4x4 instanceMatrix= loadMatrix(matrixString);
00597
00598
00599 GLC_StructInstance* pStructInstance= new GLC_StructInstance(instName);
00600 pStructInstance->move(instanceMatrix);
00601
00602
00603 GLC_Attributes userAttributes;
00604 while (endElementNotReached(m_pStreamReader, "Instance3D"))
00605 {
00606 if (m_pStreamReader->isStartElement() && (m_pStreamReader->name() == "Instance3DExtensionType"))
00607 {
00608 while (endElementNotReached(m_pStreamReader, "Instance3DExtensionType"))
00609 {
00610 if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "Attribute"))
00611 {
00612 QString name= readAttribute("name", true);
00613 QString value= readAttribute("value", true);
00614 userAttributes.insert(name, value);
00615 }
00616 readNext();;
00617 }
00618 }
00619 readNext();;
00620 }
00621 if (!userAttributes.isEmpty())
00622 {
00623 pStructInstance->setAttributes(userAttributes);
00624 }
00625 if (instanceOf.contains(externRef))
00626 {
00627
00628 const QString extRefId= instanceOf.remove(externRef).remove("#1");
00629 m_SetOfExtRef << extRefId;
00630 m_InstanceOfExtRefHash.insert(pStructInstance, extRefId);
00631 }
00632 else if (instanceOf.contains(local))
00633 {
00634 const unsigned int refId= instanceOf.remove(local).toUInt();
00635 m_InstanceOf.insert(pStructInstance, refId);
00636 }
00637 else
00638 {
00639
00640 const unsigned int refId= instanceOf.toUInt();
00641 m_InstanceOf.insert(pStructInstance, refId);
00642 }
00643
00644 AssyLink assyLink;
00645 assyLink.m_ParentRefId= aggregatedById;
00646 assyLink.m_pChildInstance= pStructInstance;
00647 assyLink.m_InstanceId= instanceId;
00648 m_AssyLinkList.append(assyLink);
00649 }
00650
00651
00652 void GLC_3dxmlToWorld::loadReferenceRep()
00653 {
00654 const QString local= "urn:3DXML:Representation:loc:";
00655 const QString externName= "urn:3DXML:";
00656
00657 const unsigned int id= readAttribute("id", true).toUInt();
00658
00659 const QString format= readAttribute("format", false);
00660 QString associatedFile(readAttribute("associatedFile", true));
00661 if (format == "TESSELLATED")
00662 {
00663 if (associatedFile.contains(local))
00664 {
00665 const QString repId= associatedFile.remove(local);
00666 m_ReferenceRepHash.insert(id, repId);
00667 }
00668 else if (associatedFile.contains(externName))
00669 {
00670 const QString repId= associatedFile.remove(externName);
00671 m_ReferenceRepHash.insert(id, repId);
00672 }
00673 }
00674 else if (format == "UVR")
00675 {
00676 QString message(QString("GLC_3dxmlToWorld::loadReferenceRep in file ") + m_CurrentFileName + " format " + format + " not supported");
00677 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotSupported);
00678 clear();
00679 throw(fileFormatException);
00680
00681 }
00682 }
00683
00684
00685 void GLC_3dxmlToWorld::loadInstanceRep()
00686 {
00687 const QString local= "urn:3DXML:Reference:loc:";
00688
00689
00690 const unsigned int aggregatedById= getContent(m_pStreamReader, "IsAggregatedBy").toUInt();
00691 QString instanceOf= getContent(m_pStreamReader, "IsInstanceOf");
00692
00693 if (instanceOf.contains(local))
00694 {
00695
00696 const unsigned int refId= instanceOf.remove(local).toUInt();
00697
00698 RepLink repLink;
00699 repLink.m_ReferenceId= aggregatedById;
00700 repLink.m_RepId= refId;
00701
00702 m_LocalRepLinkList.append(repLink);
00703 }
00704 else
00705 {
00706
00707 const unsigned int refId= instanceOf.toUInt();
00708 RepLink repLink;
00709 repLink.m_ReferenceId= aggregatedById;
00710 repLink.m_RepId= refId;
00711
00712 m_ExternRepLinkList.append(repLink);
00713 }
00714 }
00715
00716
00717 void GLC_3dxmlToWorld::loadExternalRef3D()
00718 {
00719 if (m_SetOfExtRef.isEmpty()) return;
00720
00721 const int size= m_SetOfExtRef.size();
00722 int previousQuantumValue= 0;
00723 int currentQuantumValue= 0;
00724 int currentFileIndex= 0;
00725 emit currentQuantum(currentQuantumValue);
00726
00727 SetOfExtRef::iterator iExtRef= m_SetOfExtRef.begin();
00728 while (iExtRef != m_SetOfExtRef.constEnd())
00729 {
00730
00731 m_CurrentFileName= (*iExtRef);
00732
00733 if (! m_IsInArchive)
00734 {
00735
00736 m_CurrentDateTime= QFileInfo(QFileInfo(m_FileName).absolutePath() + QDir::separator() + QFileInfo(m_CurrentFileName).fileName()).lastModified();
00737 }
00738
00739 if (!m_LoadStructureOnly && GLC_State::cacheIsUsed() && GLC_State::currentCacheManager().isUsable(m_CurrentDateTime, QFileInfo(m_FileName).baseName(), m_CurrentFileName))
00740 {
00741 GLC_CacheManager cacheManager= GLC_State::currentCacheManager();
00742
00743 GLC_BSRep binaryRep= cacheManager.binary3DRep(QFileInfo(m_FileName).baseName(), m_CurrentFileName);
00744 GLC_3DRep* pRep= new GLC_3DRep(binaryRep.loadRep());
00745
00746 setRepresentationFileName(pRep);
00747 factorizeMaterial(pRep);
00748
00749 GLC_StructReference* pCurrentRef= new GLC_StructReference(pRep);
00750 pCurrentRef->setName(QFileInfo(m_CurrentFileName).baseName());
00751 m_ExternalReferenceHash.insert(m_CurrentFileName, pCurrentRef);
00752
00753 }
00754 else if (!m_LoadStructureOnly && setStreamReaderToFile(m_CurrentFileName))
00755 {
00756
00757
00758 const QString localFileName= m_CurrentFileName;
00759
00760 GLC_StructReference* pCurrentRef= createReferenceRep(QString(), NULL);
00761 if (NULL != pCurrentRef)
00762 {
00763 m_ExternalReferenceHash.insert(localFileName, pCurrentRef);
00764 }
00765 else
00766 {
00767 QStringList stringList(m_FileName);
00768 stringList.append("GLC_3dxmlToWorld::loadExternalRef3D");
00769 stringList.append("Failed to load " + m_CurrentFileName);
00770 GLC_ErrorLog::addError(stringList);
00771 }
00772 }
00773 else if(m_LoadStructureOnly)
00774 {
00775 GLC_3DRep* pRep= new GLC_3DRep();
00776 if (m_IsInArchive)
00777 {
00778 pRep->setFileName(glc::builtArchiveString(m_FileName, m_CurrentFileName));
00779 }
00780 else
00781 {
00782 const QString repFileName= glc::builtFileString(m_FileName, m_CurrentFileName);
00783 pRep->setFileName(repFileName);
00784 m_SetOfAttachedFileName << glc::archiveEntryFileName(repFileName);
00785 }
00786
00787 if (m_GetExternalRef3DName && setStreamReaderToFile(m_CurrentFileName))
00788 {
00789 const QString localFileName= m_CurrentFileName;
00790 GLC_StructReference* pCurrentRef= createReferenceRep(QString(), pRep);
00791 m_ExternalReferenceHash.insert(localFileName, pCurrentRef);
00792 }
00793 else
00794 {
00795 GLC_StructReference* pCurrentRef= new GLC_StructReference(pRep);
00796 pCurrentRef->setName(QFileInfo(m_CurrentFileName).baseName());
00797 m_ExternalReferenceHash.insert(m_CurrentFileName, pCurrentRef);
00798 }
00799 }
00800 else
00801 {
00802 qDebug() << "GLC_3dxmlToWorld::loadExternalRef3D No File Found";
00803 }
00804
00805 ++currentFileIndex;
00806
00807 currentQuantumValue = static_cast<int>((static_cast<double>(currentFileIndex) / size) * 100);
00808 if (currentQuantumValue > previousQuantumValue)
00809 {
00810 emit currentQuantum(currentQuantumValue);
00811 }
00812 previousQuantumValue= currentQuantumValue;
00813
00814 ++iExtRef;
00815 }
00816 m_SetOfExtRef.clear();
00817
00818 }
00819
00820
00821 GLC_StructReference* GLC_3dxmlToWorld::createReferenceRep(QString repId, GLC_3DRep* pRep)
00822 {
00823
00824
00825 QString refName;
00826
00827 if (repId.isEmpty())
00828 {
00829 goToElement(m_pStreamReader, "ProductStructure");
00830 checkForXmlError("Element ProductStructure not found");
00831
00832 goToElement(m_pStreamReader, "Reference3D");
00833 checkForXmlError("Element Reference3D not found");
00834 refName= readAttribute("name", true);
00835
00836 if (pRep != NULL)
00837 {
00838 pRep->setName(refName);
00839 return new GLC_StructReference(pRep);
00840 }
00841
00842 goToElement(m_pStreamReader, "ReferenceRep");
00843 if (m_pStreamReader->atEnd())
00844 {
00845 QStringList stringList(m_FileName);
00846 stringList.append("Element ReferenceRep not found in file " + m_CurrentFileName);
00847 GLC_ErrorLog::addError(stringList);
00848 return NULL;
00849 }
00850 checkForXmlError("Element ReferenceRep contains error");
00851
00852 const QString format(readAttribute("format", true));
00853 if (format != "TESSELLATED")
00854 {
00855 QString message(QString("GLC_3dxmlToWorld::addExtenalRef 3D rep format ") + format + " Not Supported");
00856 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::FileNotSupported);
00857 clear();
00858 throw(fileFormatException);
00859 }
00860
00861 repId= readAttribute("associatedFile");
00862
00863 const QString local= "urn:3DXML:Representation:loc:";
00864 const QString ext= "urn:3DXML:Representation:ext:";
00865 if (repId.contains(ext))
00866 {
00867 repId.remove(ext);
00868 repId.resize(repId.size() - 2);
00869 if (setStreamReaderToFile(repId))
00870 {
00871 return createReferenceRep(QString(), NULL);
00872 }
00873 else
00874 {
00875 return NULL;
00876 }
00877 }
00878 else
00879 {
00880 repId.remove(local);
00881 }
00882
00883 checkForXmlError("attribute associatedFile not found");
00884 goToRepId(repId);
00885 checkForXmlError("repId not found");
00886 }
00887
00888 GLC_Mesh* pMesh= new GLC_Mesh();
00889 pMesh->setName(refName);
00890 GLC_3DRep currentMesh3DRep(pMesh);
00891
00892
00893 if (repId.contains("3DXML_Local_"))
00894 {
00895 QString saveCurrentFileName= m_CurrentFileName;
00896 m_CurrentFileName= repId;
00897 setRepresentationFileName(¤tMesh3DRep);
00898 m_CurrentFileName= saveCurrentFileName;
00899 }
00900 else
00901 {
00902 setRepresentationFileName(¤tMesh3DRep);
00903 }
00904
00905 currentMesh3DRep.setLastModified(m_CurrentDateTime);
00906
00907 int numberOfMesh= 1;
00908 while (endElementNotReached(m_pStreamReader, "Representation"))
00909 {
00910 gotToPolygonalRepType();
00911 if (!endElementNotReached(m_pStreamReader, "Representation") || m_pStreamReader->atEnd() || m_pStreamReader->hasError())
00912 {
00913 if (m_pStreamReader->hasError() || m_pStreamReader->atEnd())
00914 {
00915 QString message(QString("An element have not been found in file ") + m_FileName);
00916 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
00917 clear();
00918 throw(fileFormatException);
00919 }
00920 else
00921 {
00922 pMesh->finish();
00923 currentMesh3DRep.clean();
00924 if (!currentMesh3DRep.isEmpty())
00925 {
00926 if (GLC_State::cacheIsUsed())
00927 {
00928 GLC_CacheManager currentManager= GLC_State::currentCacheManager();
00929 if (!currentManager.addToCache(QFileInfo(m_FileName).baseName(), currentMesh3DRep))
00930 {
00931 QStringList stringList("GLC_3dxmlToWorld::createReferenceRep");
00932 stringList.append(m_FileName);
00933 stringList.append("File " + currentMesh3DRep.fileName() + " Not Added to cache");
00934 GLC_ErrorLog::addError(stringList);
00935 }
00936 }
00937
00938 return new GLC_StructReference(new GLC_3DRep(currentMesh3DRep));
00939 }
00940 else
00941 {
00942 return new GLC_StructReference("Empty Rep");
00943 }
00944 }
00945 }
00946 if (numberOfMesh > 1)
00947 {
00948 pMesh->finish();
00949 pMesh = new GLC_Mesh();
00950 pMesh->setName(refName);
00951 currentMesh3DRep.addGeom(pMesh);
00952 }
00953
00954
00955 double masterLodAccuracy= readAttribute("accuracy", false).toDouble();
00956
00957 loadLOD(pMesh);
00958 if (m_pStreamReader->atEnd() || m_pStreamReader->hasError())
00959 {
00960 QStringList stringList(m_FileName);
00961 stringList.append(m_CurrentFileName);
00962 stringList.append("Master LOD not found");
00963 GLC_ErrorLog::addError(stringList);
00964 return new GLC_StructReference("Empty Rep");
00965 }
00966
00967
00968 while (endElementNotReached(m_pStreamReader, "Faces"))
00969 {
00970 readNext();;
00971 if ( m_pStreamReader->name() == "Face")
00972 {
00973 loadFace(pMesh, 0, masterLodAccuracy);
00974 }
00975 }
00976 checkForXmlError("End of Faces not found");
00977
00978 while (startElementNotReached(m_pStreamReader, "Edges") && startElementNotReached(m_pStreamReader, "VertexBuffer"))
00979 {
00980 readNext();;
00981 }
00982
00983 checkForXmlError("Element VertexBuffer not found");
00984 if (m_pStreamReader->name() == "Edges")
00985 {
00986 while (endElementNotReached(m_pStreamReader, "Edges"))
00987 {
00988 readNext();;
00989 if ( m_pStreamReader->name() == "Polyline")
00990 {
00991 loadPolyline(pMesh);
00992 readNext();;
00993 }
00994 }
00995 }
00996
00997
00998 {
00999 QString verticePosition= getContent(m_pStreamReader, "Positions").replace(',', ' ');
01000
01001 checkForXmlError("Error while retrieving Position ContentVertexBuffer");
01002
01003 QTextStream verticeStream(&verticePosition);
01004 QList<GLfloat> verticeValues;
01005 QString buff;
01006 while ((!verticeStream.atEnd()))
01007 {
01008 verticeStream >> buff;
01009 verticeValues.append(buff.toFloat());
01010 }
01011 pMesh->addVertice(verticeValues.toVector());
01012
01013 }
01014
01015 {
01016 QString normals= getContent(m_pStreamReader, "Normals").replace(',', ' ');
01017
01018 checkForXmlError("Error while retrieving Normals values");
01019
01020 QTextStream normalsStream(&normals);
01021 QList<GLfloat> normalValues;
01022 QString buff;
01023 while ((!normalsStream.atEnd()))
01024 {
01025 normalsStream >> buff;
01026 normalValues.append(buff.toFloat());
01027 }
01028 pMesh->addNormals(normalValues.toVector());
01029 }
01030
01031
01032 while (endElementNotReached(m_pStreamReader, "VertexBuffer"))
01033 {
01034
01035 if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "TextureCoordinates"))
01036 {
01037 QString texels= getContent(m_pStreamReader, "TextureCoordinates").replace(',', ' ');
01038 checkForXmlError("Error while retrieving Texture coordinates");
01039 QTextStream texelStream(&texels);
01040 QList<GLfloat> texelValues;
01041 QString buff;
01042 while ((!texelStream.atEnd()))
01043 {
01044 texelStream >> buff;
01045 texelValues.append(buff.toFloat());
01046 }
01047 pMesh->addTexels(texelValues.toVector());
01048 }
01049 readNext();;
01050 }
01051
01052 ++numberOfMesh;
01053 }
01054
01055 pMesh->finish();
01056
01057 currentMesh3DRep.clean();
01058 if (!currentMesh3DRep.isEmpty())
01059 {
01060 if (GLC_State::cacheIsUsed())
01061 {
01062 GLC_CacheManager currentManager= GLC_State::currentCacheManager();
01063 currentManager.addToCache(QFileInfo(m_FileName).baseName(), currentMesh3DRep);
01064 }
01065
01066 return new GLC_StructReference(new GLC_3DRep(currentMesh3DRep));
01067 }
01068 else
01069 {
01070 return new GLC_StructReference("Empty Rep");
01071 }
01072 }
01073
01074
01075 GLC_Matrix4x4 GLC_3dxmlToWorld::loadMatrix(const QString& stringMatrix)
01076 {
01077
01078 QStringList stringValues(stringMatrix.split(" "));
01079
01080 if (stringValues.size() != 12) return GLC_Matrix4x4();
01081
01082 QVector<double> values(16);
01083
01084 values[0]= stringValues[0].toDouble();
01085 values[1]= stringValues[1].toDouble();
01086 values[2]= stringValues[2].toDouble();
01087 values[3]= 0.0;
01088 values[4]= stringValues[3].toDouble();
01089 values[5]= stringValues[4].toDouble();
01090 values[6]= stringValues[5].toDouble();
01091 values[7]= 0.0;
01092 values[8]= stringValues[6].toDouble();
01093 values[9]= stringValues[7].toDouble();
01094 values[10]= stringValues[8].toDouble();
01095 values[11]= 0.0;
01096
01097 values[12]= stringValues[9].toDouble();
01098 values[13]= stringValues[10].toDouble();
01099 values[14]= stringValues[11].toDouble();
01100 values[15]= 1.0;
01101
01102 GLC_Matrix4x4 resultMatrix(values.data());
01103 resultMatrix.optimise();
01104
01105 return resultMatrix;
01106 }
01107
01108
01109 void GLC_3dxmlToWorld::createUnfoldedTree()
01110 {
01111
01112
01113
01114 qSort(m_AssyLinkList.begin(), m_AssyLinkList.end());
01115 AssyLinkList::iterator iLink= m_AssyLinkList.begin();
01116 while(iLink != m_AssyLinkList.constEnd())
01117 {
01118 GLC_StructInstance* pChildInstance= (*iLink).m_pChildInstance;
01119 if (pChildInstance->structReference() == NULL)
01120 {
01121 QStringList stringList(m_FileName);
01122 stringList.append("Instance without reference");
01123 GLC_ErrorLog::addError(stringList);
01124 pChildInstance->setReference(new GLC_StructReference("Part"));
01125 }
01126 Q_ASSERT(m_ReferenceHash.contains((*iLink).m_ParentRefId));
01127 GLC_StructReference* pRef= m_ReferenceHash.value((*iLink).m_ParentRefId);
01128
01129 QList<GLC_StructInstance*> instanceList= pRef->listOfStructInstances();
01130 const int instanceNumber= instanceList.size();
01131 for (int i= 0; i < instanceNumber; ++i)
01132 {
01133 if (instanceList.at(i)->hasStructOccurence())
01134 {
01135 QList<GLC_StructOccurence*> occurenceList= instanceList.at(i)->listOfStructOccurences();
01136 const int occurenceNumber= occurenceList.size();
01137 for (int j= 0; j < occurenceNumber; ++j)
01138 {
01139 if (pChildInstance->hasStructOccurence() && pChildInstance->firstOccurenceHandle()->isOrphan())
01140 {
01141 Q_ASSERT(pChildInstance->listOfStructOccurences().size() == 1);
01142 occurenceList.at(j)->addChild(pChildInstance->firstOccurenceHandle());
01143 }
01144 else
01145 {
01146 occurenceList.at(j)->addChild(pChildInstance);
01147 }
01148 }
01149 }
01150 else
01151 {
01152 GLC_StructOccurence* pOccurence= new GLC_StructOccurence(instanceList.at(i), m_pWorld->worldHandle());
01153 if (pChildInstance->hasStructOccurence() && pChildInstance->firstOccurenceHandle()->isOrphan())
01154 {
01155 Q_ASSERT(pChildInstance->listOfStructOccurences().size() == 1);
01156 pOccurence->addChild(pChildInstance->firstOccurenceHandle());
01157 }
01158 else
01159 {
01160 pOccurence->addChild(pChildInstance);
01161 }
01162 }
01163 }
01164
01165 ++iLink;
01166 }
01167
01168 m_AssyLinkList.clear();
01169
01170
01171 ReferenceHash::const_iterator iRef= m_ReferenceHash.constBegin();
01172 while (m_ReferenceHash.constEnd() != iRef)
01173 {
01174 if (iRef.key() != 1)
01175 {
01176 GLC_StructReference* pReference= iRef.value();
01177 if (!pReference->hasStructInstance())
01178 {
01179 QStringList stringList(m_FileName);
01180 stringList.append("GLC_3dxmlToWorld::createUnfoldedTree() : Orphan reference: " + pReference->name());
01181 GLC_ErrorLog::addError(stringList);
01182 delete pReference;
01183 }
01184 else
01185 {
01186 QList<GLC_StructInstance*> instances= pReference->listOfStructInstances();
01187 const int size= instances.size();
01188 for (int i= 0; i < size; ++i)
01189 {
01190 GLC_StructInstance* pInstance= instances.at(i);
01191 if (!pInstance->hasStructOccurence())
01192 {
01193 QStringList stringList(m_FileName);
01194 stringList.append("GLC_3dxmlToWorld::createUnfoldedTree() : Orphan Instance: " + pInstance->name());
01195 GLC_ErrorLog::addError(stringList);
01196 delete pInstance;
01197 }
01198 else
01199 {
01200 QList<GLC_StructOccurence*> occurences= pInstance->listOfStructOccurences();
01201 const int occurencesSize= occurences.size();
01202 for (int j= 0; j < occurencesSize; ++j)
01203 {
01204 GLC_StructOccurence* pOcc= occurences.at(j);
01205 if (pOcc->isOrphan())
01206 {
01207 QStringList stringList(m_FileName);
01208 stringList.append("GLC_3dxmlToWorld::createUnfoldedTree(): Orphan occurence: " + pOcc->name());
01209 GLC_ErrorLog::addError(stringList);
01210 delete pOcc;
01211 }
01212 }
01213 }
01214 }
01215 }
01216 }
01217 ++iRef;
01218 }
01219 m_ReferenceHash.clear();
01220
01221
01222 m_pWorld->rootOccurence()->updateChildrenAbsoluteMatrix();
01223
01224 }
01225
01226 void GLC_3dxmlToWorld::checkForXmlError(const QString& info)
01227 {
01228 if (m_pStreamReader->atEnd() || m_pStreamReader->hasError())
01229 {
01230 QString message(QString("An element have not been found in file ") + m_CurrentFileName);
01231
01232 QStringList stringList(info + " " + m_pStreamReader->errorString());
01233 stringList.append(message);
01234 GLC_ErrorLog::addError(stringList);
01235
01236 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
01237 clear();
01238 throw(fileFormatException);
01239 }
01240 }
01241
01242 void GLC_3dxmlToWorld::loadLOD(GLC_Mesh* pMesh)
01243 {
01244 int lodIndex= 1;
01245 while(!m_pStreamReader->atEnd() && !((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "Faces")))
01246 {
01247 readNext();;
01248 if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "SurfaceAttributes"))
01249 {
01250 m_pCurrentMaterial= loadSurfaceAttributes();
01251 }
01252 else if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "PolygonalLOD"))
01253 {
01254 double accuracy= readAttribute("accuracy", true).toDouble();
01255
01256 while (endElementNotReached(m_pStreamReader, "Faces"))
01257 {
01258 readNext();;
01259 if ( m_pStreamReader->name() == "Face")
01260 {
01261 loadFace(pMesh, lodIndex, accuracy);
01262 }
01263 }
01264 checkForXmlError("End of Faces not found");
01265 ++lodIndex;
01266 }
01267 }
01268 }
01269
01270 void GLC_3dxmlToWorld::loadFace(GLC_Mesh* pMesh, const int lod, double accuracy)
01271 {
01272
01273
01274 QString triangles= readAttribute("triangles", false).trimmed();
01275 QString strips= readAttribute("strips", false).trimmed();
01276 QString fans= readAttribute("fans", false).trimmed();
01277
01278 if (triangles.isEmpty() && strips.isEmpty() && fans.isEmpty())
01279 {
01280 QStringList stringList(m_CurrentFileName);
01281 stringList.append("GLC_3dxmlToWorld::loadFace : Empty face found");
01282 GLC_ErrorLog::addError(stringList);
01283 return;
01284 }
01285
01286 GLC_Material* pCurrentMaterial= NULL;
01287
01288 while(endElementNotReached(m_pStreamReader, "Face"))
01289 {
01290 if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "SurfaceAttributes"))
01291 {
01292 pCurrentMaterial= loadSurfaceAttributes();
01293 }
01294 readNext();;
01295 }
01296 if (NULL == pCurrentMaterial)
01297 {
01298 pCurrentMaterial= m_pCurrentMaterial;
01299 }
01300
01301
01302 if (!triangles.isEmpty())
01303 {
01304
01305 if (triangles.contains(','))
01306 {
01307 triangles.remove(',');
01308 }
01309 QTextStream trianglesStream(&triangles);
01310 IndexList trianglesIndex;
01311 QString buff;
01312 while ((!trianglesStream.atEnd()))
01313 {
01314 trianglesStream >> buff;
01315 trianglesIndex.append(buff.toUInt());
01316 }
01317 pMesh->addTriangles(pCurrentMaterial, trianglesIndex, lod, accuracy);
01318 }
01319
01320 if (!strips.isEmpty())
01321 {
01322
01323 QStringList stripsList(strips.split(","));
01324 const int size= stripsList.size();
01325 for (int i= 0; i < size; ++i)
01326 {
01327
01328 QTextStream stripsStream(&stripsList[i]);
01329 IndexList stripsIndex;
01330 QString buff;
01331 while ((!stripsStream.atEnd()))
01332 {
01333 stripsStream >> buff;
01334 stripsIndex.append(buff.toUInt());
01335 }
01336 pMesh->addTrianglesStrip(pCurrentMaterial, stripsIndex, lod, accuracy);
01337 }
01338 }
01339
01340 if (!fans.isEmpty())
01341 {
01342 QStringList fansList(fans.split(","));
01343 const int size= fansList.size();
01344 for (int i= 0; i < size; ++i)
01345 {
01346 QTextStream fansStream(&fansList[i]);
01347 IndexList fansIndex;
01348 QString buff;
01349 while ((!fansStream.atEnd()))
01350 {
01351 fansStream >> buff;
01352 fansIndex.append(buff.toUInt());
01353 }
01354 pMesh->addTrianglesFan(pCurrentMaterial, fansIndex, lod, accuracy);
01355 }
01356 }
01357
01358 }
01359
01360
01361 void GLC_3dxmlToWorld::loadPolyline(GLC_Mesh* pMesh)
01362 {
01363 QString data= readAttribute("vertices", true);
01364
01365 data.replace(',', ' ');
01366 QTextStream dataStream(&data);
01367 GLfloatVector dataVector;
01368 QString buff;
01369 while ((!dataStream.atEnd()))
01370 {
01371 dataStream >> buff;
01372 dataVector.append(buff.toFloat());
01373 }
01374 pMesh->addVerticeGroup(dataVector);
01375 }
01376
01377
01378 void GLC_3dxmlToWorld::clearMaterialHash()
01379 {
01380 MaterialHash::iterator iMaterial= m_MaterialHash.begin();
01381 while (m_MaterialHash.constEnd() != iMaterial)
01382 {
01383 if (iMaterial.value()->isUnused())
01384 {
01385 delete iMaterial.value();
01386 }
01387 ++iMaterial;
01388 }
01389
01390 m_MaterialHash.clear();
01391 }
01392
01393 GLC_Material* GLC_3dxmlToWorld::loadSurfaceAttributes()
01394 {
01395 GLC_Material* pMaterial= NULL;
01396 while(endElementNotReached(m_pStreamReader, "SurfaceAttributes"))
01397 {
01398 if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "Color"))
01399 {
01400 pMaterial= getMaterial();
01401 }
01402 else if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "MaterialApplication"))
01403 {
01404 while (endElementNotReached(m_pStreamReader, "MaterialApplication"))
01405 {
01406 readNext();;
01407 if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "MaterialId"))
01408 {
01409 checkForXmlError("Material ID not found");
01410 QString materialId= readAttribute("id", true).remove("urn:3DXML:CATMaterialRef.3dxml#");
01411 pMaterial= m_MaterialHash.value(materialId);
01412 }
01413 }
01414
01415 }
01416 readNext();;
01417 }
01418
01419 return pMaterial;
01420 }
01421
01422 GLC_Material* GLC_3dxmlToWorld::getMaterial()
01423 {
01424 GLC_Material* pMaterial= NULL;
01425 const QString red(readAttribute("red", true));
01426 const QString green(readAttribute("green", true));
01427 const QString blue(readAttribute("blue", true));
01428 const QString alpha(readAttribute("alpha", true));
01429
01430 qreal redReal= red.toDouble();
01431 qreal greenReal= green.toDouble();
01432 qreal blueReal= blue.toDouble();
01433 qreal alphaReal= alpha.toDouble();
01434 QColor diffuse;
01435 diffuse.setRgbF(redReal, greenReal, blueReal);
01436 pMaterial= new GLC_Material(diffuse);
01437 pMaterial->setName("Material_" + QString::number(m_MaterialHash.size()));
01438 pMaterial->setAmbientColor(QColor(50, 50, 50));
01439 pMaterial->setSpecularColor(QColor(70, 70, 70));
01440 pMaterial->setShininess(35.0);
01441 pMaterial->setOpacity(alphaReal);
01442
01443 const QString matKey= QString::number(pMaterial->hashCode());
01444 if (m_MaterialHash.contains(matKey))
01445 {
01446 delete pMaterial;
01447 pMaterial= m_MaterialHash.value(matKey);
01448 }
01449 else
01450 {
01451 m_MaterialHash.insert(matKey, pMaterial);
01452 }
01453
01454 return pMaterial;
01455 }
01456
01457
01458 bool GLC_3dxmlToWorld::setStreamReaderToFile(QString fileName, bool test)
01459 {
01460 m_CurrentFileName= fileName;
01461 if (m_IsInArchive)
01462 {
01463 QMutexLocker locker(&m_ZipMutex);
01464 m_ByteArrayList.clear();
01465
01466 QuaZipFile* p3dxmlFile= new QuaZipFile(m_p3dxmlArchive);
01467
01468
01469 if (!m_p3dxmlArchive->setCurrentFile(fileName, QuaZip::csInsensitive))
01470 {
01471 if (!test)
01472 {
01473 QString message(QString("GLC_3dxmlToWorld::setStreamReaderToFile File ") + m_FileName + " doesn't contains " + fileName);
01474 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
01475 clear();
01476 throw(fileFormatException);
01477 }
01478 else return false;
01479 }
01480
01481
01482 if(!p3dxmlFile->open(QIODevice::ReadOnly))
01483 {
01484 QString message(QString("GLC_3dxmlToWorld::setStreamReaderToFile Unable to Open ") + fileName);
01485 GLC_FileFormatException fileFormatException(message, fileName, GLC_FileFormatException::FileNotSupported);
01486 clear();
01487 throw(fileFormatException);
01488 }
01489
01490
01491 checkFileValidity(p3dxmlFile);
01492 {
01493 delete p3dxmlFile;
01494 p3dxmlFile= new QuaZipFile(m_p3dxmlArchive);
01495 m_p3dxmlArchive->setCurrentFile(fileName, QuaZip::csInsensitive);
01496 p3dxmlFile->open(QIODevice::ReadOnly);
01497 }
01498
01499
01500 delete m_pStreamReader;
01501
01502 QByteArray currentByteArray;
01503 while (!currentByteArray.isEmpty() || m_ByteArrayList.isEmpty())
01504 {
01505 currentByteArray= p3dxmlFile->read(chunckSize);
01506 m_ByteArrayList.append(currentByteArray);
01507 }
01508 m_pStreamReader= new QXmlStreamReader(m_ByteArrayList.takeFirst());
01509 delete p3dxmlFile;
01510 }
01511 else
01512 {
01513 delete m_pCurrentFile;
01514
01515 if (fileName != m_FileName && !m_FileName.isEmpty())
01516 {
01517 fileName= QFileInfo(m_FileName).absolutePath() + QDir::separator() + fileName;
01518 }
01519
01520 m_CurrentDateTime= QFileInfo(fileName).lastModified();
01521
01522 m_pCurrentFile= new QFile(fileName);
01523 if (!m_pCurrentFile->open(QIODevice::ReadOnly))
01524 {
01525 QString message(QString("GLC_3dxmlToWorld::setStreamReaderToFile File ") + fileName + QString(" not found"));
01526 QStringList stringList(message);
01527 GLC_ErrorLog::addError(stringList);
01528 return false;
01529 }
01530 else if (m_FileName != fileName)
01531 {
01532 m_SetOfAttachedFileName << fileName;
01533 }
01534
01535
01536 checkFileValidity(m_pCurrentFile);
01537
01538
01539 delete m_pStreamReader;
01540 m_pStreamReader= new QXmlStreamReader(m_pCurrentFile);
01541 }
01542 return true;
01543 }
01544
01545
01546 void GLC_3dxmlToWorld::loadLocalRepresentations()
01547 {
01548 qDebug() << "GLC_3dxmlToWorld::loadLocalRepresentations()";
01549
01550 if (m_LocalRepLinkList.isEmpty()) return;
01551 QHash<const QString, GLC_3DRep> repHash;
01552
01553
01554 goToElement(m_pStreamReader, "GeometricRepresentationSet");
01555 while (endElementNotReached(m_pStreamReader, "GeometricRepresentationSet"))
01556 {
01557 if (m_pStreamReader->name() == "Representation")
01558 {
01559 QString id= readAttribute("id", true);
01560 GLC_StructReference* pRef= createReferenceRep("3DXML_Local_" + id, NULL);
01561 if (pRef->hasRepresentation())
01562 {
01563 GLC_3DRep representation(*(dynamic_cast<GLC_3DRep*>(pRef->representationHandle())));
01564 repHash.insert(id, representation);
01565 }
01566 delete pRef;
01567 }
01568 readNext();;
01569 }
01570
01571
01572
01573 RepLinkList::iterator iLocalRep= m_LocalRepLinkList.begin();
01574 while (iLocalRep != m_LocalRepLinkList.constEnd())
01575 {
01576 unsigned int referenceId= (*iLocalRep).m_ReferenceId;
01577 unsigned int refId= (*iLocalRep).m_RepId;
01578
01579 GLC_StructReference* pReference= m_ReferenceHash.value(referenceId);
01580 const QString representationID= m_ReferenceRepHash.value(refId);
01581 pReference->setRepresentation(repHash.value(representationID));
01582 pReference->setRepresentationName(pReference->name());
01583
01584 ++iLocalRep;
01585 }
01586 }
01587
01588 void GLC_3dxmlToWorld::loadGraphicsProperties()
01589 {
01590 if (m_pStreamReader->atEnd() || m_pStreamReader->hasError())
01591 {
01592 QString message(QString("GLC_3dxmlToWorld::loadGraphicsProperties Element DefaultView Not found in ") + m_FileName);
01593 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
01594 clear();
01595 throw(fileFormatException);
01596 }
01597
01598
01599 while(endElementNotReached(m_pStreamReader, "DefaultView"))
01600 {
01601 if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "DefaultViewProperty"))
01602 {
01603 loadDefaultViewProperty();
01604 }
01605
01606 readNext();;
01607 }
01608
01609
01610 if (m_pStreamReader->hasError())
01611 {
01612 QString message(QString("GLC_3dxmlToWorld::loadGraphicsProperties An error occur in ") + m_FileName);
01613 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
01614 clear();
01615 throw(fileFormatException);
01616 }
01617
01618 }
01619
01620 void GLC_3dxmlToWorld::loadDefaultViewProperty()
01621 {
01622 goToElement(m_pStreamReader, "OccurenceId");
01623 unsigned int occurenceId= getContent(m_pStreamReader, "OccurenceId").toUInt();
01624
01625
01626 while(endElementNotReached(m_pStreamReader, "DefaultViewProperty"))
01627 {
01628 if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "GraphicProperties"))
01629 {
01630 while(endElementNotReached(m_pStreamReader, "GraphicProperties"))
01631 {
01632 if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "GeneralAttributes"))
01633 {
01634 QString visibleString= readAttribute("visible", true);
01635 if (visibleString != "true")
01636 {
01637 if (!m_OccurenceAttrib.contains(occurenceId))
01638 {
01639 OccurenceAttrib* pOccurenceAttrib= new OccurenceAttrib();
01640 pOccurenceAttrib->m_IsVisible= false;
01641 m_OccurenceAttrib.insert(occurenceId, pOccurenceAttrib);
01642 }
01643 else m_OccurenceAttrib.value(occurenceId)->m_IsVisible= false;
01644 }
01645 }
01646 else if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "SurfaceAttributes"))
01647 {
01648 goToElement(m_pStreamReader, "Color");
01649 const double red= readAttribute("red", true).toDouble();
01650 const double green= readAttribute("green", true).toDouble();
01651 const double blue= readAttribute("blue", true).toDouble();
01652 double alpha= 1.0;
01653 QString alphaString= readAttribute("alpha", false);
01654 if (!alphaString.isEmpty()) alpha= alphaString.toDouble();
01655
01656 GLC_RenderProperties* pRenderProperties= new GLC_RenderProperties();
01657 if (red != -1.0f)
01658 {
01659 QColor diffuseColor;
01660 diffuseColor.setRgbF(red, green, blue, alpha);
01661 GLC_Material* pMaterial= new GLC_Material();
01662 pMaterial->setDiffuseColor(diffuseColor);
01663 pRenderProperties->setOverwriteMaterial(pMaterial);
01664 pRenderProperties->setRenderingMode(glc::OverwriteMaterial);
01665 }
01666 else if (alpha < 1.0f)
01667 {
01668 pRenderProperties->setOverwriteTransparency(static_cast<float>(alpha));
01669 pRenderProperties->setRenderingMode(glc::OverwriteTransparency);
01670 }
01671 if (!m_OccurenceAttrib.contains(occurenceId))
01672 {
01673 OccurenceAttrib* pOccurenceAttrib= new OccurenceAttrib();
01674 pOccurenceAttrib->m_pRenderProperties= pRenderProperties;
01675 m_OccurenceAttrib.insert(occurenceId, pOccurenceAttrib);
01676 }
01677 else m_OccurenceAttrib.value(occurenceId)->m_pRenderProperties= pRenderProperties;
01678 }
01679
01680 readNext();;
01681 }
01682
01683 }
01684
01685 readNext();;
01686 }
01687
01688
01689 if (m_pStreamReader->hasError())
01690 {
01691 QString message(QString("GLC_3dxmlToWorld::loadDefaultViewProperty An error occur in ") + m_FileName);
01692 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
01693 clear();
01694 throw(fileFormatException);
01695 }
01696
01697 }
01698
01699 void GLC_3dxmlToWorld::loadExternRepresentations()
01700 {
01701
01702 if (m_ExternRepLinkList.isEmpty()) return;
01703
01704 QHash<const unsigned int, GLC_3DRep> repHash;
01705
01706
01707 const int size= m_ReferenceRepHash.size();
01708 int previousQuantumValue= 0;
01709 int currentQuantumValue= 0;
01710 int currentFileIndex= 0;
01711 emit currentQuantum(currentQuantumValue);
01712
01713
01714 ReferenceRepHash::iterator iRefRep= m_ReferenceRepHash.begin();
01715 while (iRefRep != m_ReferenceRepHash.constEnd())
01716 {
01717 m_CurrentFileName= iRefRep.value();
01718 const unsigned int id= iRefRep.key();
01719
01720 if (!m_IsInArchive)
01721 {
01722
01723 m_CurrentDateTime= QFileInfo(QFileInfo(m_FileName).absolutePath() + QDir::separator() + QFileInfo(m_CurrentFileName).fileName()).lastModified();
01724 }
01725
01726
01727 if (!m_LoadStructureOnly && setStreamReaderToFile(m_CurrentFileName))
01728 {
01729 GLC_3DRep representation;
01730 if (GLC_State::cacheIsUsed() && GLC_State::currentCacheManager().isUsable(m_CurrentDateTime, QFileInfo(m_FileName).baseName(), m_CurrentFileName))
01731 {
01732 GLC_CacheManager cacheManager= GLC_State::currentCacheManager();
01733 GLC_BSRep binaryRep= cacheManager.binary3DRep(QFileInfo(m_FileName).baseName(), m_CurrentFileName);
01734 representation= binaryRep.loadRep();
01735 setRepresentationFileName(&representation);
01736 factorizeMaterial(&representation);
01737 }
01738 else
01739 {
01740 representation= loadCurrentExtRep();
01741 representation.clean();
01742 }
01743 if (!representation.isEmpty())
01744 {
01745 repHash.insert(id, representation);
01746 }
01747 }
01748 else if (m_LoadStructureOnly)
01749 {
01750 GLC_3DRep representation;
01751 if (m_IsInArchive)
01752 {
01753 representation.setFileName(glc::builtArchiveString(m_FileName, m_CurrentFileName));
01754 }
01755 else
01756 {
01757 const QString repFileName= glc::builtFileString(m_FileName, m_CurrentFileName);
01758 representation.setFileName(repFileName);
01759 m_SetOfAttachedFileName << glc::archiveEntryFileName(repFileName);
01760 }
01761
01762 repHash.insert(id, representation);
01763 }
01764
01765
01766 ++currentFileIndex;
01767 currentQuantumValue = static_cast<int>((static_cast<double>(currentFileIndex) / size) * 100);
01768 if (currentQuantumValue > previousQuantumValue)
01769 {
01770 emit currentQuantum(currentQuantumValue);
01771 }
01772 previousQuantumValue= currentQuantumValue;
01773
01774 ++iRefRep;
01775 }
01776
01777
01778 RepLinkList::iterator iExtRep= m_ExternRepLinkList.begin();
01779 while (iExtRep != m_ExternRepLinkList.constEnd())
01780 {
01781 unsigned int referenceId= (*iExtRep).m_ReferenceId;
01782 unsigned int refId= (*iExtRep).m_RepId;
01783
01784 GLC_StructReference* pReference= m_ReferenceHash.value(referenceId);
01785 if (pReference->hasRepresentation())
01786 {
01787 GLC_3DRep* pRep= dynamic_cast<GLC_3DRep*>(pReference->representationHandle());
01788 if (NULL != pRep)
01789 {
01790 GLC_3DRep newRep(repHash.value(refId));
01791 pRep->take(&newRep);
01792 }
01793 }
01794 else
01795 {
01796 pReference->setRepresentation(repHash.value(refId));
01797 }
01798
01799 if (pReference->representationName().isEmpty())
01800 {
01801 pReference->setRepresentationName(pReference->name());
01802 }
01803
01804 ++iExtRep;
01805 }
01806
01807 }
01808
01809
01810 GLC_3DRep GLC_3dxmlToWorld::loadCurrentExtRep()
01811 {
01812 GLC_Mesh* pMesh= new GLC_Mesh();
01813 GLC_3DRep currentMeshRep(pMesh);
01814 currentMeshRep.setName(QString());
01815
01816 setRepresentationFileName(¤tMeshRep);
01817
01818 currentMeshRep.setLastModified(m_CurrentDateTime);
01819
01820 int numberOfMesh= 1;
01821 while (!m_pStreamReader->atEnd())
01822 {
01823 m_pCurrentMaterial= NULL;
01824 gotToPolygonalRepType();
01825 if (m_pStreamReader->atEnd() || m_pStreamReader->hasError())
01826 {
01827 if (m_pStreamReader->hasError())
01828 {
01829 QString message(QString("An element have not been found in file ") + m_FileName);
01830 GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
01831 clear();
01832 throw(fileFormatException);
01833 }
01834 else
01835 {
01836 pMesh->finish();
01837 currentMeshRep.clean();
01838
01839 if (GLC_State::cacheIsUsed())
01840 {
01841 GLC_CacheManager currentManager= GLC_State::currentCacheManager();
01842 currentManager.addToCache(QFileInfo(m_FileName).baseName(), currentMeshRep);
01843 }
01844
01845 return currentMeshRep;
01846 }
01847 }
01848 if (numberOfMesh > 1)
01849 {
01850 pMesh->finish();
01851 pMesh = new GLC_Mesh();
01852 currentMeshRep.addGeom(pMesh);
01853 }
01854
01855
01856 double masteLodAccuracy= readAttribute("accuracy", false).toDouble();
01857
01858 loadLOD(pMesh);
01859 if (m_pStreamReader->atEnd() || m_pStreamReader->hasError())
01860 {
01861 QStringList stringList(m_FileName);
01862 stringList.append(m_CurrentFileName);
01863 stringList.append("Master LOD not found");
01864 GLC_ErrorLog::addError(stringList);
01865
01866 pMesh->finish();
01867 currentMeshRep.clean();
01868
01869 if (GLC_State::cacheIsUsed())
01870 {
01871 GLC_CacheManager currentManager= GLC_State::currentCacheManager();
01872 currentManager.addToCache(QFileInfo(m_FileName).baseName(), currentMeshRep);
01873 }
01874
01875 return currentMeshRep;
01876 }
01877
01878
01879 while (endElementNotReached(m_pStreamReader, "Faces"))
01880 {
01881 readNext();;
01882 if ( m_pStreamReader->name() == "Face")
01883 {
01884 loadFace(pMesh, 0, masteLodAccuracy);
01885 }
01886 }
01887 checkForXmlError("End of Faces not found");
01888
01889 while (startElementNotReached(m_pStreamReader, "Edges") && startElementNotReached(m_pStreamReader, "VertexBuffer"))
01890 {
01891 readNext();;
01892 }
01893
01894 checkForXmlError("Element VertexBuffer not found");
01895 if (m_pStreamReader->name() == "Edges")
01896 {
01897 while (endElementNotReached(m_pStreamReader, "Edges"))
01898 {
01899 readNext();;
01900 if ( m_pStreamReader->name() == "Polyline")
01901 {
01902 loadPolyline(pMesh);
01903 readNext();;
01904 }
01905 }
01906 }
01907
01908 {
01909 QString verticePosition= getContent(m_pStreamReader, "Positions").replace(',', ' ');
01910
01911 checkForXmlError("Error while retrieving Position ContentVertexBuffer");
01912
01913 QTextStream verticeStream(&verticePosition);
01914 QList<GLfloat> verticeValues;
01915 QString buff;
01916 while ((!verticeStream.atEnd()))
01917 {
01918 verticeStream >> buff;
01919 verticeValues.append(buff.toFloat());
01920 }
01921 pMesh->addVertice(verticeValues.toVector());
01922
01923 }
01924
01925 {
01926 QString normals= getContent(m_pStreamReader, "Normals").replace(',', ' ');
01927
01928 checkForXmlError("Error while retrieving Normals values");
01929
01930 QTextStream normalsStream(&normals);
01931 QList<GLfloat> normalValues;
01932 QString buff;
01933 while ((!normalsStream.atEnd()))
01934 {
01935 normalsStream >> buff;
01936 normalValues.append(buff.toFloat());
01937 }
01938 pMesh->addNormals(normalValues.toVector());
01939 }
01940
01941 while (endElementNotReached(m_pStreamReader, "VertexBuffer"))
01942 {
01943 if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "TextureCoordinates"))
01944 {
01945 QString texels= getContent(m_pStreamReader, "TextureCoordinates").replace(',', ' ');
01946 checkForXmlError("Error while retrieving Texture coordinates");
01947 QTextStream texelStream(&texels);
01948 QList<GLfloat> texelValues;
01949 QString buff;
01950 while ((!texelStream.atEnd()))
01951 {
01952 texelStream >> buff;
01953 texelValues.append(buff.toFloat());
01954 }
01955 pMesh->addTexels(texelValues.toVector());
01956 }
01957 readNext();;
01958 }
01959 ++numberOfMesh;
01960 }
01961
01962 pMesh->finish();
01963 currentMeshRep.clean();
01964
01965 if (GLC_State::cacheIsUsed())
01966 {
01967 GLC_CacheManager currentManager= GLC_State::currentCacheManager();
01968 currentManager.addToCache(QFileInfo(m_FileName).baseName(), currentMeshRep);
01969 }
01970
01971 return currentMeshRep;
01972 }
01973
01974 void GLC_3dxmlToWorld::loadCatMaterialRef()
01975 {
01976
01977 QList<MaterialRef> materialRefList;
01978
01979
01980 if (setStreamReaderToFile("CATMaterialRef.3dxml", true))
01981 {
01982
01983
01984 goToElement(m_pStreamReader, "CATMaterialRef");
01985 checkForXmlError("Element CATMaterialRef not found in CATMaterialRef.3dxml");
01986 while (endElementNotReached(m_pStreamReader, "CATMaterialRef"))
01987 {
01988 if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType())
01989 {
01990 const QStringRef currentElementName= m_pStreamReader->name();
01991 if (currentElementName == "CATMatReference")
01992 {
01993 MaterialRef currentMaterial;
01994 currentMaterial.m_Id= readAttribute("id", true);
01995 currentMaterial.m_Name= readAttribute("name", true);
01996 goToElement(m_pStreamReader, "MaterialDomain");
01997 checkForXmlError("Element MaterialDomain not found after CATMatReference Element");
01998 currentMaterial.m_AssociatedFile= readAttribute("associatedFile", true).remove("urn:3DXML:");
01999 materialRefList.append(currentMaterial);
02000
02001 }
02002 }
02003 readNext();;
02004 }
02005 }
02006
02007 const int size= materialRefList.size();
02008 for (int i= 0; i < size; ++i)
02009 {
02010 if (setStreamReaderToFile(materialRefList.at(i).m_AssociatedFile, true))
02011 {
02012
02013 loadMaterialDef(materialRefList.at(i));
02014 }
02015 }
02016 }
02017
02018
02019 void GLC_3dxmlToWorld::loadMaterialDef(const MaterialRef& materialRef)
02020 {
02021 GLC_Material* pMaterial= new GLC_Material();
02022 goToElement(m_pStreamReader, "Osm");
02023 checkForXmlError(QString("Element Osm not found in file : ") + materialRef.m_AssociatedFile);
02024 while (endElementNotReached(m_pStreamReader, "Osm"))
02025 {
02026 readNext();;
02027 if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && m_pStreamReader->name() == "Attr")
02028 {
02029 const QString currentName= readAttribute("Name", true);
02030 if (currentName == "DiffuseColor")
02031 {
02032 QString color= m_pStreamReader->attributes().value("Value").toString();
02033 color.remove('[');
02034 color.remove(']');
02035 QStringList colors(color.split(","));
02036 QColor diffuseColor;
02037 diffuseColor.setRedF(colors.at(0).toDouble());
02038 diffuseColor.setGreenF(colors.at(1).toDouble());
02039 diffuseColor.setBlueF(colors.at(2).toDouble());
02040 pMaterial->setDiffuseColor(diffuseColor);
02041 }
02042 else if (currentName == "Transparency")
02043 {
02044 double opacity= readAttribute("Value", true).toDouble();
02045 opacity= 1.0 - opacity;
02046 pMaterial->setOpacity(opacity);
02047 }
02048 else if (currentName == "SpecularExponent")
02049 {
02050 double SpecularExponent= readAttribute("Value", true).toDouble() * 128.0;
02051 pMaterial->setShininess(SpecularExponent);
02052 }
02053 else if (currentName == "TextureImage")
02054 {
02055
02056 QString imageId= readAttribute("Value", true).remove("urn:3DXML:CATRepImage.3dxml#");
02057 if (m_TextureImagesHash.contains(imageId))
02058 {
02059 QString imageName= m_TextureImagesHash.value(imageId);
02060 GLC_Texture* pTexture= loadTexture(imageName);
02061 if (NULL != pTexture)
02062 {
02063 pMaterial->setTexture(pTexture);
02064 }
02065 }
02066 }
02067 else if (currentName == "EmissiveCoef")
02068 {
02069
02070 }
02071 else if (currentName == "SpecularColor")
02072 {
02073 QString color= readAttribute("Value", true);
02074 color.remove('[');
02075 color.remove(']');
02076 QStringList colors(color.split(","));
02077 QColor specularColor;
02078 specularColor.setRedF(colors.at(0).toDouble());
02079 specularColor.setGreenF(colors.at(1).toDouble());
02080 specularColor.setBlueF(colors.at(2).toDouble());
02081 pMaterial->setSpecularColor(specularColor);
02082 }
02083 else if (currentName == "AmbientColor")
02084 {
02085 QString color= readAttribute("Value", true);
02086 color.remove('[');
02087 color.remove(']');
02088 QStringList colors(color.split(","));
02089 QColor ambientColor;
02090 ambientColor.setRedF(colors.at(0).toDouble());
02091 ambientColor.setGreenF(colors.at(1).toDouble());
02092 ambientColor.setBlueF(colors.at(2).toDouble());
02093 pMaterial->setAmbientColor(ambientColor);
02094 }
02095
02096 }
02097 }
02098 pMaterial->setName(materialRef.m_Name);
02099 m_MaterialHash.insert(materialRef.m_Id, pMaterial);
02100 }
02101
02102
02103 void GLC_3dxmlToWorld::loadCatRepImage()
02104 {
02105
02106 if (setStreamReaderToFile("CATRepImage.3dxml", true))
02107 {
02108
02109 goToElement(m_pStreamReader, "CATRepImage");
02110 checkForXmlError("Element CATRepImage not found in CATRepImage.3dxml");
02111 while (endElementNotReached(m_pStreamReader, "CATRepImage"))
02112 {
02113 if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType())
02114 {
02115 const QStringRef currentElementName= m_pStreamReader->name();
02116 if (currentElementName == "CATRepresentationImage")
02117 {
02118 QString id= readAttribute("id", true);
02119 QString associatedFile= readAttribute("associatedFile", true).remove("urn:3DXML:");
02120 m_TextureImagesHash.insert(id,associatedFile);
02121 }
02122 }
02123 readNext();;
02124 }
02125
02126 }
02127 }
02128
02129
02130 GLC_Texture* GLC_3dxmlToWorld::loadTexture(QString fileName)
02131 {
02132 QString format= QFileInfo(fileName).suffix().toUpper();
02133 QImage resultImage;
02134 QString resultImageFileName;
02135 if (m_IsInArchive)
02136 {
02137
02138 QuaZipFile* p3dxmlFile= new QuaZipFile(m_p3dxmlArchive);
02139
02140
02141 if (!m_p3dxmlArchive->setCurrentFile(fileName, QuaZip::csInsensitive))
02142 {
02143 return NULL;
02144 }
02145
02146
02147 if(!p3dxmlFile->open(QIODevice::ReadOnly))
02148 {
02149 delete p3dxmlFile;
02150 QString message(QString("GLC_3dxmlToWorld::loadImage Unable to Open ") + fileName);
02151 GLC_FileFormatException fileFormatException(message, fileName, GLC_FileFormatException::FileNotSupported);
02152 clear();
02153 throw(fileFormatException);
02154 }
02155 resultImage.load(p3dxmlFile, format.toLocal8Bit());
02156 p3dxmlFile->close();
02157 delete p3dxmlFile;
02158 resultImageFileName= glc::builtArchiveString(m_FileName, fileName);
02159 }
02160 else
02161 {
02162
02163 if (fileName != m_FileName)
02164 {
02165 resultImageFileName= QFileInfo(m_FileName).absolutePath() + QDir::separator() + fileName;
02166 }
02167 QFile* pCurrentFile= new QFile(resultImageFileName);
02168 if (!pCurrentFile->open(QIODevice::ReadOnly))
02169 {
02170 delete pCurrentFile;
02171 QString message(QString("GLC_3dxmlToWorld::loadImage File ") + resultImageFileName + QString(" not found"));
02172 QStringList stringList(m_CurrentFileName);
02173 stringList.append(message);
02174 GLC_ErrorLog::addError(stringList);
02175 return NULL;
02176 }
02177 else
02178 {
02179 m_SetOfAttachedFileName << resultImageFileName;
02180 }
02181 resultImage.load(pCurrentFile, format.toLocal8Bit());
02182 pCurrentFile->close();
02183 delete pCurrentFile;
02184 }
02185
02186 GLC_Texture* pTexture= NULL;
02187 if (!resultImage.isNull())
02188 {
02189 pTexture= new GLC_Texture(resultImage, resultImageFileName);
02190 }
02191 else
02192 {
02193 QStringList stringList(m_CurrentFileName);
02194 stringList.append("Unable to load " + resultImageFileName);
02195 GLC_ErrorLog::addError(stringList);
02196 }
02197
02198 return pTexture;
02199 }
02200
02201
02202 void GLC_3dxmlToWorld::factorizeMaterial(GLC_3DRep* pRep)
02203 {
02204
02205
02206 QSet<GLC_Material*> repMaterialSet= pRep->materialSet();
02208 QHash<GLC_uint, GLC_Material*> repMaterialHash;
02209
02210 QHash<QString, GLC_uint> materialMap;
02211
02212 {
02213 QSet<GLC_Material*>::const_iterator iMat= repMaterialSet.constBegin();
02214 while(repMaterialSet.constEnd() != iMat)
02215 {
02216 GLC_Material* pCurrentMat= *iMat;
02217 materialMap.insert(QString::number(pCurrentMat->hashCode()), pCurrentMat->id());
02218 repMaterialHash.insert(pCurrentMat->id(), pCurrentMat);
02219 ++iMat;
02220 }
02221 }
02222
02223
02224 QHash<QString, GLC_uint>::iterator iMat= materialMap.begin();
02225 while (materialMap.constEnd() != iMat)
02226 {
02227 if (m_MaterialHash.contains(iMat.key()))
02228 {
02229
02230 pRep->replaceMaterial(iMat.value(), m_MaterialHash.value(iMat.key()));
02231 }
02232 else
02233 {
02234
02235 m_MaterialHash.insert(iMat.key(), repMaterialHash.value(iMat.value()));
02236 }
02237 ++iMat;
02238 }
02239
02240 }
02241
02242 void GLC_3dxmlToWorld::setRepresentationFileName(GLC_3DRep* pRep)
02243 {
02244 if (m_IsInArchive)
02245 {
02246 pRep->setFileName(glc::builtArchiveString(m_FileName, m_CurrentFileName));
02247 }
02248 else
02249 {
02250 pRep->setFileName(QFileInfo(m_FileName).absolutePath() + QDir::separator() + m_CurrentFileName);
02251 }
02252 }
02253
02254 void GLC_3dxmlToWorld::checkFileValidity(QIODevice* pIODevice)
02255 {
02256 QByteArray begining= pIODevice->read(2);
02257 if (begining == "V5")
02258 {
02259 QString message(QString("GLC_3dxmlToWorld::setStreamReaderToFile : File ") + m_CurrentFileName + " is binary");
02260 GLC_FileFormatException fileFormatException(message, m_CurrentFileName, GLC_FileFormatException::FileNotSupported);
02261 clear();
02262 throw(fileFormatException);
02263 }
02264 else
02265 {
02266 pIODevice->seek(0);
02267 }
02268 }