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

SourceForge.net Logo

©2005-2010 Laurent Ribon