glc_3dxmltoworld.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 
00003  This file is part of the GLC-lib library.
00004  Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
00005  http://glc-lib.sourceforge.net
00006 
00007  GLC-lib is free software; you can redistribute it and/or modify
00008  it under the terms of the GNU Lesser General Public License as published by
00009  the Free Software Foundation; either version 3 of the License, or
00010  (at your option) any later version.
00011 
00012  GLC-lib is distributed in the hope that it will be useful,
00013  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  GNU Lesser General Public License for more details.
00016 
00017  You should have received a copy of the GNU Lesser General Public License
00018  along with GLC-lib; if not, write to the Free Software
00019  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
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 // Quazip library
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 //using namespace glcXmlUtil;
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         // Clear specific attributes hash table
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 // Set Functions
00104 
00105 // Create an GLC_World from an input 3DXML File
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         // Create the 3dxml Zip archive
00115         m_p3dxmlArchive= new QuaZip(m_FileName);
00116         // Trying to load archive
00117         if(!m_p3dxmlArchive->open(QuaZip::mdUnzip))
00118         {
00119           // In this case, the 3dxml is not compressed or is not valid
00120           m_RootName= m_FileName;
00121           delete m_p3dxmlArchive;
00122           m_p3dxmlArchive= NULL;
00123         }
00124         else
00125         {
00126                 // Get the 3DXML time stamp
00127                 m_CurrentDateTime= QFileInfo(m_FileName).lastModified();
00128 
00129                 m_IsInArchive= true;
00130                 // Set the file Name Codec
00131                 //m_p3dxmlArchive->setFileNameCodec("IBM866");
00132 
00133                 // Load the manifest
00134                 loadManifest();
00135         }
00136 
00137         if (!m_LoadStructureOnly)
00138         {
00139                 // Trying to Load CATRepImage file
00140                 loadCatRepImage();
00141 
00142                 // Trying to Load CATRefMaterial File
00143                 loadCatMaterialRef();
00144         }
00145 
00146         // Load the product structure
00147         loadProductStructure();
00148 
00149 
00150         emit currentQuantum(100);
00151         return m_pWorld;
00152 }
00153 
00154 // Create 3DRep from an 3DXML rep
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                 // Create the 3dxml Zip archive
00163                 m_ZipMutex.lock();
00164                 m_p3dxmlArchive= new QuaZip(m_FileName);
00165                 // Trying to load archive
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                         // Set the file Name Codec
00175                         //m_p3dxmlArchive->setFileNameCodec("IBM866");
00176                 }
00177                 m_ZipMutex.unlock();
00178                 m_CurrentFileName= glc::archiveEntryFileName(fileName);
00179 
00180                 // Get the 3DXML time stamp
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                 // Get the rep time stamp
00189                 m_CurrentDateTime= QFileInfo(m_CurrentFileName).lastModified();
00190 
00191                 // Keep only the file name
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 // Private services functions
00257 // Load the 3dxml's manifest
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         // Clear current file
00286         if (NULL != m_pCurrentFile)
00287         {
00288                 m_pCurrentFile->close();
00289                 delete m_pCurrentFile;
00290                 m_pCurrentFile= NULL;
00291         }
00292 
00293         // Clear the 3dxml archive
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 // Go to a Rep of a xml
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 // Go to Polygonal Rep Type
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                 //qDebug() << m_pStreamReader->name();
00325                 //qDebug() << m_pStreamReader->attributes().value("xsi:type").toString();
00326                 readNext();;
00327         }
00328 
00329 }
00330 
00331 // Read the specified attribute
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 // Load the product structure
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         // Load the structure
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         // Load Default view properties
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         // Check if an error Occur
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         // Load external ref (3DXML V3)
00401         loadExternalRef3D();
00402 
00403         // Load extern representations (3DXML V4)
00404         loadExternRepresentations();
00405 
00406         { // Link locals instance with reference
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         //qDebug() << "Local instance linked with reference";
00428 
00429         { // Link external instance with reference
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                 // Check usage of reference in the external reference hash
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         //qDebug() << "external instance linked with reference";
00473 
00474         // Create the unfolded tree
00475         createUnfoldedTree();
00476 
00477         // Update occurence number
00478         m_pWorld->rootOccurence()->updateOccurenceNumber(1);
00479 
00480         // Change occurence attributes
00481         if (! m_OccurenceAttrib.isEmpty())
00482         {
00483                 //qDebug() << "Not visible occurence= " << m_OccurenceAttrib.size();
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         // Check usage of Instance
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         //qDebug() << "Unfolded tree created";
00534 
00535 }
00536 
00537 // Load a Reference3D
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) // This is the root reference.
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         // Try to find extension
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 // Load a Instance3D
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         // Try to find extension
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                 // 3dvia 3dxml
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 // Load a Reference representation
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         //const QString refName(readAttribute("name", true));
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 // Load a Instance representation
00685 void GLC_3dxmlToWorld::loadInstanceRep()
00686 {
00687         const QString local= "urn:3DXML:Reference:loc:";
00688 
00689         //const QString instName(readAttribute("name", true));
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                 // The 3dxml is a 3dxml rep from CATIA V5
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                 // The 3dxml is a 3dvia 3dxml
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 // Load External Ref
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                         // Get the representation time stamp
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                         // Avoid recursive call off createReferenceRep
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                 // Progrees bar indicator
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 // Create Instance from 3DXML Rep
00821 GLC_StructReference* GLC_3dxmlToWorld::createReferenceRep(QString repId, GLC_3DRep* pRep)
00822 {
00823         //qDebug() << "GLC_3dxmlToWorld::createReferenceRep :" << repId;
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         // Add time Stamp and file name to the 3D rep
00892 
00893         if (repId.contains("3DXML_Local_"))
00894         {
00895                 QString saveCurrentFileName= m_CurrentFileName;
00896                 m_CurrentFileName= repId;
00897                 setRepresentationFileName(&currentMesh3DRep);
00898                 m_CurrentFileName= saveCurrentFileName;
00899         }
00900         else
00901         {
00902                 setRepresentationFileName(&currentMesh3DRep);
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                 // Get the master lod accuracy
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                 // Load Faces index data
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                         //qDebug() << "Position " << verticePosition;
01001                         checkForXmlError("Error while retrieving Position ContentVertexBuffer");
01002                         // Load Vertice position
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                         //qDebug() << "Normals " << normals;
01018                         checkForXmlError("Error while retrieving Normals values");
01019                         // Load Vertice Normals
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                 // Try to find texture coordinate
01032                 while (endElementNotReached(m_pStreamReader, "VertexBuffer"))
01033                 {
01034                         //qDebug() << "Try to find texture coordinate " << m_pStreamReader->name() << " " << m_pStreamReader->lineNumber();
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 // Load Matrix
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         // Rotation
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         // Translation
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 // Create the unfolded  tree
01109 void GLC_3dxmlToWorld::createUnfoldedTree()
01110 {
01111         //qDebug() << "createUnfoldedTree";
01112         // Run throw all link in the list of link
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                 // Attach pInstance at all Occurence of pRef
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         // Check the assembly structure occurence
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         // Update position
01222         m_pWorld->rootOccurence()->updateChildrenAbsoluteMatrix();
01223 
01224 }
01225 // Check for XML error
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 // Go to the master LOD
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                         // Load Faces index data
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 // Load a face
01270 void GLC_3dxmlToWorld::loadFace(GLC_Mesh* pMesh, const int lod, double accuracy)
01271 {
01272         //qDebug() << "GLC_3dxmlToWorld::loadFace" << m_pStreamReader->name();
01273         // List of index declaration
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         // Trying to find triangles
01302         if (!triangles.isEmpty())
01303         {
01304                 // For 3dvia mesh
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         // Trying to find trips
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                         //qDebug() << "Strip " << stripsList.at(i);
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         // Trying to find fans
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 // Load polyline
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 // Clear material hash
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 // Set the stream reader to the specified file
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                 // Create QuaZip File
01466                 QuaZipFile* p3dxmlFile= new QuaZipFile(m_p3dxmlArchive);
01467 
01468                 // Get the file of the 3dxml
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                 // Open the file of the 3dxml
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                 // Test if the file is a binary
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                 // Set the stream reader
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                 // Create the file to load
01515                 if (fileName != m_FileName && !m_FileName.isEmpty())
01516                 {
01517                         fileName= QFileInfo(m_FileName).absolutePath() + QDir::separator() + fileName;
01518                 }
01519                 // Get the 3DXML time stamp
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                 // Test if the file is a binary
01536                 checkFileValidity(m_pCurrentFile);
01537 
01538                 // Set the stream reader
01539                 delete m_pStreamReader;
01540                 m_pStreamReader= new QXmlStreamReader(m_pCurrentFile);
01541         }
01542         return true;
01543 }
01544 
01545 // Load the local representation
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         // Load all local ref
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         //qDebug() << "Local rep loaded";
01571 
01572         // Attach the ref to the structure reference
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         // Load the graphics properties
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         // Check if an error Occur
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         // Load the graphics properties
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         // Check if an error Occur
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 // Load the extern representation
01699 void GLC_3dxmlToWorld::loadExternRepresentations()
01700 {
01701 
01702         if (m_ExternRepLinkList.isEmpty()) return;
01703 
01704         QHash<const unsigned int, GLC_3DRep> repHash;
01705 
01706         // Progress bar variables
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         // Load all external rep
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                         // Get the 3DXML time stamp
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                 // Progrees bar indicator
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         // Attach the ref to the structure reference
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                 // If representation hasn't a name. Set his name to reference name
01799                 if (pReference->representationName().isEmpty())
01800                 {
01801                         pReference->setRepresentationName(pReference->name());
01802                 }
01803 
01804                 ++iExtRep;
01805         }
01806 
01807 }
01808 
01809 // Return the instance of the current extern representation
01810 GLC_3DRep GLC_3dxmlToWorld::loadCurrentExtRep()
01811 {
01812         GLC_Mesh* pMesh= new GLC_Mesh();
01813         GLC_3DRep currentMeshRep(pMesh);
01814         currentMeshRep.setName(QString());
01815         // Set rep file name and time stamp
01816         setRepresentationFileName(&currentMeshRep);
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                 // Get the master lod accuracy
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                 // Load Faces index data
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                         //qDebug() << "Position " << verticePosition;
01911                         checkForXmlError("Error while retrieving Position ContentVertexBuffer");
01912                         // Load Vertice position
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                         //qDebug() << "Normals " << normals;
01928                         checkForXmlError("Error while retrieving Normals values");
01929                         // Load Vertice Normals
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                 // Try to find texture coordinate
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 // Load CatMaterial Ref if present
01974 void GLC_3dxmlToWorld::loadCatMaterialRef()
01975 {
01976 
01977         QList<MaterialRef> materialRefList;
01978 
01979         // Load material Name, Id and associated File
01980         if (setStreamReaderToFile("CATMaterialRef.3dxml", true))
01981         {
01982                 // Load the material file
01983                 //qDebug() << "CATMaterialRef.3dxml found and current";
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                                         //qDebug() << "Material " << currentMaterial.m_Name << " Added";
02001                                 }
02002                         }
02003                         readNext();;
02004                 }
02005         }
02006         // Load material files
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                         //qDebug() << "Load MaterialDef : " << materialRefList.at(i).m_AssociatedFile;
02013                         loadMaterialDef(materialRefList.at(i));
02014                 }
02015         }
02016 }
02017 
02018 // Create material from material def file
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                                 //qDebug() << "TextureImage";
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 // Load CATRepIage if present
02103 void GLC_3dxmlToWorld::loadCatRepImage()
02104 {
02105         // Load texture image name
02106         if (setStreamReaderToFile("CATRepImage.3dxml", true))
02107         {
02108                 //qDebug() << "CATRepImage.3dxml Found";
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                 //qDebug() << "CATRepImage.3dxml Load";
02126         }
02127 }
02128 
02129 // try to load the specified image
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                 // Create QuaZip File
02138                 QuaZipFile* p3dxmlFile= new QuaZipFile(m_p3dxmlArchive);
02139 
02140                 // Get the file of the 3dxml
02141                 if (!m_p3dxmlArchive->setCurrentFile(fileName, QuaZip::csInsensitive))
02142                 {
02143                         return NULL;
02144                 }
02145 
02146                 // Open the file of the 3dxml
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                 // Create the file to load
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 // Factorize material use
02202 void GLC_3dxmlToWorld::factorizeMaterial(GLC_3DRep* pRep)
02203 {
02204         //qDebug() << "GLC_3dxmlToWorld::factorizeMaterial";
02205         // Get the Set of materials of the rep
02206         QSet<GLC_Material*> repMaterialSet= pRep->materialSet();
02208         QHash<GLC_uint, GLC_Material*> repMaterialHash;
02209         // Construct the map of material String Hash and Id
02210         QHash<QString, GLC_uint> materialMap;
02211 
02212         { // Fill the map of material
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         // Make the factorization
02224         QHash<QString, GLC_uint>::iterator iMat= materialMap.begin();
02225         while (materialMap.constEnd() != iMat)
02226         {
02227                 if (m_MaterialHash.contains(iMat.key()))
02228                 {
02229                         //qDebug() << "Replace Mat :" << iMat.key() << " " << iMat.value();
02230                         pRep->replaceMaterial(iMat.value(), m_MaterialHash.value(iMat.key()));
02231                 }
02232                 else
02233                 {
02234                         //qDebug() << "Indert mat " << iMat.key() << " " << iMat.value();
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 }

SourceForge.net Logo

©2005-2011 Laurent Ribon