glc_worldto3dxml.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 
00003  This file is part of the GLC-lib library.
00004  Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
00005  http://glc-lib.sourceforge.net
00006 
00007  GLC-lib is free software; you can redistribute it and/or modify
00008  it under the terms of the GNU Lesser General Public License as published by
00009  the Free Software Foundation; either version 3 of the License, or
00010  (at your option) any later version.
00011 
00012  GLC-lib is distributed in the hope that it will be useful,
00013  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  GNU Lesser General Public License for more details.
00016 
00017  You should have received a copy of the GNU Lesser General Public License
00018  along with GLC-lib; if not, write to the Free Software
00019  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00020 
00021  *****************************************************************************/
00023 
00024 #include "glc_worldto3dxml.h"
00025 // Quazip library
00026 #include "../3rdparty/quazip/quazip.h"
00027 #include "../3rdparty/quazip/quazipfile.h"
00028 #include "../glc_exception.h"
00029 #include "../geometry/glc_mesh.h"
00030 
00031 #include <QFileInfo>
00032 
00033 GLC_WorldTo3dxml::GLC_WorldTo3dxml(const GLC_World& world, bool threaded)
00034 : QObject()
00035 , m_World(world)
00036 , m_ExportType(Compressed3dxml)
00037 , m_FileName()
00038 , m_pOutStream(NULL)
00039 , m_Generator("GLC_LIB")
00040 , m_CurrentId(0)
00041 , m_p3dxmlArchive(NULL)
00042 , m_pCurrentZipFile(NULL)
00043 , m_pCurrentFile(NULL)
00044 , m_AbsolutePath()
00045 , m_ReferenceToIdHash()
00046 , m_InstanceToIdHash()
00047 , m_ReferenceRepToIdHash()
00048 , m_ReferenceRepTo3dxmlFileName()
00049 , m_InstanceRep()
00050 , m_MaterialIdToMaterialName()
00051 , m_MaterialIdToMaterialId()
00052 , m_MaterialIdToTexture3dxmlName()
00053 , m_MaterialIdTo3dxmlImageId()
00054 , m_ExportMaterial(true)
00055 , m_3dxmlFileSet()
00056 , m_FileNameIncrement(0)
00057 , m_ListOfOverLoadedOccurence()
00058 , m_pReadWriteLock(NULL)
00059 , m_pIsInterupted(NULL)
00060 , m_IsThreaded(threaded)
00061 {
00062         m_World.rootOccurence()->updateOccurenceNumber(1);
00063 }
00064 
00065 GLC_WorldTo3dxml::~GLC_WorldTo3dxml()
00066 {
00067         delete m_p3dxmlArchive;
00068         delete m_pCurrentZipFile;
00069         delete m_pCurrentFile;
00070 }
00071 
00072 bool GLC_WorldTo3dxml::exportTo3dxml(const QString& filename, GLC_WorldTo3dxml::ExportType exportType, bool exportMaterial)
00073 {
00074         m_3dxmlFileSet.clear();
00075         m_ListOfOverLoadedOccurence.clear();
00076         m_FileNameIncrement= 0;
00077         m_ExportMaterial= exportMaterial;
00078         m_FileName= filename;
00079         m_ExportType= exportType;
00080         bool isExported= false;
00081         if (m_ExportType == Compressed3dxml)
00082         {
00083                 m_p3dxmlArchive= new QuaZip(m_FileName);
00084                 isExported= m_p3dxmlArchive->open(QuaZip::mdCreate);
00085                 // Add the manifest
00086                 addManifest();
00087 
00088         }
00089         else
00090         {
00091                 m_AbsolutePath= QFileInfo(m_FileName).absolutePath() + QDir::separator();
00092                 QFile exportFile(m_FileName);
00093                 isExported= exportFile.open(QIODevice::WriteOnly);
00094                 exportFile.close();
00095         }
00096         if (isExported)
00097         {
00098                 if (m_ExportMaterial && (m_ExportType != StructureOnly))
00099                 {
00100                         writeAllMaterialRelatedFilesIn3dxml();
00101                 }
00102 
00103                 // Export the assembly structure from the list of structure reference
00104                 exportAssemblyStructure();
00105 
00106                 if (m_ExportType != StructureOnly)
00107                 {
00108                         int previousQuantumValue= 0;
00109                         int currentQuantumValue= 0;
00110                         emit currentQuantum(currentQuantumValue);
00111 
00112                         int currentRepIndex= 0;
00113                         const int size= m_ReferenceRepTo3dxmlFileName.size();
00114                         // Export the representation
00115                         QHash<const GLC_3DRep*, QString>::const_iterator iRep= m_ReferenceRepTo3dxmlFileName.constBegin();
00116                         while ((m_ReferenceRepTo3dxmlFileName.constEnd() != iRep) && continu())
00117                         {
00118                                 write3DRep(iRep.key(), iRep.value());
00119                                 ++iRep;
00120 
00121                                 // Progrees bar indicator
00122                                 ++currentRepIndex;
00123                                 currentQuantumValue = static_cast<int>((static_cast<double>(currentRepIndex) / size) * 100);
00124                                 if (currentQuantumValue > previousQuantumValue)
00125                                 {
00126                                         emit currentQuantum(currentQuantumValue);
00127                                 }
00128                                 previousQuantumValue= currentQuantumValue;
00129                                 if (!m_IsThreaded)
00130                                 {
00131                                         QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
00132                                 }
00133                         }
00134                 }
00135         }
00136 
00137         emit currentQuantum(100);
00138         return isExported;
00139 }
00140 
00141 bool GLC_WorldTo3dxml::exportReferenceTo3DRep(const GLC_3DRep* p3DRep, const QString& fullFileName)
00142 {
00143         m_3dxmlFileSet.clear();
00144         m_ListOfOverLoadedOccurence.clear();
00145         m_FileNameIncrement= 0;
00146         m_ExportMaterial= false;
00147 
00148         m_AbsolutePath= QFileInfo(fullFileName).absolutePath() + QDir::separator();
00149 
00150         write3DRep(p3DRep, QFileInfo(fullFileName).fileName());
00151 
00152         return true;
00153 }
00154 
00155 void GLC_WorldTo3dxml::setInterupt(QReadWriteLock* pReadWriteLock, bool* pInterupt)
00156 {
00157         m_pReadWriteLock= pReadWriteLock;
00158         m_pIsInterupted= pInterupt;
00159 }
00160 
00161 void GLC_WorldTo3dxml::writeHeader()
00162 {
00163         const QString title(QFileInfo(m_FileName).fileName());
00164 
00165         m_pOutStream->writeStartElement("Header");
00166                 m_pOutStream->writeTextElement("SchemaVersion", "4.0");
00167                 m_pOutStream->writeTextElement("Title", title);
00168                 m_pOutStream->writeTextElement("Generator", m_Generator);
00169                 m_pOutStream->writeTextElement("Created", QDate::currentDate().toString(Qt::ISODate));
00170         m_pOutStream->writeEndElement();
00171 }
00172 
00173 void GLC_WorldTo3dxml::writeReference3D(const GLC_StructReference* pRef)
00174 {
00175         m_pOutStream->writeStartElement("Reference3D");
00176                 m_pOutStream->writeAttribute("xsi:type", "Reference3DType");
00177                 m_pOutStream->writeAttribute("id", QString::number(++m_CurrentId));
00178                 m_pOutStream->writeAttribute("name", pRef->name());
00179                 if (pRef->containsAttributes())
00180                 {
00181                         m_pOutStream->writeStartElement("Reference3DExtensionType");
00182                         writeExtensionAttributes(pRef->attributesHandle());
00183                         m_pOutStream->writeEndElement(); // Reference3DExtensionType
00184                 }
00185         m_pOutStream->writeEndElement(); // Reference3D
00186 
00187         m_ReferenceToIdHash.insert(pRef, m_CurrentId);
00188 }
00189 
00190 void GLC_WorldTo3dxml::writeReferenceRep(const GLC_3DRep* p3DRep)
00191 {
00192         const QString id(QString::number(++m_CurrentId));
00193         m_ReferenceRepToIdHash.insert(p3DRep, m_CurrentId);
00194         const QString associateFile(representationFileName(p3DRep));
00195         m_ReferenceRepTo3dxmlFileName.insert(p3DRep, QString(associateFile).remove("urn:3DXML:"));
00196 
00197         m_pOutStream->writeStartElement("ReferenceRep");
00198                 m_pOutStream->writeAttribute("xsi:type", "ReferenceRepType");
00199                 m_pOutStream->writeAttribute("id", id);
00200                 m_pOutStream->writeAttribute("name", p3DRep->name());
00201                 m_pOutStream->writeAttribute("format", "TESSELLATED");
00202                 m_pOutStream->writeAttribute("version", "1.2");
00203                 m_pOutStream->writeAttribute("associatedFile", associateFile);
00204                 m_pOutStream->writeTextElement("PLM_ExternalID", p3DRep->name());
00205                 m_pOutStream->writeTextElement("V_discipline", "Design");
00206                 m_pOutStream->writeTextElement("V_usage", "3DShape");
00207                 m_pOutStream->writeTextElement("V_nature", "1");
00208         m_pOutStream->writeEndElement();
00209 
00210 
00211 }
00212 void GLC_WorldTo3dxml::writeInstance3D(const GLC_StructInstance* pInstance, unsigned int parentId)
00213 {
00214         const GLC_StructReference* pRef= pInstance->structReference();
00215         const unsigned int referenceId= m_ReferenceToIdHash.value(pRef);
00216         const QString instanceMatrix(matrixString(pInstance->relativeMatrix()));
00217 
00218         m_pOutStream->writeStartElement("Instance3D");
00219                 m_pOutStream->writeAttribute("xsi:type", "Instance3DType");
00220                 m_pOutStream->writeAttribute("id", QString::number(++m_CurrentId));
00221                 m_pOutStream->writeAttribute("name", pInstance->name());
00222                 m_pOutStream->writeTextElement("IsAggregatedBy", QString::number(parentId));
00223                 m_pOutStream->writeTextElement("IsInstanceOf", QString::number(referenceId));
00224                 m_pOutStream->writeTextElement("RelativeMatrix", instanceMatrix);
00225                 if (pInstance->containsAttributes())
00226                 {
00227                         m_pOutStream->writeStartElement("Instance3DExtensionType");
00228                         writeExtensionAttributes(pInstance->attributesHandle());
00229                         m_pOutStream->writeEndElement(); // Instance3DExtensionType
00230                 }
00231 
00232         m_pOutStream->writeEndElement(); // Instance3D
00233 
00234         m_InstanceToIdHash.insert(pInstance, m_CurrentId);
00235 }
00236 
00237 void  GLC_WorldTo3dxml::writeInstanceRep(const GLC_3DRep* p3DRep, unsigned int parentId)
00238 {
00239         const unsigned int referenceId= m_ReferenceRepToIdHash.value(p3DRep);
00240         m_pOutStream->writeStartElement("InstanceRep");
00241                 m_pOutStream->writeAttribute("xsi:type", "InstanceRepType");
00242                 m_pOutStream->writeAttribute("id", QString::number(++m_CurrentId));
00243                 m_pOutStream->writeAttribute("name", p3DRep->name());
00244                 m_pOutStream->writeTextElement("IsAggregatedBy", QString::number(parentId));
00245                 m_pOutStream->writeTextElement("IsInstanceOf", QString::number(referenceId));
00246         m_pOutStream->writeEndElement();
00247 
00248         m_InstanceRep.insert(parentId);
00249 
00250 }
00251 void GLC_WorldTo3dxml::setStreamWriterToFile(const QString& fileName)
00252 {
00253         delete m_pOutStream;
00254         m_pOutStream= NULL;
00255 
00256         bool success= false;
00257         if (NULL != m_p3dxmlArchive)
00258         {
00259                 if (NULL != m_pCurrentZipFile)
00260                 {
00261                         m_pCurrentZipFile->close();
00262                         delete m_pOutStream;
00263                         delete m_pCurrentZipFile;
00264                 }
00265                 QuaZipNewInfo quazipNewInfo(fileName);
00266                 m_pCurrentZipFile= new QuaZipFile(m_p3dxmlArchive);
00267                 success= m_pCurrentZipFile->open(QIODevice::WriteOnly, quazipNewInfo);
00268                 if (success)
00269                 {
00270                         m_pOutStream= new QXmlStreamWriter(m_pCurrentZipFile);
00271                 }
00272         }
00273         else
00274         {
00275                 delete m_pCurrentFile;
00276                 m_pCurrentFile= new QFile(m_AbsolutePath + fileName);
00277                 success= m_pCurrentFile->open(QIODevice::WriteOnly);
00278                 if (success)
00279                 {
00280                         m_pOutStream= new QXmlStreamWriter(m_pCurrentFile);
00281                 }
00282         }
00283 
00284         if (NULL == m_pOutStream)
00285         {
00286                 QString message(QString("GLC_WorldTo3dxml::setStreamWriterToFile Unable to create ") + fileName);
00287                 GLC_Exception fileException(message);
00288                 throw(fileException);
00289         }
00290         else
00291         {
00292                 m_pOutStream->setAutoFormatting(true);
00293         }
00294 }
00295 
00296 void GLC_WorldTo3dxml::addManifest()
00297 {
00298         setStreamWriterToFile("Manifest.xml");
00299         m_pOutStream->writeStartDocument();
00300 
00301         m_pOutStream->writeStartElement("Manifest");
00302                 m_pOutStream->writeAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
00303                 m_pOutStream->writeAttribute("xsi:noNamespaceSchemaLocation", "Manifest.xsd");
00304                 m_pOutStream->writeTextElement("Root", QFileInfo(m_FileName).fileName());
00305                 m_pOutStream->writeEndElement();
00306         m_pOutStream->writeEndElement();
00307 
00308         m_pOutStream->writeEndDocument();
00309 }
00310 
00311 void GLC_WorldTo3dxml::exportAssemblyStructure()
00312 {
00313         m_ReferenceToIdHash.clear();
00314         m_InstanceToIdHash.clear();
00315         m_ReferenceRepToIdHash.clear();
00316         m_ReferenceRepTo3dxmlFileName.clear();
00317         m_InstanceRep.clear();
00318 
00319         // Create the assembly file
00320         setStreamWriterToFile(QFileInfo(m_FileName).fileName());
00321         m_pOutStream->writeStartDocument();
00322         m_pOutStream->writeStartElement("Model_3dxml");
00323         m_pOutStream->writeAttribute("xmlns", "http://www.3ds.com/xsd/3DXML");
00324         m_pOutStream->writeAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
00325         m_pOutStream->writeAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink");
00326 
00327         writeHeader();
00328 
00329         // Product Structure
00330         m_pOutStream->writeStartElement("ProductStructure");
00331         m_pOutStream->writeAttribute("root", "1");
00332         exportAssemblyFromOccurence(m_World.rootOccurence());
00333         m_pOutStream->writeEndElement(); // ProductStructure
00334 
00335         if (!m_ListOfOverLoadedOccurence.isEmpty())
00336         {
00337                 m_pOutStream->writeStartElement("DefaultView");
00338                         const int size= m_ListOfOverLoadedOccurence.size();
00339                         for (int i= 0; i < size; ++i)
00340                         {
00341                                 writeOccurenceDefaultViewProperty(m_ListOfOverLoadedOccurence.at(i));
00342                         }
00343                 m_pOutStream->writeEndElement(); // DefaultView
00344         }
00345 
00346         m_pOutStream->writeEndElement(); // Model_3dxml
00347 
00348         m_pOutStream->writeEndDocument();
00349 }
00350 
00351 void GLC_WorldTo3dxml::exportAssemblyFromOccurence(const GLC_StructOccurence* pOccurence)
00352 {
00353         if (pOccurence->isOrphan())
00354         {
00355                 writeReference3D(pOccurence->structReference());
00356         }
00357         else
00358         {
00359                 // Reference 3D
00360                 GLC_StructReference* pCurrentRef= pOccurence->structReference();
00361                 if (!m_ReferenceToIdHash.contains(pCurrentRef))
00362                 {
00363                         writeReference3D(pCurrentRef);
00364                         // Reference Rep
00365                         if (pCurrentRef->hasRepresentation())
00366                         {
00367                                 GLC_3DRep* pCurrentRep= dynamic_cast<GLC_3DRep*>(pCurrentRef->representationHandle());
00368                                 if (NULL != pCurrentRep && !m_ReferenceRepToIdHash.contains(pCurrentRep))
00369                                 {
00370                                         writeReferenceRep(pCurrentRep);
00371                                 }
00372                         }
00373                 }
00374                 // Instance 3D and instance rep
00375                 GLC_StructInstance* pCurrentInstance= pOccurence->structInstance();
00376                 if (!m_InstanceToIdHash.contains(pCurrentInstance))
00377                 {
00378                         // Instance 3D
00379                         const unsigned int parentId= m_ReferenceToIdHash.value(pOccurence->parent()->structReference());
00380                         writeInstance3D(pCurrentInstance, parentId);
00381 
00382                         // Instance Rep
00383                         if (pCurrentRef->hasRepresentation())
00384                         {
00385                                 GLC_3DRep* pCurrentRep= dynamic_cast<GLC_3DRep*>(pCurrentRef->representationHandle());
00386                                 const unsigned int parentId= m_ReferenceToIdHash.value(pCurrentRef);
00387                                 if (NULL != pCurrentRep && !m_InstanceRep.contains(parentId))
00388                                 {
00389                                         writeInstanceRep(pCurrentRep, parentId);
00390                                 }
00391                         }
00392                 }
00393         }
00394 
00395         // Process children
00396         const int childCount= pOccurence->childCount();
00397         for (int i= 0; i < childCount; ++i)
00398         {
00399                 exportAssemblyFromOccurence(pOccurence->child(i));
00400         }
00401 
00402         // Add occurence with Overload properties to a list
00403         if (m_World.collection()->contains(pOccurence->id()))
00404         {
00405                 GLC_3DViewInstance* pInstance= m_World.collection()->instanceHandle(pOccurence->id());
00406                 Q_ASSERT(NULL != pInstance);
00407                 const bool isVisible= pInstance->isVisible();
00408                 const bool isOverload= !isVisible || !pInstance->renderPropertiesHandle()->isDefault() || pOccurence->isFlexible();
00409                 if (isOverload)
00410                 {
00411                         m_ListOfOverLoadedOccurence.append(pOccurence);
00412                 }
00413         }
00414 
00415 }
00416 
00417 QString GLC_WorldTo3dxml::matrixString(const GLC_Matrix4x4& matrix)
00418 {
00419         QString resultMatrix;
00420         const QChar spaceChar(' ');
00421         // Rotation
00422         resultMatrix+= QString::number(matrix.getData()[0], 'g', 16) + spaceChar;
00423         resultMatrix+= QString::number(matrix.getData()[1], 'g', 16) + spaceChar;
00424         resultMatrix+= QString::number(matrix.getData()[2], 'g', 16) + spaceChar;
00425 
00426         resultMatrix+= QString::number(matrix.getData()[4], 'g', 16) + spaceChar;
00427         resultMatrix+= QString::number(matrix.getData()[5], 'g', 16) + spaceChar;
00428         resultMatrix+= QString::number(matrix.getData()[6], 'g', 16) + spaceChar;
00429 
00430         resultMatrix+= QString::number(matrix.getData()[8], 'g', 16) + spaceChar;
00431         resultMatrix+= QString::number(matrix.getData()[9], 'g', 16) + spaceChar;
00432         resultMatrix+= QString::number(matrix.getData()[10], 'g', 16) + spaceChar;
00433 
00434         // Translation
00435         resultMatrix+= QString::number(matrix.getData()[12], 'g', 16) + spaceChar;
00436         resultMatrix+= QString::number(matrix.getData()[13], 'g', 16) + spaceChar;
00437         resultMatrix+= QString::number(matrix.getData()[14], 'g', 16);
00438 
00439         return resultMatrix;
00440 }
00441 
00442 void GLC_WorldTo3dxml::write3DRep(const GLC_3DRep* pRep, const QString& fileName)
00443 {
00444         setStreamWriterToFile(fileName);
00445 
00446         m_pOutStream->writeStartDocument();
00447         m_pOutStream->writeStartElement("XMLRepresentation");
00448         m_pOutStream->writeAttribute("version", "1.2");
00449         m_pOutStream->writeAttribute("xmlns", "http://www.3ds.com/xsd/3DXML");
00450         m_pOutStream->writeAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
00451         m_pOutStream->writeAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink");
00452         m_pOutStream->writeAttribute("xsi:schemaLocation", "http://www.3ds.com/xsd/3DXML ./3DXMLMesh.xsd");
00453 
00454         m_pOutStream->writeStartElement("Root"); // Root
00455         m_pOutStream->writeAttribute("xsi:type", "BagRepType");
00456         m_pOutStream->writeAttribute("id", QString::number(++m_CurrentId));
00457         const int bodyCount= pRep->numberOfBody();
00458         for (int i= 0; i < bodyCount; ++i)
00459         {
00460                 GLC_Mesh* pMesh= dynamic_cast<GLC_Mesh*>(pRep->geomAt(i));
00461                 if (NULL != pMesh)
00462                 {
00463                         writeGeometry(pMesh);
00464                 }
00465         }
00466         m_pOutStream->writeEndElement(); // Root
00467 
00468         m_pOutStream->writeEndElement(); // XMLRepresentation
00469 
00470         m_pOutStream->writeEndDocument();
00471 }
00472 
00473 QString GLC_WorldTo3dxml::representationFileName(const GLC_3DRep* pRep)
00474 {
00475         Q_ASSERT(m_ReferenceRepToIdHash.contains(pRep));
00476         QString repName= pRep->name();
00477         QString fileName;
00478         if (m_ExportType == StructureOnly)
00479         {
00480                 QString newFileName= pRep->fileName();
00481                 // Test if the file name is encoded by GLC_Lib (Structure only loaded)
00482                 if (glc::isFileString(newFileName))
00483                 {
00484                         newFileName= glc::archiveEntryFileName(newFileName);
00485                 }
00486                 if (newFileName.isEmpty() || (glc::isArchiveString(newFileName)))
00487                 {
00488                         fileName= "urn:3DXML:NoFile_0.3DRep";
00489                 }
00490                 else
00491                 {
00492                         // Compute the relative fileName from the structure
00493                         QDir structureDir(m_AbsolutePath);
00494                         QString relativeFilePath= structureDir.relativeFilePath(newFileName);
00495                         fileName= "urn:3DXML:" + relativeFilePath;
00496                 }
00497         }
00498         else if (repName.isEmpty())
00499         {
00500                 fileName= "urn:3DXML:Representation_0.3DRep";
00501         }
00502         else
00503         {
00504                 fileName= "urn:3DXML:" + repName + ".3DRep";
00505         }
00506         return xmlFileName(fileName);
00507 }
00508 
00509 void GLC_WorldTo3dxml::writeGeometry(const GLC_Mesh* pMesh)
00510 {
00511         // Get the list of material id
00512         QList<GLC_uint> materialList= pMesh->materialIds();
00513         const int materialCount= materialList.size();
00514 
00515         m_pOutStream->writeStartElement("Rep");
00516         m_pOutStream->writeAttribute("xsi:type", "PolygonalRepType");
00517         m_pOutStream->writeAttribute("id", QString::number(++m_CurrentId));
00518         const double masterAccuracy= pMesh->getLodAccuracy(0);
00519         m_pOutStream->writeAttribute("accuracy", QString::number(masterAccuracy));
00520         m_pOutStream->writeAttribute("solid", "1");
00521         const int lodCount= pMesh->lodCount();
00522         if (lodCount > 1)
00523         {
00524                 // The mesh contains LOD
00525                 for (int i= 1; i < lodCount; ++i)
00526                 {
00527                         const double lodAccuracy= pMesh->getLodAccuracy(i);
00528                         m_pOutStream->writeStartElement("PolygonalLOD");
00529                         m_pOutStream->writeAttribute("accuracy", QString::number(lodAccuracy));
00530                         m_pOutStream->writeStartElement("Faces");
00531                         for (int matIndex= 0; matIndex < materialCount; ++matIndex)
00532                         {
00533                                 const GLC_uint materialId= materialList.at(matIndex);
00534                                 if (pMesh->lodContainsMaterial(i, materialId))
00535                                 {
00536                                         writeGeometryFace(pMesh, i, materialId);
00537                                 }
00538                         }
00539                         m_pOutStream->writeEndElement(); // Faces
00540                         m_pOutStream->writeEndElement(); // PolygonalLOD
00541                 }
00542         }
00543 
00544         // Master LOD
00545         m_pOutStream->writeStartElement("Faces");
00546         for (int matIndex= 0; matIndex < materialCount; ++matIndex)
00547         {
00548                 const GLC_uint materialId= materialList.at(matIndex);
00549                 if (pMesh->lodContainsMaterial(0, materialId))
00550                 {
00551                         writeGeometryFace(pMesh, 0, materialId);
00552                 }
00553         }
00554         m_pOutStream->writeEndElement(); // Faces
00555         if (!pMesh->wireDataIsEmpty())
00556         {
00557                 writeEdges(pMesh);
00558         }
00559 
00560         // Save Bulk data
00561         m_pOutStream->writeStartElement("VertexBuffer");
00562         {
00563                 // Get positions
00564                 GLfloatVector positionVector= pMesh->positionVector();
00565                 QString positions;
00566                 const int size= positionVector.size();
00567                 for (int i= 0; i < size; i+=3)
00568                 {
00569                         positions.append(QString::number(positionVector.at(i)));
00570                         positions.append(' ');
00571                         positions.append(QString::number(positionVector.at(i + 1)));
00572                         positions.append(' ');
00573                         positions.append(QString::number(positionVector.at(i + 2)));
00574                         positions.append(", ");
00575                 }
00576                 positions.remove(positions.size() - 2, 2);
00577                 m_pOutStream->writeTextElement("Positions", positions);
00578         }
00579         {
00580                 // Get normals
00581                 GLfloatVector normalVector= pMesh->normalVector();
00582                 QString normals;
00583                 const int size= normalVector.size();
00584                 for (int i= 0; i < size; i+=3)
00585                 {
00586                         normals.append(QString::number(normalVector.at(i)));
00587                         normals.append(' ');
00588                         normals.append(QString::number(normalVector.at(i + 1)));
00589                         normals.append(' ');
00590                         normals.append(QString::number(normalVector.at(i + 2)));
00591                         normals.append(", ");
00592                 }
00593                 normals.remove(normals.size() - 2, 2);
00594                 m_pOutStream->writeTextElement("Normals", normals);
00595         }
00596         {
00597                 // Get texture coordinates
00598                 GLfloatVector texelVector= pMesh->texelVector();
00599                 if (!texelVector.isEmpty())
00600                 {
00601                         QString texels;
00602                         const int size= texelVector.size();
00603                         for (int i= 0; i < size; i+=2)
00604                         {
00605                                 texels.append(QString::number(texelVector.at(i)));
00606                                 texels.append(' ');
00607                                 texels.append(QString::number(texelVector.at(i + 1)));
00608                                 texels.append(", ");
00609                         }
00610                         texels.remove(texels.size() - 2, 2);
00611 
00612                         m_pOutStream->writeStartElement("TextureCoordinates");
00613                         m_pOutStream->writeAttribute("dimension", "2D");
00614                         m_pOutStream->writeAttribute("channel", "0");
00615                         m_pOutStream->writeCharacters(texels);
00616                         m_pOutStream->writeEndElement(); // TexturesCoordinates
00617                 }
00618         }
00619 
00620 
00621         m_pOutStream->writeEndElement(); // VertexBuffer
00622         m_pOutStream->writeEndElement(); // Rep
00623 
00624 }
00625 void GLC_WorldTo3dxml::writeGeometryFace(const GLC_Mesh* pMesh, int lod, GLC_uint materialId)
00626 {
00627         m_pOutStream->writeStartElement("Face");
00628         if (pMesh->containsTriangles(lod, materialId))
00629         {
00630                 QVector<GLuint> triangleIndex= pMesh->getTrianglesIndex(lod, materialId);
00631                 QString indexString;
00632                 const int indexSize= triangleIndex.size();
00633                 for (int index= 0; index < indexSize; ++index)
00634                 {
00635                         indexString.append(QString::number(triangleIndex.at(index)));
00636                         indexString.append(' ');
00637                 }
00638                 indexString.remove(indexString.size() - 1, 1);
00639                 m_pOutStream->writeAttribute("triangles", indexString);
00640         }
00641         if (pMesh->containsStrips(lod, materialId))
00642         {
00643                 QList<QVector<GLuint> > stripsIndex= pMesh->getStripsIndex(lod, materialId);
00644                 QString indexStrips;
00645                 const int stripCount= stripsIndex.size();
00646                 for (int stripIndex= 0; stripIndex < stripCount; ++stripIndex)
00647                 {
00648                         QVector<GLuint> currentStripIndex= stripsIndex.at(stripIndex);
00649                         QString currentIndex;
00650                         const int indexSize= currentStripIndex.size();
00651                         for (int index= 0; index < indexSize; ++index)
00652                         {
00653                                 currentIndex.append(QString::number(currentStripIndex.at(index)));
00654                                 currentIndex.append(' ');
00655                         }
00656                         currentIndex.remove(currentIndex.size() - 1, 1);
00657                         indexStrips.append(currentIndex);
00658                         indexStrips.append(',');
00659                 }
00660                 indexStrips.remove(indexStrips.size() - 1, 1);
00661                 m_pOutStream->writeAttribute("strips", indexStrips);
00662         }
00663         if (pMesh->containsFans(lod, materialId))
00664         {
00665                 QList<QVector<GLuint> > fansIndex= pMesh->getFansIndex(lod, materialId);
00666                 QString indexFans;
00667                 const int fanCount= fansIndex.size();
00668                 for (int fanIndex= 0; fanIndex < fanCount; ++fanIndex)
00669                 {
00670                         QVector<GLuint> currentFanIndex= fansIndex.at(fanIndex);
00671                         QString currentIndex;
00672                         const int indexSize= currentFanIndex.size();
00673                         for (int index= 0; index < indexSize; ++index)
00674                         {
00675                                 currentIndex.append(QString::number(currentFanIndex.at(index)));
00676                                 currentIndex.append(' ');
00677                         }
00678                         currentIndex.remove(currentIndex.size() - 1, 1);
00679                         indexFans.append(currentIndex);
00680                         indexFans.append(',');
00681                 }
00682                 indexFans.remove(indexFans.size() - 1, 1);
00683                 m_pOutStream->writeAttribute("fans", indexFans);
00684         }
00685 
00686         writeSurfaceAttributes(pMesh->material(materialId));
00687 
00688         m_pOutStream->writeEndElement(); // Face
00689 
00690 }
00691 
00692 void GLC_WorldTo3dxml::writeSurfaceAttributes(const GLC_Material* pMaterial)
00693 {
00694         QColor diffuseColor= pMaterial->diffuseColor();
00695         m_pOutStream->writeStartElement("SurfaceAttributes");
00696         if (m_ExportMaterial)
00697         {
00698                 const QString material3dxmlId=(QString::number(m_MaterialIdToMaterialId.value(pMaterial->id())));
00699                 m_pOutStream->writeStartElement("MaterialApplication");
00700                         m_pOutStream->writeAttribute("xsi:type", "MaterialApplicationType");
00701                         m_pOutStream->writeAttribute("mappingChannel", "0");
00702                         m_pOutStream->writeStartElement("MaterialId");
00703                                 m_pOutStream->writeAttribute("id", "urn:3DXML:CATMaterialRef.3dxml#" + material3dxmlId);
00704                         m_pOutStream->writeEndElement(); // MaterialId
00705                 m_pOutStream->writeEndElement(); // MaterialApplication
00706         }
00707         else
00708         {
00709                 m_pOutStream->writeStartElement("Color");
00710                         m_pOutStream->writeAttribute("xsi:type", "RGBAColorType");
00711                         m_pOutStream->writeAttribute("red", QString::number(diffuseColor.redF()));
00712                         m_pOutStream->writeAttribute("green", QString::number(diffuseColor.greenF()));
00713                         m_pOutStream->writeAttribute("blue", QString::number(diffuseColor.blueF()));
00714                         m_pOutStream->writeAttribute("alpha", QString::number(diffuseColor.alphaF()));
00715                 m_pOutStream->writeEndElement(); // Color
00716         }
00717         m_pOutStream->writeEndElement(); // SurfaceAttributes
00718 }
00719 
00720 void GLC_WorldTo3dxml::writeEdges(const GLC_Mesh* pMesh)
00721 {
00722         m_pOutStream->writeStartElement("Edges");
00723         writeLineAttributes(pMesh->wireColor());
00724 
00725         GLfloatVector positionVector= pMesh->wirePositionVector();
00726         const int polylineCount= pMesh->wirePolylineCount();
00727         for (int i= 0; i < polylineCount; ++i)
00728         {
00729                 m_pOutStream->writeStartElement("Polyline");
00730                 QString polylinePosition;
00731                 const GLuint offset= pMesh->wirePolylineOffset(i);
00732                 const GLsizei size= pMesh->wirePolylineSize(i);
00733                 for (GLsizei index= 0; index < size; ++index)
00734                 {
00735                         const int startIndex= 3 * (offset + index);
00736                         polylinePosition.append(QString::number(positionVector.at(startIndex)));
00737                         polylinePosition.append(' ');
00738                         polylinePosition.append(QString::number(positionVector.at(startIndex + 1)));
00739                         polylinePosition.append(' ');
00740                         polylinePosition.append(QString::number(positionVector.at(startIndex + 2)));
00741                         polylinePosition.append(',');
00742                 }
00743                 polylinePosition.remove(polylinePosition.size() - 1, 1);
00744                 m_pOutStream->writeAttribute("vertices", polylinePosition);
00745                 m_pOutStream->writeEndElement(); // Polyline
00746         }
00747         m_pOutStream->writeEndElement(); // Edges
00748 }
00749 
00750 void GLC_WorldTo3dxml::writeLineAttributes(const QColor& color)
00751 {
00752         m_pOutStream->writeStartElement("LineAttributes");
00753         m_pOutStream->writeAttribute("lineType", "SOLID");
00754         m_pOutStream->writeAttribute("thickness", "1");
00755                 m_pOutStream->writeStartElement("Color");
00756                         m_pOutStream->writeAttribute("xsi:type", "RGBAColorType");
00757                         m_pOutStream->writeAttribute("red", QString::number(color.redF()));
00758                         m_pOutStream->writeAttribute("green", QString::number(color.greenF()));
00759                         m_pOutStream->writeAttribute("blue", QString::number(color.blueF()));
00760                         m_pOutStream->writeAttribute("alpha", QString::number(color.alphaF()));
00761                 m_pOutStream->writeEndElement(); // Color
00762         m_pOutStream->writeEndElement(); // LineAttributes
00763 }
00764 
00765 void GLC_WorldTo3dxml::writeMaterial(const GLC_Material* pMaterial)
00766 {
00767         const GLC_uint materialId= pMaterial->id();
00768         QString materialName;
00769         if (pMaterial->name().isEmpty())
00770         {
00771                 materialName= "Material_0" + QString::number(materialId);
00772         }
00773         else
00774         {
00775                 materialName= symplifyName(pMaterial->name());
00776         }
00777 
00778 
00779         m_MaterialIdToMaterialName.insert(materialId, materialName);
00780 
00781         const QString fileName= xmlFileName(materialName + "_Rendering.3DRep");
00782         setStreamWriterToFile(fileName);
00783 
00784         // Begin to write the material file
00785         m_pOutStream->writeStartDocument();
00786         m_pOutStream->writeStartElement("Osm");
00787                 m_pOutStream->writeAttribute("xmlns", "http://www.3ds.com/xsd/osm.xsd");
00788                 m_pOutStream->writeAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
00789                 m_pOutStream->writeAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink");
00790                 m_pOutStream->writeAttribute("xsi:schemaLocation", "http://www.3ds.com/xsd/3DXML ./osm.xsd");
00791                 m_pOutStream->writeStartElement("Feature");
00792                         m_pOutStream->writeAttribute("Alias", "RenderingRootFeature");
00793                         m_pOutStream->writeAttribute("Id", "1");
00794                         m_pOutStream->writeAttribute("StartUp", "RenderingRootFeature");
00795                 m_pOutStream->writeEndElement(); // Feature
00796                 m_pOutStream->writeStartElement("Feature");
00797                         m_pOutStream->writeAttribute("Alias", "RenderingFeature");
00798                         m_pOutStream->writeAttribute("Id", "2");
00799                         m_pOutStream->writeAttribute("StartUp", "RenderingFeature");
00800                         m_pOutStream->writeAttribute("Aggregating", "1");
00801 
00802                         writeMaterialAttributtes("Filtering", "int", "1");
00803                         writeMaterialAttributtes("Rotation", "double", "0");
00804                         writeMaterialAttributtes("PreviewType", "int", "1");
00805                         writeMaterialAttributtes("AmbientCoef", "double", "1");
00806                         writeMaterialAttributtes("DiffuseCoef", "double", "1");
00807                         writeMaterialAttributtes("SpecularCoef", "double", "1");
00808                         writeMaterialAttributtes("EmissiveCoef", "double", "0");
00809                         writeMaterialAttributtes("AlphaTest", "boolean", "false");
00810                         writeMaterialAttributtes("TextureFunction", "int", "0");
00811                         writeMaterialAttributtes("MappingType", "int", "2");
00812                         writeMaterialAttributtes("Refraction", "double", "1");
00813                         writeMaterialAttributtes("TextureDimension", "int", "2");
00814                         writeMaterialAttributtes("TranslationU", "double", "0");
00815                         writeMaterialAttributtes("TranslationV", "double", "0");
00816                         writeMaterialAttributtes("FlipU", "boolean", "false");
00817                         writeMaterialAttributtes("FlipV", "boolean", "false");
00818                         writeMaterialAttributtes("WrappingModeU", "int", "1");
00819                         writeMaterialAttributtes("WrappingModeV", "int", "1");
00820                         writeMaterialAttributtes("ScaleU", "double", "1");
00821                         writeMaterialAttributtes("ScaleV", "double", "1");
00822                         writeMaterialAttributtes("Reflectivity", "double", "0.1");
00823                         writeMaterialAttributtes("BlendColor", "double", "[1,1,1]");
00824 
00825                         writeMaterialAttributtes("Transparency", "double", QString::number(1.0 - pMaterial->opacity()));
00826                         double specularExponent= pMaterial->shininess() / 128.0;
00827                         writeMaterialAttributtes("SpecularExponent", "double", QString::number(specularExponent));
00828                         writeMaterialAttributtes("DiffuseColor", "double", colorToString(pMaterial->diffuseColor()));
00829                         writeMaterialAttributtes("SpecularColor", "double", colorToString(pMaterial->specularColor()));
00830                         writeMaterialAttributtes("AmbientColor", "double", colorToString(pMaterial->ambientColor()));
00831                         writeMaterialAttributtes("EmissiveColor", "double", colorToString(pMaterial->emissiveColor()));
00832                         if (pMaterial->hasTexture())
00833                         {
00834                                 Q_ASSERT(m_MaterialIdTo3dxmlImageId.contains(pMaterial->id()));
00835                                 const QString imageId(QString::number(m_MaterialIdTo3dxmlImageId.value(pMaterial->id())));
00836 
00837                                 writeMaterialAttributtes("TextureImage", "external", "urn:3DXML:CATRepImage.3dxml#" + imageId);
00838                         }
00839                 m_pOutStream->writeEndElement(); // Feature
00840         m_pOutStream->writeEndElement(); // Osm
00841         m_pOutStream->writeEndDocument();
00842 }
00843 
00844 void GLC_WorldTo3dxml::writeMaterialAttributtes(const QString& name, const QString& type, const QString& value)
00845 {
00846         m_pOutStream->writeStartElement("Attr");
00847                 m_pOutStream->writeAttribute("Name", name);
00848                 m_pOutStream->writeAttribute("Type", type);
00849                 m_pOutStream->writeAttribute("Value", value);
00850         m_pOutStream->writeEndElement(); // Attr
00851 }
00852 
00853 QString GLC_WorldTo3dxml::colorToString(const QColor& color)
00854 {
00855         return QString('[' + QString::number(color.redF()) + ',' + QString::number(color.greenF()) + ',' + QString::number(color.blueF()) + ']');
00856 }
00857 
00858 void GLC_WorldTo3dxml::writeCatRepImageFile(const QList<GLC_Material*>& materialList)
00859 {
00860         unsigned int currentId= 0;
00861         const QString fileName("CATRepImage.3dxml");
00862         setStreamWriterToFile(fileName);
00863 
00864         // Begin to write the rep image file
00865         m_pOutStream->writeStartDocument();
00866         m_pOutStream->writeStartElement("Model_3dxml");
00867                 m_pOutStream->writeAttribute("xmlns", "http://www.3ds.com/xsd/3DXML");
00868                 m_pOutStream->writeAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
00869                 m_pOutStream->writeAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink");
00870                 m_pOutStream->writeAttribute("xsi:schemaLocation", "http://www.3ds.com/xsd/3DXML ./3DXML.xsd");
00871                 writeHeader();
00872                 m_pOutStream->writeStartElement("CATRepImage");
00873                         m_pOutStream->writeAttribute("root", QString::number(currentId));
00874                         const int size= materialList.size();
00875                         for (int i= 0; i < size; ++i)
00876                         {
00877                                 writeCATRepresentationImage(materialList.at(i), ++currentId);
00878                         }
00879                 m_pOutStream->writeEndElement(); // CATRepImage
00880         m_pOutStream->writeEndElement(); // Model_3dxml
00881         m_pOutStream->writeEndDocument();
00882 }
00883 
00884 void GLC_WorldTo3dxml::writeCATRepresentationImage(const GLC_Material* pMat, unsigned int id)
00885 {
00886         Q_ASSERT(pMat->hasTexture());
00887         m_MaterialIdTo3dxmlImageId.insert(pMat->id(), id);
00888 
00889         const QString imageName= pMat->name();
00890         QString imageFileName;
00891         QString imageFormat;
00892         const QString textureFileName= pMat->textureHandle()->fileName();
00893         if (textureFileName.isEmpty())
00894         {
00895                 imageFormat= "jpg";
00896                 if (imageName.isEmpty())
00897                 {
00898                         imageFileName= xmlFileName("textureImage." + imageFormat);
00899                 }
00900                 else
00901                 {
00902                         imageFileName= xmlFileName(imageName + '.' + imageFormat);
00903                 }
00904         }
00905         else
00906         {
00907                 imageFormat= QFileInfo(textureFileName).suffix();
00908                 imageFileName= xmlFileName(QFileInfo(textureFileName).fileName());
00909         }
00910         m_MaterialIdToTexture3dxmlName.insert(pMat->id(), imageFileName);
00911 
00912         m_pOutStream->writeStartElement("CATRepresentationImage");
00913                 m_pOutStream->writeAttribute("xsi:type", "CATRepresentationImageType");
00914                 m_pOutStream->writeAttribute("id", QString::number(id));
00915                 m_pOutStream->writeAttribute("name", imageName);
00916                 m_pOutStream->writeAttribute("format", imageFormat);
00917                 m_pOutStream->writeAttribute("associatedFile", QString("urn:3DXML:" + imageFileName));
00918 
00919                 m_pOutStream->writeTextElement("PLM_ExternalID", imageName);
00920                 m_pOutStream->writeTextElement("V_PrimaryMimeType", imageFormat);
00921                 m_pOutStream->writeTextElement("V_PrimaryFileName", imageFileName);
00922         m_pOutStream->writeEndElement(); // CATRepresentationImage
00923 }
00924 
00925 void GLC_WorldTo3dxml::writeAllMaterialRelatedFilesIn3dxml()
00926 {
00927         m_MaterialIdToMaterialName.clear();
00928         m_MaterialIdToMaterialId.clear();
00929         m_MaterialIdToTexture3dxmlName.clear();
00930         m_MaterialIdTo3dxmlImageId.clear();
00931 
00932         // Get the list of material
00933         QList<GLC_Material*> materialList= m_World.listOfMaterials();
00934 
00935         // Create the list of textured material and modified material list
00936         QList<GLC_Material*> texturedMaterial;
00937         const int size= materialList.size();
00938         for (int i= 0; i < size; ++i)
00939         {
00940                 if (materialList.at(i)->hasTexture())
00941                 {
00942                         texturedMaterial.append(materialList.at(i));
00943                 }
00944         }
00945 
00946         if (!texturedMaterial.isEmpty())
00947         {
00948                 writeCatRepImageFile(texturedMaterial);
00949                 writeImageFileIn3dxml(texturedMaterial);
00950         }
00951 
00952 
00953         // Write material 3DRep in the 3DXML
00954         for (int i= 0; i < size; ++i)
00955         {
00956                 writeMaterial(materialList.at(i));
00957         }
00958 
00959         writeCatMaterialRef(materialList);
00960 
00961 
00962 
00963 }
00964 void GLC_WorldTo3dxml::writeImageFileIn3dxml(const QList<GLC_Material*>& materialList)
00965 {
00966         const int size= materialList.size();
00967         Q_ASSERT(size == m_MaterialIdToTexture3dxmlName.size());
00968         for (int i= 0; i < size; ++i)
00969         {
00970                 const GLC_Material* pCurrentMaterial= materialList.at(i);
00971                 const GLC_Texture* pTexture= pCurrentMaterial->textureHandle();
00972                 const QString imageName(m_MaterialIdToTexture3dxmlName.value(pCurrentMaterial->id()));
00973                 // Get the texture image
00974                 if (!pTexture->fileName().isEmpty())
00975                 {
00976                         // Try to load the texture
00977                         QImage textureImage(pTexture->fileName());
00978                         if (! textureImage.isNull())
00979                         {
00980                                 addImageTextureTo3dxml(textureImage, imageName);
00981                         }
00982                         else
00983                         {
00984                                 addImageTextureTo3dxml(pTexture->imageOfTexture(), imageName);
00985                         }
00986                 }
00987                 else
00988                 {
00989                         addImageTextureTo3dxml(pTexture->imageOfTexture(), imageName);
00990                 }
00991         }
00992 
00993 }
00994 
00995 void GLC_WorldTo3dxml::writeCatMaterialRef(const QList<GLC_Material*>& materialList)
00996 {
00997         const QString fileName("CATMaterialRef.3dxml");
00998 
00999         setStreamWriterToFile(fileName);
01000 
01001         unsigned int currentId= 0;
01002 
01003         // Begin to write the rep image file
01004         m_pOutStream->writeStartDocument();
01005         m_pOutStream->writeStartElement("Model_3dxml");
01006                 m_pOutStream->writeAttribute("xmlns", "http://www.3ds.com/xsd/3DXML");
01007                 m_pOutStream->writeAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
01008                 m_pOutStream->writeAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink");
01009                 m_pOutStream->writeAttribute("xsi:schemaLocation", "http://www.3ds.com/xsd/3DXML ./3DXML.xsd");
01010                 writeHeader();
01011                 m_pOutStream->writeStartElement("CATMaterialRef");
01012                         m_pOutStream->writeAttribute("root", QString::number(currentId));
01013                         const int size= materialList.size();
01014                         for (int i= 0; i < size; ++i)
01015                         {
01016                                 writeMaterialToCatMaterialRef(materialList.at(i), &(++currentId));
01017                         }
01018                 m_pOutStream->writeEndElement(); // CATMaterialRef
01019         m_pOutStream->writeEndElement(); // Model_3dxml
01020         m_pOutStream->writeEndDocument();
01021 }
01022 
01023 void GLC_WorldTo3dxml::writeMaterialToCatMaterialRef(const GLC_Material* pMat, unsigned int* id)
01024 {
01025         const QString materialName= m_MaterialIdToMaterialName.value(pMat->id());
01026         m_MaterialIdToMaterialId.insert(pMat->id(), *id);
01027 
01028         m_pOutStream->writeStartElement("CATMatReference");
01029                 m_pOutStream->writeAttribute("xsi:type", "CATMatReferenceType");
01030                 m_pOutStream->writeAttribute("id", QString::number(*id));
01031                 m_pOutStream->writeAttribute("name", materialName);
01032                 m_pOutStream->writeTextElement("PLM_ExternalID", materialName);
01033         m_pOutStream->writeEndElement(); // CATMatReference
01034 
01035         const QString domainName= materialName + "_Rendering";
01036         m_pOutStream->writeStartElement("MaterialDomain");
01037                 m_pOutStream->writeAttribute("xsi:type", "MaterialDomainType");
01038                 m_pOutStream->writeAttribute("id", QString::number(++(*id)));
01039                 m_pOutStream->writeAttribute("name", domainName);
01040                 m_pOutStream->writeAttribute("format", "TECHREP");
01041                 const QString associatedFileName("urn:3DXML:" + domainName + ".3DRep");
01042                 m_pOutStream->writeAttribute("associatedFile", associatedFileName);
01043                 m_pOutStream->writeAttribute("version", "1.0");
01044                 m_pOutStream->writeTextElement("PLM_ExternalID", domainName);
01045                 if (pMat->hasTexture())
01046                 {
01047                         m_pOutStream->writeStartElement("PLMRelation");
01048                                 m_pOutStream->writeTextElement("C_Semantics", "Reference");
01049                                 m_pOutStream->writeTextElement("C_Role", "CATMaterialReferenceToTextureLink");
01050                                 m_pOutStream->writeStartElement("Ids");
01051                                         const QString imageId(QString::number(m_MaterialIdTo3dxmlImageId.value(pMat->id())));
01052                                         m_pOutStream->writeTextElement("id", "urn:3DXML:CATRepImage.3dxml#" + imageId);
01053                                 m_pOutStream->writeEndElement(); // Ids
01054                         m_pOutStream->writeEndElement(); // PLMRelation
01055                 }
01056                 m_pOutStream->writeTextElement("V_MatDomain", "Rendering");
01057         m_pOutStream->writeEndElement(); // MaterialDomain
01058 
01059         m_pOutStream->writeStartElement("MaterialDomainInstance");
01060                 m_pOutStream->writeAttribute("xsi:type", "MaterialDomainInstanceType");
01061                 m_pOutStream->writeAttribute("id", QString::number(++(*id)));
01062                 m_pOutStream->writeAttribute("name", materialName + ".1");
01063                 m_pOutStream->writeTextElement("PLM_ExternalID", materialName + ".1");
01064                 m_pOutStream->writeTextElement("IsAggregatedBy", QString::number((*id) - 2));
01065                 m_pOutStream->writeTextElement("IsInstanceOf", QString::number((*id) - 1));
01066         m_pOutStream->writeEndElement(); // MaterialDomainInstance
01067 }
01068 
01069 void GLC_WorldTo3dxml::addImageTextureTo3dxml(const QImage& image, const QString& fileName)
01070 {
01071         delete m_pOutStream;
01072         m_pOutStream= NULL;
01073 
01074         bool success= false;
01075         if (NULL != m_p3dxmlArchive)
01076         {
01077                 if (NULL != m_pCurrentZipFile)
01078                 {
01079                         m_pCurrentZipFile->close();
01080                         delete m_pOutStream;
01081                         delete m_pCurrentZipFile;
01082                 }
01083                 QuaZipNewInfo quazipNewInfo(fileName);
01084                 m_pCurrentZipFile= new QuaZipFile(m_p3dxmlArchive);
01085                 success= m_pCurrentZipFile->open(QIODevice::WriteOnly, quazipNewInfo);
01086                 if (success)
01087                 {
01088                         image.save(m_pCurrentZipFile, QFileInfo(fileName).suffix().toAscii().constData());
01089                         m_pCurrentZipFile->close();
01090                         delete m_pCurrentZipFile;
01091                         m_pCurrentZipFile= NULL;
01092                 }
01093         }
01094         else
01095         {
01096                 delete m_pCurrentFile;
01097                 m_pCurrentFile= new QFile(m_AbsolutePath + fileName);
01098                 success= m_pCurrentFile->open(QIODevice::WriteOnly);
01099                 if (success)
01100                 {
01101                         image.save(m_pCurrentFile, QFileInfo(fileName).suffix().toAscii().constData());
01102                         delete m_pCurrentFile;
01103                         m_pCurrentFile= NULL;
01104                 }
01105         }
01106 }
01107 
01108 QString GLC_WorldTo3dxml::xmlFileName(QString fileName)
01109 {
01110         QString prefix;
01111         if (fileName.contains("urn:3DXML:"))
01112         {
01113                 prefix= "urn:3DXML:";
01114                 fileName.remove(prefix);
01115         }
01116 
01117         fileName= symplifyName(fileName);
01118 
01119 
01120 
01121         QString newName;
01122         if (!m_3dxmlFileSet.contains(prefix + fileName))
01123         {
01124                 fileName.prepend(prefix);
01125                 m_3dxmlFileSet << fileName;
01126                 newName= fileName;
01127         }
01128         else
01129         {
01130                 newName= QFileInfo(fileName).completeBaseName() + QString::number(++m_FileNameIncrement) + '.' + QFileInfo(fileName).suffix();
01131                 newName.prepend(prefix);
01132         }
01133         return newName;
01134 }
01135 
01136 void GLC_WorldTo3dxml::writeExtensionAttributes(GLC_Attributes* pAttributes)
01137 {
01138         QList<QString> attributesNames= pAttributes->names();
01139         const int size= attributesNames.size();
01140         for (int i= 0; i < size; ++i)
01141         {
01142                 const QString name= attributesNames.at(i);
01143                 QString value= pAttributes->value(name);
01144                 m_pOutStream->writeStartElement("Attribute");
01145                         m_pOutStream->writeAttribute("name", name);
01146                         if (name == "FILEPATH")
01147                         {
01148                                 QDir thisPath(m_AbsolutePath);
01149                                 value= thisPath.relativeFilePath(value);
01150                         }
01151                         m_pOutStream->writeAttribute("value", value);
01152                 m_pOutStream->writeEndElement(); // Attribute
01153         }
01154 }
01155 
01156 void GLC_WorldTo3dxml::writeOccurenceDefaultViewProperty(const GLC_StructOccurence* pOccurence)
01157 {
01158         QList<unsigned int> path= instancePath(pOccurence);
01159 
01160         GLC_3DViewInstance* pInstance= m_World.collection()->instanceHandle(pOccurence->id());
01161         Q_ASSERT(NULL != pInstance);
01162         const bool isVisible= pOccurence->isVisible();
01163         m_pOutStream->writeStartElement("DefaultViewProperty");
01164         m_pOutStream->writeStartElement("OccurenceId");
01165         const QString prefix= "urn:3DXML:" + QFileInfo(m_FileName).fileName() + "#";
01166         const int pathSize= path.size();
01167         for (int i= 0; i < pathSize; ++i)
01168         {
01169                 m_pOutStream->writeTextElement("id", prefix + QString::number(path.at(i)));
01170         }
01171         m_pOutStream->writeEndElement(); // OccurenceId
01172 
01173         if (pOccurence->isFlexible())
01174         {
01175                 m_pOutStream->writeTextElement("RelativePosition", matrixString(pOccurence->occurrenceRelativeMatrix()));
01176         }
01177 
01178         if (!isVisible || !pInstance->renderPropertiesHandle()->isDefault())
01179         {
01180                 qDebug() << "(!isVisible || !pInstance->renderPropertiesHandle()->isDefault())";
01181                 m_pOutStream->writeStartElement("GraphicProperties");
01182                 m_pOutStream->writeAttribute("xsi:type", "GraphicPropertiesType");
01183                 if (! isVisible)
01184                 {
01185                         m_pOutStream->writeStartElement("GeneralAttributes");
01186                                 m_pOutStream->writeAttribute("xsi:type", "GeneralAttributesType");
01187                                 m_pOutStream->writeAttribute("visible", "false");
01188                                 m_pOutStream->writeAttribute("selectable", "true");
01189                         m_pOutStream->writeEndElement(); // GeneralAttributes
01190                 }
01191                 if (!pInstance->renderPropertiesHandle()->isDefault())
01192                 {
01193                         const GLC_RenderProperties* pProperties= pInstance->renderPropertiesHandle();
01194                         if ((pProperties->renderingMode() == glc::OverwriteTransparency))
01195                         {
01196                                 m_pOutStream->writeStartElement("SurfaceAttributes");
01197                                 m_pOutStream->writeAttribute("xsi:type", "SurfaceAttributesType");
01198                                         m_pOutStream->writeStartElement("Color");
01199                                                 m_pOutStream->writeAttribute("xsi:type", "RGBAColorType");
01200                                                 m_pOutStream->writeAttribute("red", "-1");
01201                                                 m_pOutStream->writeAttribute("green", "-1");
01202                                                 m_pOutStream->writeAttribute("blue", "-1");
01203                                                 m_pOutStream->writeAttribute("alpha", QString::number(pProperties->overwriteTransparency()));
01204                                         m_pOutStream->writeEndElement(); // Color
01205                                 m_pOutStream->writeEndElement(); // SurfaceAttributes
01206                         }
01207                         else if ((pProperties->renderingMode() == glc::OverwriteTransparencyAndMaterial))
01208                         {
01209                                 GLC_Material* pMaterial= pProperties->overwriteMaterial();
01210                                 m_pOutStream->writeStartElement("SurfaceAttributes");
01211                                 m_pOutStream->writeAttribute("xsi:type", "SurfaceAttributesType");
01212                                         m_pOutStream->writeStartElement("Color");
01213                                                 m_pOutStream->writeAttribute("xsi:type", "RGBAColorType");
01214                                                 m_pOutStream->writeAttribute("red", QString::number(pMaterial->diffuseColor().redF()));
01215                                                 m_pOutStream->writeAttribute("green", QString::number(pMaterial->diffuseColor().greenF()));
01216                                                 m_pOutStream->writeAttribute("blue", QString::number(pMaterial->diffuseColor().blueF()));
01217                                                 m_pOutStream->writeAttribute("alpha", QString::number(pProperties->overwriteTransparency()));
01218                                         m_pOutStream->writeEndElement(); // Color
01219                                 m_pOutStream->writeEndElement(); // SurfaceAttributes
01220                         }
01221                         else if ((pProperties->renderingMode() == glc::OverwriteMaterial))
01222                         {
01223                                 GLC_Material* pMaterial= pProperties->overwriteMaterial();
01224                                 m_pOutStream->writeStartElement("SurfaceAttributes");
01225                                 m_pOutStream->writeAttribute("xsi:type", "SurfaceAttributesType");
01226                                         m_pOutStream->writeStartElement("Color");
01227                                                 m_pOutStream->writeAttribute("xsi:type", "RGBAColorType");
01228                                                 m_pOutStream->writeAttribute("red", QString::number(pMaterial->diffuseColor().redF()));
01229                                                 m_pOutStream->writeAttribute("green", QString::number(pMaterial->diffuseColor().greenF()));
01230                                                 m_pOutStream->writeAttribute("blue", QString::number(pMaterial->diffuseColor().blueF()));
01231                                                 m_pOutStream->writeAttribute("alpha", QString::number(pMaterial->opacity()));
01232                                         m_pOutStream->writeEndElement(); // Color
01233                                 m_pOutStream->writeEndElement(); // SurfaceAttributes
01234                         }
01235 
01236                 }
01237                 m_pOutStream->writeEndElement(); // GraphicProperties
01238         }
01239         m_pOutStream->writeEndElement(); // DefaultViewProperty
01240 }
01241 
01242 bool GLC_WorldTo3dxml::continu()
01243 {
01244         bool continuValue= true;
01245         if (NULL != m_pReadWriteLock)
01246         {
01247                 Q_ASSERT(NULL != m_pIsInterupted);
01248                 m_pReadWriteLock->lockForRead();
01249                 continuValue= !(*m_pIsInterupted);
01250                 m_pReadWriteLock->unlock();
01251         }
01252         return continuValue;
01253 }
01254 
01255 QString GLC_WorldTo3dxml::symplifyName(QString name)
01256 {
01257         const int nameSize= name.size();
01258         for (int i= 0; i < nameSize; ++i)
01259         {
01260                 if (!name.at(i).isLetterOrNumber() && (name.at(i) != '.'))
01261                 {
01262                         name.replace(i, 1, '_');
01263                 }
01264         }
01265 
01266         return name;
01267 }
01268 
01269 QList<unsigned int> GLC_WorldTo3dxml::instancePath(const GLC_StructOccurence* pOccurence)
01270 {
01271         QList<unsigned int> path;
01272         if (!pOccurence->isOrphan())
01273         {
01274                 GLC_StructInstance* pInstance= pOccurence->structInstance();
01275                 Q_ASSERT(m_InstanceToIdHash.contains(pInstance));
01276                 path.prepend(m_InstanceToIdHash.value(pInstance));
01277                 QList<unsigned int> subPath(instancePath(pOccurence->parent()));
01278                 subPath.append(path);
01279                 path= subPath;
01280         }
01281         return path;
01282 }

SourceForge.net Logo

©2005-2011 Laurent Ribon