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

SourceForge.net Logo

©2005 Laurent Ribon