GLC_lib  2.5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
glc_3dxmltoworld.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 
3  This file is part of the GLC-lib library.
4  Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
5  http://glc-lib.sourceforge.net
6 
7  GLC-lib is free software; you can redistribute it and/or modify
8  it under the terms of the GNU Lesser General Public License as published by
9  the Free Software Foundation; either version 3 of the License, or
10  (at your option) any later version.
11 
12  GLC-lib is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU Lesser General Public License for more details.
16 
17  You should have received a copy of the GNU Lesser General Public License
18  along with GLC-lib; if not, write to the Free Software
19  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 
21 *****************************************************************************/
22 
24 
25 #include "glc_3dxmltoworld.h"
26 #include "../sceneGraph/glc_world.h"
27 #include "../glc_fileformatexception.h"
28 #include "../geometry/glc_mesh.h"
29 #include "../geometry/glc_3drep.h"
30 #include "glc_xmlutil.h"
31 
32 // Quazip library
33 #include "../3rdparty/quazip/quazip.h"
34 #include "../3rdparty/quazip/quazipfile.h"
35 
36 #include <QString>
37 #include <QGLContext>
38 #include <QFileInfo>
39 #include <QSet>
40 #include <QMutexLocker>
41 
42 //using namespace glcXmlUtil;
43 
45 
46 static qint64 chunckSize= 10000000;
47 
49 : QObject()
50 , m_pStreamReader(NULL)
51 , m_FileName()
52 , m_p3dxmlArchive(NULL)
53 , m_pCurrentFile(NULL)
54 , m_RootName()
55 , m_pWorld(NULL)
56 , m_ReferenceHash()
57 , m_AssyLinkList()
58 , m_InstanceOf()
59 , m_SetOfExtRef()
60 , m_InstanceOfExtRefHash()
61 , m_ExternalReferenceHash()
62 , m_MaterialHash()
63 , m_IsInArchive(false)
64 , m_ReferenceRepHash()
65 , m_LocalRepLinkList()
66 , m_ExternRepLinkList()
67 , m_SetOfExtRep()
68 , m_pCurrentMaterial(NULL)
69 , m_TextureImagesHash()
70 , m_LoadStructureOnly(false)
71 , m_SetOfAttachedFileName()
72 , m_CurrentFileName()
73 , m_CurrentDateTime()
74 , m_V3OccurenceAttribHash()
75 , m_V4OccurenceAttribList()
76 , m_GetExternalRef3DName(false)
77 , m_ByteArrayList()
78 , m_IsVersion3(false)
79 {
80 
81 }
82 
84 {
85  delete m_pStreamReader;
86  m_pStreamReader= NULL;
87 
88  delete m_pCurrentFile;
89  delete m_p3dxmlArchive;
90 
92 
93  // Clear specific attributes hash table
94  QHash<unsigned int, V3OccurenceAttrib*>::iterator iAttrib= m_V3OccurenceAttribHash.begin();
95  while (m_V3OccurenceAttribHash.constEnd() != iAttrib)
96  {
97  delete iAttrib.value();
98  ++iAttrib;
99  }
100 
101  const int v4OccurenceAttribCount= m_V4OccurenceAttribList.count();
102  for (int i= 0; i < v4OccurenceAttribCount; ++i)
103  {
104  delete m_V4OccurenceAttribList.at(i);
105  }
106 }
107 
109 // Set Functions
111 
112 // Create an GLC_World from an input 3DXML File
113 GLC_World* GLC_3dxmlToWorld::createWorldFrom3dxml(QFile &file, bool structureOnly, bool getExternalRef)
114 {
115  clear();
116  m_pWorld= new GLC_World();
117  m_GetExternalRef3DName= getExternalRef;
118  m_LoadStructureOnly= structureOnly;
119  m_FileName= file.fileName();
120 
121  // Create the 3dxml Zip archive
122  m_p3dxmlArchive= new QuaZip(m_FileName);
123  // Trying to load archive
124  if(!m_p3dxmlArchive->open(QuaZip::mdUnzip))
125  {
126  // In this case, the 3dxml is not compressed or is not valid
128  delete m_p3dxmlArchive;
129  m_p3dxmlArchive= NULL;
130  }
131  else
132  {
133  // Get the 3DXML time stamp
134  m_CurrentDateTime= QFileInfo(m_FileName).lastModified();
135 
136  m_IsInArchive= true;
137  // Set the file Name Codec
138  //m_p3dxmlArchive->setFileNameCodec("IBM866");
139 
140  // Load the manifest
141  loadManifest();
142  }
143 
144  if (!m_LoadStructureOnly)
145  {
146  // Trying to Load CATRepImage file
147  loadCatRepImage();
148 
149  // Trying to Load CATRefMaterial File
151  }
152 
153  // Read the header
154  readHeader();
155 
156  // Load the product structure
158 
159 
160  emit currentQuantum(100);
161  return m_pWorld;
162 }
163 
164 // Create 3DRep from an 3DXML rep
166 {
167  GLC_3DRep resultRep;
168  if (glc::isArchiveString(fileName))
169  {
170  m_FileName= glc::archiveFileName(fileName);
171 
172  // Create the 3dxml Zip archive
173  m_ZipMutex.lock();
174  m_p3dxmlArchive= new QuaZip(m_FileName);
175  // Trying to load archive
176  if(!m_p3dxmlArchive->open(QuaZip::mdUnzip))
177  {
178  delete m_p3dxmlArchive;
179  return GLC_3DRep();
180  }
181  else
182  {
183  m_IsInArchive= true;
184  // Set the file Name Codec
185  //m_p3dxmlArchive->setFileNameCodec("IBM866");
186  }
187  m_ZipMutex.unlock();
189 
190  // Get the 3DXML time stamp
191  m_CurrentDateTime= QFileInfo(QFileInfo(m_FileName)).lastModified();
192  }
193  else if (glc::isFileString(fileName))
194  {
195  m_FileName= glc::archiveFileName(fileName);
197 
198  // Get the rep time stamp
199  m_CurrentDateTime= QFileInfo(m_CurrentFileName).lastModified();
200 
201  // Keep only the file name
202  QDir structureDir(QFileInfo(m_FileName).absolutePath() + QDir::separator());
203  m_CurrentFileName= structureDir.relativeFilePath(m_CurrentFileName);
204 
205  }
206  else
207  {
208  return resultRep;
209  }
210 
211 
212  setRepresentationFileName(&resultRep);
213 
214  if (QFileInfo(m_CurrentFileName).suffix().toLower() == "3dxml")
215  {
216  if (GLC_State::cacheIsUsed() && GLC_State::currentCacheManager().isUsable(m_CurrentDateTime, QFileInfo(m_FileName).baseName(), QFileInfo(m_CurrentFileName).fileName()))
217  {
219 
220  GLC_BSRep binaryRep = cacheManager.binary3DRep(QFileInfo(m_FileName).baseName(), QFileInfo(m_CurrentFileName).fileName());
221  resultRep = binaryRep.loadRep();
222  }
223  else
224  {
226  {
227  GLC_StructReference* pStructRef = createReferenceRep(QString(), NULL);
228  GLC_3DRep* pRep = NULL;
229  if ((NULL != pStructRef) && pStructRef->hasRepresentation())
230  {
231  pRep= dynamic_cast<GLC_3DRep*> (pStructRef->representationHandle());
232 
233  if (NULL != pRep)
234  {
235  resultRep = GLC_3DRep(*pRep);
236  resultRep.setName(pStructRef->name());
237  }
238  }
239  delete pStructRef;
240  }
241  }
242  }
243  else if ((QFileInfo(m_CurrentFileName).suffix().toLower() == "3drep") || (QFileInfo(m_CurrentFileName).suffix().toLower() == "xml"))
244  {
245  if (GLC_State::cacheIsUsed() && GLC_State::currentCacheManager().isUsable(m_CurrentDateTime, QFileInfo(m_FileName).baseName(), QFileInfo(m_CurrentFileName).fileName()))
246  {
248  GLC_BSRep binaryRep = cacheManager.binary3DRep(QFileInfo(m_FileName).baseName(), QFileInfo(m_CurrentFileName).fileName());
249  resultRep = binaryRep.loadRep();
250  }
251  else
252  {
254  {
255  resultRep = loadCurrentExtRep();
256  }
257  }
258  }
259  resultRep.clean();
260 
261  return resultRep;
262 }
263 
265 // Private services functions
267 // Load the 3dxml's manifest
269 {
270  setStreamReaderToFile("Manifest.xml");
272 
273  if (m_pStreamReader->atEnd() || m_pStreamReader->hasError())
274  {
275  QString message(QString("GLC_3dxmlToWorld::loadManifest Manifest file ") + m_FileName + " doesn't contains Root Element");
277  clear();
278  throw(fileFormatException);
279  }
280 
281  delete m_pStreamReader;
282  m_pStreamReader= NULL;
283 }
284 
287 {
288  delete m_pWorld;
289  m_pWorld= NULL;
290 
291  delete m_pStreamReader;
292  m_pStreamReader= NULL;
293 
294  m_ByteArrayList.clear();
295  // Clear current file
296  if (NULL != m_pCurrentFile)
297  {
298  m_pCurrentFile->close();
299  delete m_pCurrentFile;
300  m_pCurrentFile= NULL;
301  }
302 
303  // Clear the 3dxml archive
304  if (NULL != m_p3dxmlArchive)
305  {
306  m_p3dxmlArchive->close();
307  delete m_p3dxmlArchive;
308  m_p3dxmlArchive= NULL;
309  }
310 
311  m_SetOfAttachedFileName.clear();
312 
314 }
315 
316 // Go to a Rep of a xml
317 void GLC_3dxmlToWorld::goToRepId(const QString& id)
318 {
319  while(!m_pStreamReader->atEnd() && !((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "Representation")
320  && (m_pStreamReader->attributes().value("id").toString() == id)))
321  {
322  readNext();
323  }
324 
325 }
326 
327 // Go to Polygonal Rep Type
329 {
330  while(endElementNotReached(m_pStreamReader, "Representation") && !m_pStreamReader->atEnd() && !((QXmlStreamReader::StartElement == m_pStreamReader->tokenType())
331  && ((m_pStreamReader->name() == "Rep") || (m_pStreamReader->name() == "Root"))
332  && (m_pStreamReader->attributes().value("xsi:type").toString() == "PolygonalRepType")))
333  {
334  //qDebug() << m_pStreamReader->name();
335  //qDebug() << m_pStreamReader->attributes().value("xsi:type").toString();
336  readNext();
337  }
338 
339 }
340 
341 // Read the specified attribute
342 QString GLC_3dxmlToWorld::readAttribute(const QString& name, bool required)
343 {
344  QString attributeValue;
345  if (required && !m_pStreamReader->attributes().hasAttribute(name))
346  {
347  QString message(QString("required attribute ") + name + QString(" Not found"));
349  clear();
350  throw(fileFormatException);
351  }
352  else
353  {
354  attributeValue= m_pStreamReader->attributes().value(name).toString();
355  }
356  return attributeValue;
357 }
358 
360 {
362 
363  goToElement(m_pStreamReader, "Header");
364  if (m_pStreamReader->atEnd() || m_pStreamReader->hasError())
365  {
366  QString message(QString("GLC_3dxmlToWorld::readHeader Element Header Not found in ") + m_FileName);
368  clear();
369  throw(fileFormatException);
370  }
371 
372  while(endElementNotReached(m_pStreamReader, "Header"))
373  {
374  if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "SchemaVersion"))
375  {
376  QString version= getContent(m_pStreamReader, "SchemaVersion");
377  m_IsVersion3= version.startsWith('3');
378  }
379  readNext();
380  }
381 }
382 
383 // Load the product structure
385 {
386 
387  goToElement(m_pStreamReader, "ProductStructure");
388  if (m_pStreamReader->atEnd() || m_pStreamReader->hasError())
389  {
390  QString message(QString("GLC_3dxmlToWorld::loadProductStructure Element ProctStructure Not found in ") + m_FileName);
392  clear();
393  throw(fileFormatException);
394  }
395 
396  // Load the structure
397  while(endElementNotReached(m_pStreamReader, "ProductStructure"))
398  {
399  if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType())
400  && ((m_pStreamReader->name() == "Reference3D") || (m_pStreamReader->name() == "Instance3D")
401  || (m_pStreamReader->name() == "ReferenceRep") || (m_pStreamReader->name() == "InstanceRep")))
402  {
403  if (m_pStreamReader->name() == "Reference3D") loadReference3D();
404  else if (m_pStreamReader->name() == "Instance3D") loadInstance3D();
405  else if (m_pStreamReader->name() == "ReferenceRep") loadReferenceRep();
406  else loadInstanceRep();
407  }
408 
409  readNext();
410  }
411 
412  // Load Default view properties
413  while(endElementNotReached(m_pStreamReader, "Model_3dxml"))
414  {
415  if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType())
416  && ((m_pStreamReader->name() == "DefaultView") || (m_pStreamReader->name() == "GeometricRepresentationSet")))
417  {
418  if (m_pStreamReader->name() == "DefaultView") loadDefaultView();
419  else if (m_pStreamReader->name() == "GeometricRepresentationSet") loadLocalRepresentations();
420 
421  }
422  readNext();
423  }
424 
425  // Check if an error Occur
426  if (m_pStreamReader->hasError())
427  {
428  QString message(QString("GLC_3dxmlToWorld::loadProductStructure An error occur in ") + m_FileName);
430  clear();
431  throw(fileFormatException);
432  }
433 
434  // Load external ref (3DXML V3)
436 
437  // Load extern representations (3DXML V4)
439 
440  { // Link locals instance with reference
441  InstanceOfHash::iterator iInstance= m_InstanceOf.begin();
442  while (iInstance != m_InstanceOf.constEnd())
443  {
444  GLC_StructInstance* pInstance= iInstance.key();
445  GLC_StructReference* pRef= m_ReferenceHash.value(iInstance.value());
446  if (NULL == pRef)
447  {
448  QString message(QString("GLC_3dxmlToWorld::loadProductStructure a instance reference a non existing reference"));
449  message.append(" Instance name " + pInstance->name());
451  clear();
452  throw(fileFormatException);
453  }
454  pInstance->setReference(pRef);
455 
456  ++iInstance;
457  }
458  m_InstanceOf.clear();
459 
460  }
461  //qDebug() << "Local instance linked with reference";
462 
463  { // Link external instance with reference
464 
465  InstanceOfExtRefHash::iterator iInstance= m_InstanceOfExtRefHash.begin();
466  while (iInstance != m_InstanceOfExtRefHash.constEnd())
467  {
468  GLC_StructInstance* pInstance= iInstance.key();
469  GLC_StructReference* pRef;
470  if (m_ExternalReferenceHash.contains(iInstance.value()))
471  {
472  pRef= m_ExternalReferenceHash.value(iInstance.value());
473  }
474  else
475  {
476  QString referenceName= pInstance->name();
477  referenceName= referenceName.left(pInstance->name().lastIndexOf('.'));
478  QStringList stringList(m_FileName);
479  stringList.append("Reference not found : " + referenceName);
480  GLC_ErrorLog::addError(stringList);
481  pRef= new GLC_StructReference(referenceName);
482  }
483 
484  pInstance->setReference(pRef);
485 
486  ++iInstance;
487  }
488 
489  // Check usage of reference in the external reference hash
490  ExternalReferenceHash::const_iterator iRef= m_ExternalReferenceHash.constBegin();
491  while (m_ExternalReferenceHash.constEnd() != iRef)
492  {
493  GLC_StructReference* pRef= iRef.value();
494  if (! pRef->hasStructInstance())
495  {
496  QStringList stringList(m_FileName);
497  stringList.append("Orphan reference : " + pRef->name());
498  GLC_ErrorLog::addError(stringList);
499  delete pRef;
500  }
501  ++iRef;
502  }
503  m_ExternalReferenceHash.clear();
504 
505  }
506  //qDebug() << "external instance linked with reference";
507 
508  // Create the unfolded tree
510 
511  // Update occurence number
513 
514  // Change occurence attributes for 3DXML V3
515  if (! m_V3OccurenceAttribHash.isEmpty())
516  {
517  //qDebug() << "Not visible occurence= " << m_V3OccurenceAttribHash.size();
518  QList<GLC_StructOccurence*> occurenceList= m_pWorld->listOfOccurence();
519  const int size= occurenceList.size();
520  for (int i= 0; i < size; ++i)
521  {
522  if (m_V3OccurenceAttribHash.contains(occurenceList.at(i)->occurenceNumber()))
523  {
524  V3OccurenceAttrib* pOccurenceAttrib= m_V3OccurenceAttribHash.value(occurenceList.at(i)->occurenceNumber());
525  occurenceList.at(i)->setVisibility(pOccurenceAttrib->m_IsVisible);
526  if (NULL != pOccurenceAttrib->m_pRenderProperties)
527  {
528  occurenceList.at(i)->setRenderProperties(*(pOccurenceAttrib->m_pRenderProperties));
529  }
530  }
531  }
532  }
533 
534  // Change occurence attributes for 3DXML V4
535  if (!m_V4OccurenceAttribList.isEmpty())
536  {
537  QHash<GLC_StructInstance*, unsigned int> instanceToIdHash;
538  const int assyCount= m_AssyLinkList.count();
539  for (int i= 0; i < assyCount; ++i)
540  {
541  AssyLink assyLink= m_AssyLinkList.at(i);
542  instanceToIdHash.insert(assyLink.m_pChildInstance, assyLink.m_InstanceId);
543  }
544 
545  const int attribCount= m_V4OccurenceAttribList.count();
546  for (int i= 0; i < attribCount; ++i)
547  {
548  V4OccurenceAttrib* pCurrentV4OccurenceAttrib= m_V4OccurenceAttribList.at(i);
549  //qDebug() << pCurrentV4OccurenceAttrib->m_Path;
550  applyV4Attribute(m_pWorld->rootOccurence(), pCurrentV4OccurenceAttrib, instanceToIdHash);
551  }
552  }
553 
554  // Check usage of Instance
555  InstanceOfExtRefHash::const_iterator iInstance= m_InstanceOfExtRefHash.constBegin();
556  while (m_InstanceOfExtRefHash.constEnd() != iInstance)
557  {
558  GLC_StructInstance* pInstance= iInstance.key();
559  if (!pInstance->hasStructOccurence())
560  {
561  QStringList stringList(m_FileName);
562  stringList.append("Orphan Instance : " + pInstance->name());
563  GLC_ErrorLog::addError(stringList);
564  delete pInstance;
565  }
566  else
567  {
568  QList<GLC_StructOccurence*> occurences= pInstance->listOfStructOccurences();
569  const int size= occurences.size();
570  for (int i= 0; i < size; ++i)
571  {
572  const GLC_StructOccurence* pOccurence= occurences.at(i);
573  if (pOccurence->isOrphan())
574  {
575  QStringList stringList(m_FileName);
576  stringList.append("Orphan occurence : " + pOccurence->name());
577  GLC_ErrorLog::addError(stringList);
578  delete pOccurence;
579  }
580  }
581  }
582  ++iInstance;
583  }
584 
585  m_InstanceOfExtRefHash.clear();
586 
587 
588  //qDebug() << "Unfolded tree created";
589 
590 }
591 
592 // Load a Reference3D
594 {
595  const unsigned int id= readAttribute("id", true).toUInt();
596  const QString refName(readAttribute("name", true));
597  GLC_StructReference* pStructReference;
598 
599  if (id == 1) // This is the root reference.
600  {
601  m_pWorld->setRootName(refName);
602  pStructReference= m_pWorld->rootOccurence()->structInstance()->structReference();
603  pStructReference->setName(refName);
604  }
605  else
606  {
607  pStructReference= new GLC_StructReference(refName);
608  }
609  // Try to find extension
610  GLC_Attributes userAttributes;
611  while (endElementNotReached(m_pStreamReader, "Reference3D"))
612  {
613  if (m_pStreamReader->isStartElement() && (m_pStreamReader->name() == "Reference3DExtensionType"))
614  {
615  while (endElementNotReached(m_pStreamReader, "Reference3DExtensionType"))
616  {
617  if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "Attribute"))
618  {
619  QString name= readAttribute("name", true);
620  QString value= readAttribute("value", true);
621  if (name == "FILEPATH" && QDir(value).isRelative())
622  {
623  value= QFileInfo(m_FileName).absolutePath() + QDir::separator() + value;
624  }
625  userAttributes.insert(name, value);
626  }
627  readNext();
628  }
629  }
630  readNext();
631  }
632  if (!userAttributes.isEmpty())
633  {
634  pStructReference->setAttributes(userAttributes);
635  }
636 
637  m_ReferenceHash.insert(id, pStructReference);
638 }
639 
640 // Load a Instance3D
642 {
643  const QString local= "urn:3DXML:Reference:loc:";
644  const QString externRef= "urn:3DXML:Reference:ext:";
645 
646  const unsigned int instanceId= readAttribute("id", true).toUInt();
647  const QString instName(readAttribute("name", false));
648  goToElement(m_pStreamReader, "IsAggregatedBy");
649  const unsigned int aggregatedById= getContent(m_pStreamReader, "IsAggregatedBy").toUInt();
650  QString instanceOf= getContent(m_pStreamReader, "IsInstanceOf");
651  const QString matrixString= getContent(m_pStreamReader, "RelativeMatrix");
652  GLC_Matrix4x4 instanceMatrix= loadMatrix(matrixString);
653 
654 
655  GLC_StructInstance* pStructInstance= new GLC_StructInstance(instName);
656  pStructInstance->move(instanceMatrix);
657 
658  // Try to find extension
659  GLC_Attributes userAttributes;
660  while (endElementNotReached(m_pStreamReader, "Instance3D"))
661  {
662  if (m_pStreamReader->isStartElement() && (m_pStreamReader->name() == "Instance3DExtensionType"))
663  {
664  while (endElementNotReached(m_pStreamReader, "Instance3DExtensionType"))
665  {
666  if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "Attribute"))
667  {
668  QString name= readAttribute("name", true);
669  QString value= readAttribute("value", true);
670  userAttributes.insert(name, value);
671  }
672  readNext();
673  }
674  }
675  readNext();
676  }
677  if (!userAttributes.isEmpty())
678  {
679  pStructInstance->setAttributes(userAttributes);
680  }
681  if (instanceOf.contains(externRef))
682  {
683 
684  const QString extRefId= instanceOf.remove(externRef).remove("#1");
685  m_SetOfExtRef << extRefId;
686  m_InstanceOfExtRefHash.insert(pStructInstance, extRefId);
687  }
688  else if (instanceOf.contains(local))
689  {
690  const unsigned int refId= instanceOf.remove(local).toUInt();
691  m_InstanceOf.insert(pStructInstance, refId);
692  }
693  else
694  {
695  // 3dvia 3dxml
696  const unsigned int refId= instanceOf.toUInt();
697  m_InstanceOf.insert(pStructInstance, refId);
698  }
699 
700  AssyLink assyLink;
701  assyLink.m_ParentRefId= aggregatedById;
702  assyLink.m_pChildInstance= pStructInstance;
703  assyLink.m_InstanceId= instanceId;
704  m_AssyLinkList.append(assyLink);
705 }
706 
707 // Load a Reference representation
709 {
710  const QString local= "urn:3DXML:Representation:loc:";
711  const QString externName= "urn:3DXML:";
712 
713  const unsigned int id= readAttribute("id", true).toUInt();
714  //const QString refName(readAttribute("name", true));
715  const QString format= readAttribute("format", false);
716  QString associatedFile(readAttribute("associatedFile", true));
717  if (format == "TESSELLATED")
718  {
719  if (associatedFile.contains(local))
720  {
721  const QString repId= associatedFile.remove(local);
722  m_ReferenceRepHash.insert(id, repId);
723  }
724  else if (associatedFile.contains(externName))
725  {
726  const QString repId= associatedFile.remove(externName);
727  m_ReferenceRepHash.insert(id, repId);
728  }
729  }
730  else if (format == "UVR")
731  {
732  QString message(QString("GLC_3dxmlToWorld::loadReferenceRep in file ") + m_CurrentFileName + " format " + format + " not supported");
734  clear();
735  throw(fileFormatException);
736 
737  }
738 }
739 
740 // Load a Instance representation
742 {
743  const QString local= "urn:3DXML:Reference:loc:";
744 
745  goToElement(m_pStreamReader, "IsAggregatedBy");
746  const unsigned int aggregatedById= getContent(m_pStreamReader, "IsAggregatedBy").toUInt();
747  QString instanceOf= getContent(m_pStreamReader, "IsInstanceOf");
748 
749  if (instanceOf.contains(local))
750  {
751  // The 3dxml is a 3dxml rep from CATIA V5
752  const unsigned int refId= instanceOf.remove(local).toUInt();
753 
754  RepLink repLink;
755  repLink.m_ReferenceId= aggregatedById;
756  repLink.m_RepId= refId;
757 
758  m_LocalRepLinkList.append(repLink);
759  }
760  else
761  {
762  // The 3dxml is a 3dvia 3dxml
763  const unsigned int refId= instanceOf.toUInt();
764  RepLink repLink;
765  repLink.m_ReferenceId= aggregatedById;
766  repLink.m_RepId= refId;
767 
768  m_ExternRepLinkList.append(repLink);
769  }
770 }
771 
772 // Load External Ref
774 {
775  if (m_SetOfExtRef.isEmpty()) return;
776 
777  const int size= m_SetOfExtRef.size();
778  int previousQuantumValue= 0;
779  int currentQuantumValue= 0;
780  int currentFileIndex= 0;
781  emit currentQuantum(currentQuantumValue);
782 
783  SetOfExtRef::iterator iExtRef= m_SetOfExtRef.begin();
784  while (iExtRef != m_SetOfExtRef.constEnd())
785  {
786 
787  m_CurrentFileName= (*iExtRef);
788 
789  if (! m_IsInArchive)
790  {
791  // Get the representation time stamp
792  m_CurrentDateTime= QFileInfo(QFileInfo(m_FileName).absolutePath() + QDir::separator() + QFileInfo(m_CurrentFileName).fileName()).lastModified();
793  }
794 
796  {
798 
799  GLC_BSRep binaryRep= cacheManager.binary3DRep(QFileInfo(m_FileName).baseName(), m_CurrentFileName);
800  GLC_3DRep* pRep= new GLC_3DRep(binaryRep.loadRep());
801 
803 
804  GLC_StructReference* pCurrentRef= new GLC_StructReference(pRep);
805  pCurrentRef->setName(QFileInfo(m_CurrentFileName).baseName());
806  m_ExternalReferenceHash.insert(m_CurrentFileName, pCurrentRef);
807 
808  }
810  {
811 
812  // Avoid recursive call off createReferenceRep
813  const QString localFileName= m_CurrentFileName;
814 
815  GLC_StructReference* pCurrentRef= createReferenceRep(QString(), NULL);
816  if (NULL != pCurrentRef)
817  {
818  m_ExternalReferenceHash.insert(localFileName, pCurrentRef);
819  }
820  else
821  {
822  QStringList stringList(m_FileName);
823  stringList.append("GLC_3dxmlToWorld::loadExternalRef3D");
824  stringList.append("Failed to load " + m_CurrentFileName);
825  GLC_ErrorLog::addError(stringList);
826  }
827  }
828  else if(m_LoadStructureOnly)
829  {
830  GLC_3DRep* pRep= new GLC_3DRep();
831  if (m_IsInArchive)
832  {
834  }
835  else
836  {
837  const QString repFileName= glc::builtFileString(m_FileName, m_CurrentFileName);
838  pRep->setFileName(repFileName);
840  }
841 
843  {
844  const QString localFileName= m_CurrentFileName;
845  GLC_StructReference* pCurrentRef= createReferenceRep(QString(), pRep);
846  m_ExternalReferenceHash.insert(localFileName, pCurrentRef);
847  }
848  else
849  {
850  GLC_StructReference* pCurrentRef= new GLC_StructReference(pRep);
851  pCurrentRef->setName(QFileInfo(m_CurrentFileName).baseName());
852  m_ExternalReferenceHash.insert(m_CurrentFileName, pCurrentRef);
853  }
854  }
855  else
856  {
857  qDebug() << "GLC_3dxmlToWorld::loadExternalRef3D No File Found";
858  }
859 
860  ++currentFileIndex;
861  // Progrees bar indicator
862  currentQuantumValue = static_cast<int>((static_cast<double>(currentFileIndex) / size) * 100);
863  if (currentQuantumValue > previousQuantumValue)
864  {
865  emit currentQuantum(currentQuantumValue);
866  }
867  previousQuantumValue= currentQuantumValue;
868 
869  ++iExtRef;
870  }
871  m_SetOfExtRef.clear();
872 
873 }
874 
875 // Create Instance from 3DXML Rep
877 {
878  //qDebug() << "GLC_3dxmlToWorld::createReferenceRep :" << repId;
879 
880  QString refName;
881 
882  if (repId.isEmpty())
883  {
884  goToElement(m_pStreamReader, "ProductStructure");
885  checkForXmlError("Element ProductStructure not found");
886 
887  goToElement(m_pStreamReader, "Reference3D");
888  checkForXmlError("Element Reference3D not found");
889  refName= readAttribute("name", true);
890 
891  if (pRep != NULL)
892  {
893  pRep->setName(refName);
894  return new GLC_StructReference(pRep);
895  }
896 
897  goToElement(m_pStreamReader, "ReferenceRep");
898  if (m_pStreamReader->atEnd())
899  {
900  QStringList stringList(m_FileName);
901  stringList.append("Element ReferenceRep not found in file " + m_CurrentFileName);
902  GLC_ErrorLog::addError(stringList);
903  return NULL;
904  }
905  checkForXmlError("Element ReferenceRep contains error");
906 
907  const QString format(readAttribute("format", true));
908  if (format != "TESSELLATED")
909  {
910  QString message(QString("GLC_3dxmlToWorld::addExtenalRef 3D rep format ") + format + " Not Supported");
912  clear();
913  throw(fileFormatException);
914  }
915 
916  repId= readAttribute("associatedFile");
917 
918  const QString local= "urn:3DXML:Representation:loc:";
919  const QString ext= "urn:3DXML:Representation:ext:";
920  if (repId.contains(ext))
921  {
922  repId.remove(ext);
923  repId.resize(repId.size() - 2);
924  if (setStreamReaderToFile(repId))
925  {
926  return createReferenceRep(QString(), NULL);
927  }
928  else
929  {
930  return NULL;
931  }
932  }
933  else
934  {
935  repId.remove(local);
936  }
937 
938  checkForXmlError("attribute associatedFile not found");
939  goToRepId(repId);
940  checkForXmlError("repId not found");
941  }
942 
943  GLC_Mesh* pMesh= new GLC_Mesh();
944  pMesh->setName(refName);
945  GLC_3DRep currentMesh3DRep(pMesh);
946  // Add time Stamp and file name to the 3D rep
947 
948  if (repId.contains("3DXML_Local_"))
949  {
950  QString saveCurrentFileName= m_CurrentFileName;
951  m_CurrentFileName= repId;
952  setRepresentationFileName(&currentMesh3DRep);
953  m_CurrentFileName= saveCurrentFileName;
954  }
955  else
956  {
957  setRepresentationFileName(&currentMesh3DRep);
958  }
959 
960  currentMesh3DRep.setLastModified(m_CurrentDateTime);
961 
962  int numberOfMesh= 1;
963  while (endElementNotReached(m_pStreamReader, "Representation"))
964  {
966  if (!endElementNotReached(m_pStreamReader, "Representation") || m_pStreamReader->atEnd() || m_pStreamReader->hasError())
967  {
968  if (m_pStreamReader->hasError() || m_pStreamReader->atEnd())
969  {
970  QString message(QString("An element have not been found in file ") + m_FileName);
972  clear();
973  throw(fileFormatException);
974  }
975  else
976  {
977  pMesh->finish();
978  currentMesh3DRep.clean();
979  if (!currentMesh3DRep.isEmpty())
980  {
982  {
984  if (!currentManager.addToCache(QFileInfo(m_FileName).baseName(), currentMesh3DRep))
985  {
986  QStringList stringList("GLC_3dxmlToWorld::createReferenceRep");
987  stringList.append(m_FileName);
988  stringList.append("File " + currentMesh3DRep.fileName() + " Not Added to cache");
989  GLC_ErrorLog::addError(stringList);
990  }
991  }
992 
993  return new GLC_StructReference(new GLC_3DRep(currentMesh3DRep));
994  }
995  else
996  {
997  return new GLC_StructReference("Empty Rep");
998  }
999  }
1000  }
1001  if (numberOfMesh > 1)
1002  {
1003  pMesh->finish();
1004  pMesh = new GLC_Mesh();
1005  pMesh->setName(refName);
1006  currentMesh3DRep.addGeom(pMesh);
1007  }
1008 
1009  loadRep(pMesh);
1010 
1011  ++numberOfMesh;
1012  }
1013 
1014  pMesh->finish();
1015 
1016  currentMesh3DRep.clean();
1017  if (!currentMesh3DRep.isEmpty())
1018  {
1019  if (GLC_State::cacheIsUsed())
1020  {
1022  currentManager.addToCache(QFileInfo(m_FileName).baseName(), currentMesh3DRep);
1023  }
1024 
1025  return new GLC_StructReference(new GLC_3DRep(currentMesh3DRep));
1026  }
1027  else
1028  {
1029  return new GLC_StructReference("Empty Rep");
1030  }
1031 }
1032 
1033 // Load Matrix
1034 GLC_Matrix4x4 GLC_3dxmlToWorld::loadMatrix(const QString& stringMatrix)
1035 {
1036 
1037  QStringList stringValues(stringMatrix.split(" "));
1038 
1039  if (stringValues.size() != 12) return GLC_Matrix4x4();
1040 
1041  QVector<double> values(16);
1042  // Rotation
1043  values[0]= stringValues[0].toDouble();
1044  values[1]= stringValues[1].toDouble();
1045  values[2]= stringValues[2].toDouble();
1046  values[3]= 0.0;
1047  values[4]= stringValues[3].toDouble();
1048  values[5]= stringValues[4].toDouble();
1049  values[6]= stringValues[5].toDouble();
1050  values[7]= 0.0;
1051  values[8]= stringValues[6].toDouble();
1052  values[9]= stringValues[7].toDouble();
1053  values[10]= stringValues[8].toDouble();
1054  values[11]= 0.0;
1055  // Translation
1056  values[12]= stringValues[9].toDouble();
1057  values[13]= stringValues[10].toDouble();
1058  values[14]= stringValues[11].toDouble();
1059  values[15]= 1.0;
1060 
1061  GLC_Matrix4x4 resultMatrix(values.data());
1062  resultMatrix.optimise();
1063 
1064  return resultMatrix;
1065 }
1066 
1067 // Create the unfolded tree
1069 {
1070  //qDebug() << "createUnfoldedTree";
1071  // Run throw all link in the list of link
1072 
1073  qSort(m_AssyLinkList.begin(), m_AssyLinkList.end());
1074  AssyLinkList::iterator iLink= m_AssyLinkList.begin();
1075  while(iLink != m_AssyLinkList.constEnd())
1076  {
1077  GLC_StructInstance* pChildInstance= (*iLink).m_pChildInstance;
1078  if (pChildInstance->structReference() == NULL)
1079  {
1080  QStringList stringList(m_FileName);
1081  stringList.append("Instance without reference");
1082  GLC_ErrorLog::addError(stringList);
1083  pChildInstance->setReference(new GLC_StructReference("Part"));
1084  }
1085  Q_ASSERT(m_ReferenceHash.contains((*iLink).m_ParentRefId));
1086  GLC_StructReference* pRef= m_ReferenceHash.value((*iLink).m_ParentRefId);
1087  // Attach pInstance at all Occurence of pRef
1088  QList<GLC_StructInstance*> instanceList= pRef->listOfStructInstances();
1089  const int instanceNumber= instanceList.size();
1090  for (int i= 0; i < instanceNumber; ++i)
1091  {
1092  if (instanceList.at(i)->hasStructOccurence())
1093  {
1094  QList<GLC_StructOccurence*> occurenceList= instanceList.at(i)->listOfStructOccurences();
1095  const int occurenceNumber= occurenceList.size();
1096  for (int j= 0; j < occurenceNumber; ++j)
1097  {
1098  if (pChildInstance->hasStructOccurence() && pChildInstance->firstOccurenceHandle()->isOrphan())
1099  {
1100  Q_ASSERT(pChildInstance->listOfStructOccurences().size() == 1);
1101  occurenceList.at(j)->addChild(pChildInstance->firstOccurenceHandle());
1102  }
1103  else
1104  {
1105  occurenceList.at(j)->addChild(pChildInstance);
1106  }
1107  }
1108  }
1109  else
1110  {
1111  GLC_StructOccurence* pOccurence= new GLC_StructOccurence(instanceList.at(i), m_pWorld->worldHandle());
1112  if (pChildInstance->hasStructOccurence() && pChildInstance->firstOccurenceHandle()->isOrphan())
1113  {
1114  Q_ASSERT(pChildInstance->listOfStructOccurences().size() == 1);
1115  pOccurence->addChild(pChildInstance->firstOccurenceHandle());
1116  }
1117  else
1118  {
1119  pOccurence->addChild(pChildInstance);
1120  }
1121  }
1122  }
1123 
1124  ++iLink;
1125  }
1126 
1127  // Check the assembly structure occurence
1128  ReferenceHash::const_iterator iRef= m_ReferenceHash.constBegin();
1129  while (m_ReferenceHash.constEnd() != iRef)
1130  {
1131  if (iRef.key() != 1)
1132  {
1133  GLC_StructReference* pReference= iRef.value();
1134  if (!pReference->hasStructInstance())
1135  {
1136  QStringList stringList(m_FileName);
1137  stringList.append("GLC_3dxmlToWorld::createUnfoldedTree() : Orphan reference: " + pReference->name());
1138  GLC_ErrorLog::addError(stringList);
1139  delete pReference;
1140  }
1141  else
1142  {
1143  QList<GLC_StructInstance*> instances= pReference->listOfStructInstances();
1144  const int size= instances.size();
1145  for (int i= 0; i < size; ++i)
1146  {
1147  GLC_StructInstance* pInstance= instances.at(i);
1148  if (!pInstance->hasStructOccurence())
1149  {
1150  QStringList stringList(m_FileName);
1151  stringList.append("GLC_3dxmlToWorld::createUnfoldedTree() : Orphan Instance: " + pInstance->name());
1152  GLC_ErrorLog::addError(stringList);
1153  delete pInstance;
1154  }
1155  else
1156  {
1157  QList<GLC_StructOccurence*> occurences= pInstance->listOfStructOccurences();
1158  const int occurencesSize= occurences.size();
1159  for (int j= 0; j < occurencesSize; ++j)
1160  {
1161  GLC_StructOccurence* pOcc= occurences.at(j);
1162  if (pOcc->isOrphan())
1163  {
1164  QStringList stringList(m_FileName);
1165  stringList.append("GLC_3dxmlToWorld::createUnfoldedTree(): Orphan occurence: " + pOcc->name());
1166  GLC_ErrorLog::addError(stringList);
1167  delete pOcc;
1168  }
1169  }
1170  }
1171  }
1172  }
1173  }
1174  ++iRef;
1175  }
1176  m_ReferenceHash.clear();
1177 
1178  // Update position
1180 
1181 }
1182 // Check for XML error
1183 void GLC_3dxmlToWorld::checkForXmlError(const QString& info)
1184 {
1185  if (m_pStreamReader->atEnd() || m_pStreamReader->hasError())
1186  {
1187  QString message(QString("An element have not been found in file ") + m_CurrentFileName);
1188 
1189  QStringList stringList(info + " " + m_pStreamReader->errorString());
1190  stringList.append(message);
1191  GLC_ErrorLog::addError(stringList);
1192 
1194  clear();
1195  throw(fileFormatException);
1196  }
1197 }
1198 
1199 // Load a face
1200 void GLC_3dxmlToWorld::loadFace(GLC_Mesh* pMesh, const int lod, double accuracy)
1201 {
1202  //qDebug() << "GLC_3dxmlToWorld::loadFace" << m_pStreamReader->name();
1203  // List of index declaration
1204  QString triangles= readAttribute("triangles", false).trimmed();
1205  QString strips= readAttribute("strips", false).trimmed();
1206  QString fans= readAttribute("fans", false).trimmed();
1207 
1208  if (triangles.isEmpty() && strips.isEmpty() && fans.isEmpty())
1209  {
1210  QStringList stringList(m_CurrentFileName);
1211  stringList.append("GLC_3dxmlToWorld::loadFace : Empty face found");
1212  GLC_ErrorLog::addError(stringList);
1213  return;
1214  }
1215 
1216  GLC_Material* pCurrentMaterial= NULL;
1217 
1218  while(endElementNotReached(m_pStreamReader, "Face"))
1219  {
1220  if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "SurfaceAttributes"))
1221  {
1222  pCurrentMaterial= loadSurfaceAttributes();
1223  }
1224  readNext();
1225  }
1226  if (NULL == pCurrentMaterial)
1227  {
1228  pCurrentMaterial= m_pCurrentMaterial;
1229  }
1230 
1231  // Trying to find triangles
1232  if (!triangles.isEmpty())
1233  {
1234  // For 3dvia mesh
1235  if (triangles.contains(','))
1236  {
1237  triangles.remove(',');
1238  }
1239  QTextStream trianglesStream(&triangles);
1240  IndexList trianglesIndex;
1241  QString buff;
1242  while ((!trianglesStream.atEnd()))
1243  {
1244  trianglesStream >> buff;
1245  trianglesIndex.append(buff.toUInt());
1246  }
1247  pMesh->addTriangles(pCurrentMaterial, trianglesIndex, lod, accuracy);
1248  }
1249  // Trying to find trips
1250  if (!strips.isEmpty())
1251  {
1252 
1253  QStringList stripsList(strips.split(","));
1254  const int size= stripsList.size();
1255  for (int i= 0; i < size; ++i)
1256  {
1257  //qDebug() << "Strip " << stripsList.at(i);
1258  QTextStream stripsStream(&stripsList[i]);
1259  IndexList stripsIndex;
1260  QString buff;
1261  while ((!stripsStream.atEnd()))
1262  {
1263  stripsStream >> buff;
1264  stripsIndex.append(buff.toUInt());
1265  }
1266  pMesh->addTrianglesStrip(pCurrentMaterial, stripsIndex, lod, accuracy);
1267  }
1268  }
1269  // Trying to find fans
1270  if (!fans.isEmpty())
1271  {
1272  QStringList fansList(fans.split(","));
1273  const int size= fansList.size();
1274  for (int i= 0; i < size; ++i)
1275  {
1276  QTextStream fansStream(&fansList[i]);
1277  IndexList fansIndex;
1278  QString buff;
1279  while ((!fansStream.atEnd()))
1280  {
1281  fansStream >> buff;
1282  fansIndex.append(buff.toUInt());
1283  }
1284  pMesh->addTrianglesFan(pCurrentMaterial, fansIndex, lod, accuracy);
1285  }
1286  }
1287 
1288 }
1289 
1290 // Load polyline
1292 {
1293  QString data= readAttribute("vertices", true);
1294 
1295  data.replace(',', ' ');
1296  QTextStream dataStream(&data);
1297  QList<GLfloat> values;
1298  QString buff;
1299  while ((!dataStream.atEnd()))
1300  {
1301  dataStream >> buff;
1302  values.append(buff.toFloat());
1303  }
1304  if ((values.size() % 3) == 0)
1305  {
1306  pMesh->addVerticeGroup(values.toVector());
1307  }
1308  else
1309  {
1310  QString message(QString("polyline buffer is not a multiple of 3 ") + m_CurrentFileName);
1311 
1312  QStringList stringList(message);
1313  GLC_ErrorLog::addError(stringList);
1314 
1316  clear();
1317  throw(fileFormatException);
1318  }
1319 
1320 
1321 }
1322 
1323 // Clear material hash
1325 {
1326  MaterialHash::iterator iMaterial= m_MaterialHash.begin();
1327  while (m_MaterialHash.constEnd() != iMaterial)
1328  {
1329  if (iMaterial.value()->isUnused())
1330  {
1331  delete iMaterial.value();
1332  }
1333  ++iMaterial;
1334  }
1335 
1336  m_MaterialHash.clear();
1337 }
1338 
1340 {
1341  GLC_Material* pMaterial= NULL;
1342  while(endElementNotReached(m_pStreamReader, "SurfaceAttributes"))
1343  {
1344  if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "Color"))
1345  {
1346  pMaterial= getMaterial();
1347  }
1348  else if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "MaterialApplication"))
1349  {
1350  while (endElementNotReached(m_pStreamReader, "MaterialApplication"))
1351  {
1352  readNext();
1353  if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "MaterialId"))
1354  {
1355  checkForXmlError("Material ID not found");
1356  QString materialId= readAttribute("id", true).remove("urn:3DXML:CATMaterialRef.3dxml#");
1357  pMaterial= m_MaterialHash.value(materialId);
1358  }
1359  }
1360 
1361  }
1362  readNext();
1363  }
1364 
1365  return pMaterial;
1366 }
1367 
1369 {
1370  GLC_Material* pMaterial= NULL;
1371  const QString red(readAttribute("red", true));
1372  const QString green(readAttribute("green", true));
1373  const QString blue(readAttribute("blue", true));
1374  const QString alpha(readAttribute("alpha", true));
1375 
1376  qreal redReal= red.toDouble();
1377  qreal greenReal= green.toDouble();
1378  qreal blueReal= blue.toDouble();
1379  qreal alphaReal= alpha.toDouble();
1380  QColor diffuse;
1381  diffuse.setRgbF(redReal, greenReal, blueReal);
1382  pMaterial= new GLC_Material(diffuse);
1383  pMaterial->setName("Material_" + QString::number(m_MaterialHash.size()));
1384  pMaterial->setAmbientColor(QColor(50, 50, 50));
1385  pMaterial->setSpecularColor(QColor(70, 70, 70));
1386  pMaterial->setShininess(35.0);
1387  pMaterial->setOpacity(alphaReal);
1388 
1389  const QString matKey= QString::number(pMaterial->hashCode());
1390  if (m_MaterialHash.contains(matKey))
1391  {
1392  delete pMaterial;
1393  pMaterial= m_MaterialHash.value(matKey);
1394  }
1395  else
1396  {
1397  m_MaterialHash.insert(matKey, pMaterial);
1398  }
1399 
1400  return pMaterial;
1401 }
1402 
1403 // Set the stream reader to the specified file
1404 bool GLC_3dxmlToWorld::setStreamReaderToFile(QString fileName, bool test)
1405 {
1406  m_CurrentFileName= fileName;
1407  if (m_IsInArchive)
1408  {
1409  QMutexLocker locker(&m_ZipMutex);
1410  m_ByteArrayList.clear();
1411  // Create QuaZip File
1412  QuaZipFile* p3dxmlFile= new QuaZipFile(m_p3dxmlArchive);
1413 
1414  // Get the file of the 3dxml
1415  if (!m_p3dxmlArchive->setCurrentFile(fileName, QuaZip::csInsensitive))
1416  {
1417  if (!test)
1418  {
1419  QString message(QString("GLC_3dxmlToWorld::setStreamReaderToFile File ") + m_FileName + " doesn't contains " + fileName);
1421  clear();
1422  throw(fileFormatException);
1423  }
1424  else return false;
1425  }
1426 
1427  // Open the file of the 3dxml
1428  if(!p3dxmlFile->open(QIODevice::ReadOnly))
1429  {
1430  QString message(QString("GLC_3dxmlToWorld::setStreamReaderToFile Unable to Open ") + fileName);
1431  GLC_FileFormatException fileFormatException(message, fileName, GLC_FileFormatException::FileNotSupported);
1432  clear();
1433  throw(fileFormatException);
1434  }
1435 
1436  // Test if the file is a binary
1437  checkFileValidity(p3dxmlFile);
1438  {
1439  delete p3dxmlFile;
1440  p3dxmlFile= new QuaZipFile(m_p3dxmlArchive);
1441  m_p3dxmlArchive->setCurrentFile(fileName, QuaZip::csInsensitive);
1442  p3dxmlFile->open(QIODevice::ReadOnly);
1443  }
1444 
1445  // Set the stream reader
1446  delete m_pStreamReader;
1447 
1448  QByteArray currentByteArray;
1449  while (!currentByteArray.isEmpty() || m_ByteArrayList.isEmpty())
1450  {
1451  currentByteArray= p3dxmlFile->read(chunckSize);
1452  m_ByteArrayList.append(currentByteArray);
1453  }
1454  m_pStreamReader= new QXmlStreamReader(m_ByteArrayList.takeFirst());
1455  delete p3dxmlFile;
1456  }
1457  else
1458  {
1459  delete m_pCurrentFile;
1460  // Create the file to load
1461  if (fileName != m_FileName && !m_FileName.isEmpty())
1462  {
1463  fileName= QFileInfo(m_FileName).absolutePath() + QDir::separator() + fileName;
1464  }
1465  // Get the 3DXML time stamp
1466  m_CurrentDateTime= QFileInfo(fileName).lastModified();
1467 
1468  m_pCurrentFile= new QFile(fileName);
1469  if (!m_pCurrentFile->open(QIODevice::ReadOnly))
1470  {
1471  QString message(QString("GLC_3dxmlToWorld::setStreamReaderToFile File ") + fileName + QString(" not found"));
1472  QStringList stringList(message);
1473  GLC_ErrorLog::addError(stringList);
1474  return false;
1475  }
1476  else if (m_FileName != fileName)
1477  {
1478  m_SetOfAttachedFileName << fileName;
1479  }
1480 
1481  // Test if the file is a binary
1483 
1484  // Set the stream reader
1485  delete m_pStreamReader;
1486  m_pStreamReader= new QXmlStreamReader(m_pCurrentFile);
1487  }
1488  return true;
1489 }
1490 
1491 // Load the local representation
1493 {
1494  qDebug() << "GLC_3dxmlToWorld::loadLocalRepresentations()";
1495 
1496  if (m_LocalRepLinkList.isEmpty()) return;
1497  QHash<const QString, GLC_3DRep> repHash;
1498 
1499  // Load all local ref
1500  goToElement(m_pStreamReader, "GeometricRepresentationSet");
1501  while (endElementNotReached(m_pStreamReader, "GeometricRepresentationSet"))
1502  {
1503  if (m_pStreamReader->name() == "Representation")
1504  {
1505  QString id= readAttribute("id", true);
1506  GLC_StructReference* pRef= createReferenceRep("3DXML_Local_" + id, NULL);
1507  if (pRef->hasRepresentation())
1508  {
1509  GLC_3DRep representation(*(dynamic_cast<GLC_3DRep*>(pRef->representationHandle())));
1510  repHash.insert(id, representation);
1511  }
1512  delete pRef;
1513  }
1514  readNext();
1515  }
1516  //qDebug() << "Local rep loaded";
1517 
1518  // Attach the ref to the structure reference
1519  RepLinkList::iterator iLocalRep= m_LocalRepLinkList.begin();
1520  while (iLocalRep != m_LocalRepLinkList.constEnd())
1521  {
1522  unsigned int referenceId= (*iLocalRep).m_ReferenceId;
1523  unsigned int refId= (*iLocalRep).m_RepId;
1524 
1525  GLC_StructReference* pReference= m_ReferenceHash.value(referenceId);
1526  const QString representationID= m_ReferenceRepHash.value(refId);
1527  pReference->setRepresentation(repHash.value(representationID));
1528  pReference->setRepresentationName(pReference->name());
1529 
1530  ++iLocalRep;
1531  }
1532 }
1533 
1535 {
1536  if (m_pStreamReader->atEnd() || m_pStreamReader->hasError())
1537  {
1538  QString message(QString("GLC_3dxmlToWorld::loadGraphicsProperties Element DefaultView Not found in ") + m_FileName);
1540  clear();
1541  throw(fileFormatException);
1542  }
1543 
1544  // Load the graphics properties
1545  while(endElementNotReached(m_pStreamReader, "DefaultView"))
1546  {
1547  if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "DefaultViewProperty"))
1548  {
1551  }
1552 
1553  readNext();
1554  }
1555 
1556  // Check if an error Occur
1557  if (m_pStreamReader->hasError())
1558  {
1559  QString message(QString("GLC_3dxmlToWorld::loadGraphicsProperties An error occur in ") + m_FileName);
1561  clear();
1562  throw(fileFormatException);
1563  }
1564 
1565 }
1566 
1568 {
1569  goToElement(m_pStreamReader, "OccurenceId");
1570  unsigned int occurenceId= getContent(m_pStreamReader, "OccurenceId").toUInt();
1571 
1572  // Load the graphics properties
1573  while(endElementNotReached(m_pStreamReader, "DefaultViewProperty"))
1574  {
1575  if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "GraphicProperties"))
1576  {
1577  while(endElementNotReached(m_pStreamReader, "GraphicProperties"))
1578  {
1579  if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "GeneralAttributes"))
1580  {
1581  QString visibleString= readAttribute("visible", true);
1582  if (visibleString != "true")
1583  {
1584  if (!m_V3OccurenceAttribHash.contains(occurenceId))
1585  {
1586  V3OccurenceAttrib* pOccurenceAttrib= new V3OccurenceAttrib();
1587  pOccurenceAttrib->m_IsVisible= false;
1588  m_V3OccurenceAttribHash.insert(occurenceId, pOccurenceAttrib);
1589  }
1590  else m_V3OccurenceAttribHash.value(occurenceId)->m_IsVisible= false;
1591  }
1592  }
1593  else if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "SurfaceAttributes"))
1594  {
1595  goToElement(m_pStreamReader, "Color");
1596  const double red= readAttribute("red", true).toDouble();
1597  const double green= readAttribute("green", true).toDouble();
1598  const double blue= readAttribute("blue", true).toDouble();
1599  double alpha= 1.0;
1600  QString alphaString= readAttribute("alpha", false);
1601  if (!alphaString.isEmpty()) alpha= alphaString.toDouble();
1602 
1603  GLC_RenderProperties* pRenderProperties= new GLC_RenderProperties();
1604  if (red != -1.0f)
1605  {
1606  QColor diffuseColor;
1607  diffuseColor.setRgbF(red, green, blue, alpha);
1608  GLC_Material* pMaterial= new GLC_Material();
1609  pMaterial->setDiffuseColor(diffuseColor);
1610  pRenderProperties->setOverwriteMaterial(pMaterial);
1611  pRenderProperties->setRenderingMode(glc::OverwriteMaterial);
1612  }
1613  else if (alpha < 1.0f)
1614  {
1615  pRenderProperties->setOverwriteTransparency(static_cast<float>(alpha));
1616  pRenderProperties->setRenderingMode(glc::OverwriteTransparency);
1617  }
1618  if (!m_V3OccurenceAttribHash.contains(occurenceId))
1619  {
1620  V3OccurenceAttrib* pOccurenceAttrib= new V3OccurenceAttrib();
1621  pOccurenceAttrib->m_pRenderProperties= pRenderProperties;
1622  m_V3OccurenceAttribHash.insert(occurenceId, pOccurenceAttrib);
1623  }
1624  else m_V3OccurenceAttribHash.value(occurenceId)->m_pRenderProperties= pRenderProperties;
1625  }
1626 
1627  readNext();
1628  }
1629 
1630  }
1631 
1632  readNext();
1633  }
1634 
1635  // Check if an error Occur
1636  if (m_pStreamReader->hasError())
1637  {
1638  QString message(QString("GLC_3dxmlToWorld::loadDefaultViewProperty An error occur in ") + m_FileName);
1640  clear();
1641  throw(fileFormatException);
1642  }
1643 
1644 }
1645 
1647 {
1648  V4OccurenceAttrib* pV4OccurenceAttrib= new V4OccurenceAttrib();
1649 
1650  while(endElementNotReached(m_pStreamReader, "DefaultViewProperty"))
1651  {
1652  if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "OccurenceId"))
1653  {
1654  pV4OccurenceAttrib->m_Path= loadOccurencePath();
1655  }
1656  else if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "RelativePosition"))
1657  {
1658  const QString matrix= getContent(m_pStreamReader, "RelativePosition");
1659  pV4OccurenceAttrib->m_pMatrix= new GLC_Matrix4x4(loadMatrix(matrix));
1660  }
1661  else if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "GraphicProperties"))
1662  {
1663  loadGraphicProperties(pV4OccurenceAttrib);
1664  }
1665  readNext();
1666  }
1667 
1668  if(!pV4OccurenceAttrib->m_Path.isEmpty())
1669  {
1670  m_V4OccurenceAttribList.append(pV4OccurenceAttrib);
1671  }
1672  else
1673  {
1674  delete pV4OccurenceAttrib;
1675  }
1676 
1677  // Check if an error Occur
1678  if (m_pStreamReader->hasError())
1679  {
1680  QString message(QString("GLC_3dxmlToWorld::loadV4DefaultViewProperty An error occur in ") + m_FileName);
1682  clear();
1683  throw(fileFormatException);
1684  }
1685 
1686 }
1687 
1689 {
1690  QList<unsigned int> path;
1691  while(endElementNotReached(m_pStreamReader, "OccurenceId"))
1692  {
1693  if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "id"))
1694  {
1695  QString instanceId= getContent(m_pStreamReader, "id");
1696  instanceId= instanceId.right(instanceId.length() - 1 - instanceId.indexOf('#'));
1697  path.append(instanceId.toUInt());
1698  }
1699  readNext();
1700  }
1701 
1702  // Check if an error Occur
1703  if (m_pStreamReader->hasError() || path.contains(0))
1704  {
1705  QString message(QString("GLC_3dxmlToWorld::loadOccurencePath An error occur in ") + m_FileName);
1707  clear();
1708  throw(fileFormatException);
1709  }
1710 
1711  return path;
1712 }
1713 
1715 {
1716  while(endElementNotReached(m_pStreamReader, "GraphicProperties"))
1717  {
1718  if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "GeneralAttributes"))
1719  {
1720  QString visibleString= readAttribute("visible", true);
1721  if (visibleString != "true")
1722  {
1723  pAttrib->m_IsVisible= false;
1724  }
1725  }
1726  else if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "SurfaceAttributes"))
1727  {
1728  goToElement(m_pStreamReader, "Color");
1729  const double red= readAttribute("red", true).toDouble();
1730  const double green= readAttribute("green", true).toDouble();
1731  const double blue= readAttribute("blue", true).toDouble();
1732  double alpha= 1.0;
1733  QString alphaString= readAttribute("alpha", false);
1734  if (!alphaString.isEmpty()) alpha= alphaString.toDouble();
1735 
1736  GLC_RenderProperties* pRenderProperties= new GLC_RenderProperties();
1737  if (red != -1.0f)
1738  {
1739  QColor diffuseColor;
1740  diffuseColor.setRgbF(red, green, blue, alpha);
1741  GLC_Material* pMaterial= new GLC_Material();
1742  pMaterial->setDiffuseColor(diffuseColor);
1743  pRenderProperties->setOverwriteMaterial(pMaterial);
1744  if (alpha < 1.0f)
1745  {
1746  pMaterial->setOpacity(static_cast<float>(alpha));
1747  }
1748  pRenderProperties->setRenderingMode(glc::OverwriteMaterial);
1749  }
1750  else if (alpha < 1.0f)
1751  {
1752  pRenderProperties->setOverwriteTransparency(static_cast<float>(alpha));
1753  pRenderProperties->setRenderingMode(glc::OverwriteTransparency);
1754  }
1755 
1756  pAttrib->m_pRenderProperties= pRenderProperties;
1757  }
1758 
1759  readNext();
1760  }
1761 }
1762 
1763 // Load the extern representation
1765 {
1766 
1767  if (m_ExternRepLinkList.isEmpty()) return;
1768 
1769  QHash<const unsigned int, GLC_3DRep> repHash;
1770 
1771  // Progress bar variables
1772  const int size= m_ReferenceRepHash.size();
1773  int previousQuantumValue= 0;
1774  int currentQuantumValue= 0;
1775  int currentFileIndex= 0;
1776  emit currentQuantum(currentQuantumValue);
1777 
1778  // Load all external rep
1779  ReferenceRepHash::iterator iRefRep= m_ReferenceRepHash.begin();
1780  while (iRefRep != m_ReferenceRepHash.constEnd())
1781  {
1782  m_CurrentFileName= iRefRep.value();
1783  const unsigned int id= iRefRep.key();
1784 
1785  if (!m_IsInArchive)
1786  {
1787  // Get the 3DXML time stamp
1788  m_CurrentDateTime= QFileInfo(QFileInfo(m_FileName).absolutePath() + QDir::separator() + QFileInfo(m_CurrentFileName).fileName()).lastModified();
1789  }
1790 
1791 
1793  {
1794  GLC_3DRep representation;
1796  {
1798  GLC_BSRep binaryRep= cacheManager.binary3DRep(QFileInfo(m_FileName).baseName(), m_CurrentFileName);
1799  representation= binaryRep.loadRep();
1800  setRepresentationFileName(&representation);
1801  }
1802  else
1803  {
1804  representation= loadCurrentExtRep();
1805  representation.clean();
1806  }
1807  if (!representation.isEmpty())
1808  {
1809  repHash.insert(id, representation);
1810  }
1811  }
1812  else if (m_LoadStructureOnly)
1813  {
1814  GLC_3DRep representation;
1815  if (m_IsInArchive)
1816  {
1818  }
1819  else
1820  {
1821  const QString repFileName= glc::builtFileString(m_FileName, m_CurrentFileName);
1822  representation.setFileName(repFileName);
1824  }
1825 
1826  repHash.insert(id, representation);
1827  }
1828 
1829  // Progrees bar indicator
1830  ++currentFileIndex;
1831  currentQuantumValue = static_cast<int>((static_cast<double>(currentFileIndex) / size) * 100);
1832  if (currentQuantumValue > previousQuantumValue)
1833  {
1834  emit currentQuantum(currentQuantumValue);
1835  }
1836  previousQuantumValue= currentQuantumValue;
1837 
1838  ++iRefRep;
1839  }
1840 
1841  // Attach the ref to the structure reference
1842  RepLinkList::iterator iExtRep= m_ExternRepLinkList.begin();
1843  while (iExtRep != m_ExternRepLinkList.constEnd())
1844  {
1845  unsigned int referenceId= (*iExtRep).m_ReferenceId;
1846  unsigned int refId= (*iExtRep).m_RepId;
1847 
1848  GLC_StructReference* pReference= m_ReferenceHash.value(referenceId);
1849  if (pReference->hasRepresentation())
1850  {
1851  GLC_3DRep* pRep= dynamic_cast<GLC_3DRep*>(pReference->representationHandle());
1852  if (NULL != pRep)
1853  {
1854  GLC_3DRep newRep(repHash.value(refId));
1855  pRep->take(&newRep);
1856  }
1857  }
1858  else
1859  {
1860  pReference->setRepresentation(repHash.value(refId));
1861  }
1862  // If representation hasn't a name. Set his name to reference name
1863  if (pReference->representationName().isEmpty())
1864  {
1865  pReference->setRepresentationName(pReference->name());
1866  }
1867 
1868  ++iExtRep;
1869  }
1870 
1871 }
1872 
1873 // Return the instance of the current extern representation
1875 {
1876  GLC_Mesh* pMesh= new GLC_Mesh();
1877  GLC_3DRep currentMeshRep(pMesh);
1878  currentMeshRep.setName(QString());
1879  // Set rep file name and time stamp
1880  setRepresentationFileName(&currentMeshRep);
1881 
1882  currentMeshRep.setLastModified(m_CurrentDateTime);
1883 
1884  int numberOfMesh= 1;
1885  while (!m_pStreamReader->atEnd())
1886  {
1887  m_pCurrentMaterial= NULL;
1889  if (m_pStreamReader->atEnd() || m_pStreamReader->hasError())
1890  {
1891  if (m_pStreamReader->hasError())
1892  {
1893  QString message(QString("An element have not been found in file ") + m_FileName);
1895  clear();
1896  throw(fileFormatException);
1897  }
1898  else
1899  {
1900  pMesh->finish();
1901  currentMeshRep.clean();
1902 
1903  if (GLC_State::cacheIsUsed())
1904  {
1906  currentManager.addToCache(QFileInfo(m_FileName).baseName(), currentMeshRep);
1907  }
1908 
1909  return currentMeshRep;
1910  }
1911  }
1912  if (numberOfMesh > 1)
1913  {
1914  pMesh->finish();
1915  pMesh = new GLC_Mesh();
1916  currentMeshRep.addGeom(pMesh);
1917  }
1918 
1919  loadRep(pMesh);
1920 
1921  ++numberOfMesh;
1922  }
1923 
1924  pMesh->finish();
1925  currentMeshRep.clean();
1926 
1927  if (GLC_State::cacheIsUsed())
1928  {
1930  currentManager.addToCache(QFileInfo(m_FileName).baseName(), currentMeshRep);
1931  }
1932 
1933  return currentMeshRep;
1934 }
1935 // Load CatMaterial Ref if present
1937 {
1938 
1939  QList<MaterialRef> materialRefList;
1940 
1941  // Load material Name, Id and associated File
1942  if (setStreamReaderToFile("CATMaterialRef.3dxml", true))
1943  {
1944  // Load the material file
1945  //qDebug() << "CATMaterialRef.3dxml found and current";
1946  goToElement(m_pStreamReader, "CATMaterialRef");
1947  checkForXmlError("Element CATMaterialRef not found in CATMaterialRef.3dxml");
1948  while (endElementNotReached(m_pStreamReader, "CATMaterialRef"))
1949  {
1950  if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType())
1951  {
1952  const QStringRef currentElementName= m_pStreamReader->name();
1953  if (currentElementName == "CATMatReference")
1954  {
1955  MaterialRef currentMaterial;
1956  currentMaterial.m_Id= readAttribute("id", true);
1957  currentMaterial.m_Name= readAttribute("name", true);
1958  goToElement(m_pStreamReader, "MaterialDomain");
1959  checkForXmlError("Element MaterialDomain not found after CATMatReference Element");
1960  currentMaterial.m_AssociatedFile= readAttribute("associatedFile", true).remove("urn:3DXML:");
1961  materialRefList.append(currentMaterial);
1962  //qDebug() << "Material " << currentMaterial.m_Name << " Added";
1963  }
1964  }
1965  readNext();
1966  }
1967  }
1968  // Load material files
1969  const int size= materialRefList.size();
1970  for (int i= 0; i < size; ++i)
1971  {
1972  if (setStreamReaderToFile(materialRefList.at(i).m_AssociatedFile, true))
1973  {
1974  //qDebug() << "Load MaterialDef : " << materialRefList.at(i).m_AssociatedFile;
1975  loadMaterialDef(materialRefList.at(i));
1976  }
1977  }
1978 }
1979 
1980 // Create material from material def file
1982 {
1983  GLC_Material* pMaterial= new GLC_Material();
1984  goToElement(m_pStreamReader, "Osm");
1985  checkForXmlError(QString("Element Osm not found in file : ") + materialRef.m_AssociatedFile);
1986  while (endElementNotReached(m_pStreamReader, "Osm"))
1987  {
1988  readNext();
1989  if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && m_pStreamReader->name() == "Attr")
1990  {
1991  const QString currentName= readAttribute("Name", true);
1992  if (currentName == "DiffuseColor")
1993  {
1994  QString color= m_pStreamReader->attributes().value("Value").toString();
1995  color.remove('[');
1996  color.remove(']');
1997  QStringList colors(color.split(","));
1998  QColor diffuseColor;
1999  diffuseColor.setRedF(colors.at(0).toDouble());
2000  diffuseColor.setGreenF(colors.at(1).toDouble());
2001  diffuseColor.setBlueF(colors.at(2).toDouble());
2002  pMaterial->setDiffuseColor(diffuseColor);
2003  }
2004  else if (currentName == "Transparency")
2005  {
2006  double opacity= readAttribute("Value", true).toDouble();
2007  opacity= 1.0 - opacity;
2008  pMaterial->setOpacity(opacity);
2009  }
2010  else if (currentName == "SpecularExponent")
2011  {
2012  double SpecularExponent= readAttribute("Value", true).toDouble() * 128.0;
2013  pMaterial->setShininess(SpecularExponent);
2014  }
2015  else if (currentName == "TextureImage")
2016  {
2017  //qDebug() << "TextureImage";
2018  QString imageId= readAttribute("Value", true).remove("urn:3DXML:CATRepImage.3dxml#");
2019  if (m_TextureImagesHash.contains(imageId))
2020  {
2021  QString imageName= m_TextureImagesHash.value(imageId);
2022  GLC_Texture* pTexture= loadTexture(imageName);
2023  if (NULL != pTexture)
2024  {
2025  pMaterial->setTexture(pTexture);
2026  }
2027  }
2028  }
2029  else if (currentName == "EmissiveCoef")
2030  {
2031 
2032  }
2033  else if (currentName == "SpecularColor")
2034  {
2035  QString color= readAttribute("Value", true);
2036  color.remove('[');
2037  color.remove(']');
2038  QStringList colors(color.split(","));
2039  QColor specularColor;
2040  specularColor.setRedF(colors.at(0).toDouble());
2041  specularColor.setGreenF(colors.at(1).toDouble());
2042  specularColor.setBlueF(colors.at(2).toDouble());
2043  pMaterial->setSpecularColor(specularColor);
2044  }
2045  else if (currentName == "AmbientColor")
2046  {
2047  QString color= readAttribute("Value", true);
2048  color.remove('[');
2049  color.remove(']');
2050  QStringList colors(color.split(","));
2051  QColor ambientColor;
2052  ambientColor.setRedF(colors.at(0).toDouble());
2053  ambientColor.setGreenF(colors.at(1).toDouble());
2054  ambientColor.setBlueF(colors.at(2).toDouble());
2055  pMaterial->setAmbientColor(ambientColor);
2056  }
2057 
2058  }
2059  }
2060  pMaterial->setName(materialRef.m_Name);
2061  m_MaterialHash.insert(materialRef.m_Id, pMaterial);
2062 }
2063 
2064 // Load CATRepIage if present
2066 {
2067  // Load texture image name
2068  if (setStreamReaderToFile("CATRepImage.3dxml", true))
2069  {
2070  //qDebug() << "CATRepImage.3dxml Found";
2071  goToElement(m_pStreamReader, "CATRepImage");
2072  checkForXmlError("Element CATRepImage not found in CATRepImage.3dxml");
2073  while (endElementNotReached(m_pStreamReader, "CATRepImage"))
2074  {
2075  if (QXmlStreamReader::StartElement == m_pStreamReader->tokenType())
2076  {
2077  const QStringRef currentElementName= m_pStreamReader->name();
2078  if (currentElementName == "CATRepresentationImage")
2079  {
2080  QString id= readAttribute("id", true);
2081  QString associatedFile= readAttribute("associatedFile", true).remove("urn:3DXML:");
2082  m_TextureImagesHash.insert(id,associatedFile);
2083  }
2084  }
2085  readNext();
2086  }
2087  //qDebug() << "CATRepImage.3dxml Load";
2088  }
2089 }
2090 
2091 // try to load the specified image
2093 {
2094  QString format= QFileInfo(fileName).suffix().toUpper();
2095  QImage resultImage;
2096  QString resultImageFileName;
2097  if (m_IsInArchive)
2098  {
2099  // Create QuaZip File
2100  QuaZipFile* p3dxmlFile= new QuaZipFile(m_p3dxmlArchive);
2101 
2102  // Get the file of the 3dxml
2103  if (!m_p3dxmlArchive->setCurrentFile(fileName, QuaZip::csInsensitive))
2104  {
2105  return NULL;
2106  }
2107 
2108  // Open the file of the 3dxml
2109  if(!p3dxmlFile->open(QIODevice::ReadOnly))
2110  {
2111  delete p3dxmlFile;
2112  QString message(QString("GLC_3dxmlToWorld::loadImage Unable to Open ") + fileName);
2113  GLC_FileFormatException fileFormatException(message, fileName, GLC_FileFormatException::FileNotSupported);
2114  clear();
2115  throw(fileFormatException);
2116  }
2117  resultImage.load(p3dxmlFile, format.toLocal8Bit());
2118  p3dxmlFile->close();
2119  delete p3dxmlFile;
2120  resultImageFileName= glc::builtArchiveString(m_FileName, fileName);
2121  }
2122  else
2123  {
2124  // Create the file to load
2125  if (fileName != m_FileName)
2126  {
2127  resultImageFileName= QFileInfo(m_FileName).absolutePath() + QDir::separator() + fileName;
2128  }
2129  QFile* pCurrentFile= new QFile(resultImageFileName);
2130  if (!pCurrentFile->open(QIODevice::ReadOnly))
2131  {
2132  delete pCurrentFile;
2133  QString message(QString("GLC_3dxmlToWorld::loadImage File ") + resultImageFileName + QString(" not found"));
2134  QStringList stringList(m_CurrentFileName);
2135  stringList.append(message);
2136  GLC_ErrorLog::addError(stringList);
2137  return NULL;
2138  }
2139  else
2140  {
2141  m_SetOfAttachedFileName << resultImageFileName;
2142  }
2143  resultImage.load(pCurrentFile, format.toLocal8Bit());
2144  pCurrentFile->close();
2145  delete pCurrentFile;
2146  }
2147 
2148  GLC_Texture* pTexture= NULL;
2149  if (!resultImage.isNull())
2150  {
2151  pTexture= new GLC_Texture(resultImage, resultImageFileName);
2152  }
2153  else
2154  {
2155  QStringList stringList(m_CurrentFileName);
2156  stringList.append("Unable to load " + resultImageFileName);
2157  GLC_ErrorLog::addError(stringList);
2158  }
2159 
2160  return pTexture;
2161 }
2162 
2164 {
2165  if (m_IsInArchive)
2166  {
2168  }
2169  else
2170  {
2171  pRep->setFileName(QFileInfo(m_FileName).absolutePath() + QDir::separator() + m_CurrentFileName);
2172  }
2173 }
2174 
2175 void GLC_3dxmlToWorld::checkFileValidity(QIODevice* pIODevice)
2176 {
2177  QByteArray begining= pIODevice->read(2);
2178  if (begining == "V5")
2179  {
2180  QString message(QString("GLC_3dxmlToWorld::setStreamReaderToFile : File ") + m_CurrentFileName + " is binary");
2182  clear();
2183  throw(fileFormatException);
2184  }
2185  else
2186  {
2187  pIODevice->seek(0);
2188  }
2189 }
2190 
2191 void GLC_3dxmlToWorld::applyV4Attribute(GLC_StructOccurence* pOccurence, V4OccurenceAttrib* pV4OccurenceAttrib, QHash<GLC_StructInstance*, unsigned int>& instanceToIdHash)
2192 {
2193  Q_ASSERT(pOccurence->hasChild() && !pV4OccurenceAttrib->m_Path.isEmpty());
2194  unsigned int id= pV4OccurenceAttrib->m_Path.takeFirst();
2195 
2196  const int childCount= pOccurence->childCount();
2197  bool occurenceFound= false;
2198  int i= 0;
2199  while (!occurenceFound && (i < childCount))
2200  {
2201  GLC_StructOccurence* pChildOccurence= pOccurence->child(i);
2202  if (instanceToIdHash.contains(pChildOccurence->structInstance()) && (instanceToIdHash.value(pChildOccurence->structInstance()) == id))
2203  {
2204  Q_ASSERT(id == instanceToIdHash.value(pChildOccurence->structInstance()));
2205  occurenceFound= true;
2206 
2207  if (pV4OccurenceAttrib->m_Path.isEmpty())
2208  {
2209  pChildOccurence->setVisibility(pV4OccurenceAttrib->m_IsVisible);
2210  if (NULL != pV4OccurenceAttrib->m_pRenderProperties)
2211  {
2212  pChildOccurence->setRenderProperties(*(pV4OccurenceAttrib->m_pRenderProperties));
2213  }
2214  if (pV4OccurenceAttrib->m_pMatrix != NULL)
2215  {
2216  pChildOccurence->makeFlexible(*(pV4OccurenceAttrib->m_pMatrix));
2217  }
2218  }
2219  else
2220  {
2221  applyV4Attribute(pChildOccurence, pV4OccurenceAttrib, instanceToIdHash);
2222  }
2223  }
2224  else
2225  {
2226  ++i;
2227  }
2228  }
2229  if (!occurenceFound)
2230  {
2231  qDebug() << "GLC_3dxmlToWorld::applyV4Attribute Occurrence not found" << id;
2232  }
2233 
2234 }
2235 
2237 {
2238  double masteLodAccuracy= readAttribute("accuracy", false).toDouble();
2239  int lodIndex= 1;
2240 
2241  bool masterLodFound= false;
2242  bool vertexBufferFound= false;
2243 
2245  {
2246  if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()))
2247  {
2248  if (m_pStreamReader->name() == "SurfaceAttributes")
2249  {
2251  }
2252  else if (m_pStreamReader->name() == "PolygonalLOD")
2253  {
2254  double accuracy= readAttribute("accuracy", true).toDouble();
2255  while (endElementNotReached(m_pStreamReader, "Faces"))
2256  {
2257  readNext();
2258  if ( m_pStreamReader->name() == "Face")
2259  {
2260  loadFace(pMesh, lodIndex, accuracy);
2261  }
2262  }
2263  checkForXmlError("End of Faces not found");
2264  ++lodIndex;
2265  }
2266  else if (m_pStreamReader->name() == "Faces")
2267  {
2268  masterLodFound= true;
2269  while (endElementNotReached(m_pStreamReader, "Faces"))
2270  {
2271  readNext();
2272  if ( m_pStreamReader->name() == "Face")
2273  {
2274  loadFace(pMesh, 0, masteLodAccuracy);
2275  }
2276  }
2277  checkForXmlError("End of Faces not found");
2278  }
2279  else if (m_pStreamReader->name() == "Edges")
2280  {
2281  while (endElementNotReached(m_pStreamReader, "Edges"))
2282  {
2283  readNext();
2284  if ( m_pStreamReader->name() == "Polyline")
2285  {
2286  loadPolyline(pMesh);
2287  while (endElementNotReached(m_pStreamReader, "Polyline"))
2288  {
2289  readNext();
2290  }
2291  }
2292  }
2293  }
2294  else if (m_pStreamReader->name() == "VertexBuffer")
2295  {
2296  vertexBufferFound= true;
2297  loadVertexBuffer(pMesh);
2298  }
2299  else readNext();
2300  }
2301  else
2302  {
2303  readNext();
2304  }
2305  }
2306  checkForXmlError("End of Rep or Root not found");
2307 
2308  if (!masterLodFound || !vertexBufferFound)
2309  {
2310  QString message;
2311  if (!masterLodFound)
2312  {
2313  message= QString("Master LOD not found in file ") + m_FileName;
2314  }
2315  if (!vertexBufferFound)
2316  {
2317  message= QString("Vertex Buffer not found in file ") + m_FileName;
2318  }
2319  GLC_ErrorLog::addError(message);
2320  }
2321 
2322 
2323 }
2324 
2326 {
2327  {
2328  QString verticePosition= getContent(m_pStreamReader, "Positions").replace(',', ' ');
2329  //qDebug() << "Position " << verticePosition;
2330  checkForXmlError("Error while retrieving Position ContentVertexBuffer");
2331  // Load Vertice position
2332  QTextStream verticeStream(&verticePosition);
2333  QList<GLfloat> verticeValues;
2334  QString buff;
2335  while ((!verticeStream.atEnd()))
2336  {
2337  verticeStream >> buff;
2338  verticeValues.append(buff.toFloat());
2339  }
2340  if ((verticeValues.size() % 3) == 0)
2341  {
2342  pMesh->addVertice(verticeValues.toVector());
2343  }
2344  else
2345  {
2346  QString message(QString("Vertice buffer is not a multiple of 3 ") + m_CurrentFileName);
2347 
2348  QStringList stringList(message);
2349  GLC_ErrorLog::addError(stringList);
2350 
2352  clear();
2353  throw(fileFormatException);
2354  }
2355  }
2356 
2357  {
2358  QString normals= getContent(m_pStreamReader, "Normals").replace(',', ' ');
2359  //qDebug() << "Normals " << normals;
2360  checkForXmlError("Error while retrieving Normals values");
2361  // Load Vertice Normals
2362  QTextStream normalsStream(&normals);
2363  QList<GLfloat> normalValues;
2364  QString buff;
2365  while ((!normalsStream.atEnd()))
2366  {
2367  normalsStream >> buff;
2368  normalValues.append(buff.toFloat());
2369  }
2370  if ((normalValues.size() % 3) == 0)
2371  {
2372  pMesh->addNormals(normalValues.toVector());
2373  }
2374  else
2375  {
2376  QString message(QString("Normal buffer is not a multiple of 3 ") + m_CurrentFileName);
2377 
2378  QStringList stringList(message);
2379  GLC_ErrorLog::addError(stringList);
2380 
2382  clear();
2383  throw(fileFormatException);
2384  }
2385 
2386  }
2387  // Try to find texture coordinate
2388  while (endElementNotReached(m_pStreamReader, "VertexBuffer"))
2389  {
2390  if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "TextureCoordinates"))
2391  {
2392  QString texels= getContent(m_pStreamReader, "TextureCoordinates").replace(',', ' ');
2393  checkForXmlError("Error while retrieving Texture coordinates");
2394  QTextStream texelStream(&texels);
2395  QList<GLfloat> texelValues;
2396  QString buff;
2397  while ((!texelStream.atEnd()))
2398  {
2399  texelStream >> buff;
2400  texelValues.append(buff.toFloat());
2401  }
2402 
2403  if ((texelValues.size() % 2) == 0)
2404  {
2405  pMesh->addTexels(texelValues.toVector());
2406  }
2407  else
2408  {
2409  QString message(QString("Texel buffer is not a multiple of 2 ") + m_CurrentFileName);
2410 
2411  QStringList stringList(message);
2412  GLC_ErrorLog::addError(stringList);
2413 
2415  clear();
2416  throw(fileFormatException);
2417  }
2418  }
2419  readNext();
2420  }
2421  checkForXmlError("VertexBuffer not found");
2422 }

©2005-2013 Laurent Ribon