glc_3drep.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 
00003  This file is part of the GLC-lib library.
00004  Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
00005  http://glc-lib.sourceforge.net
00006 
00007  GLC-lib is free software; you can redistribute it and/or modify
00008  it under the terms of the GNU Lesser General Public License as published by
00009  the Free Software Foundation; either version 3 of the License, or
00010  (at your option) any later version.
00011 
00012  GLC-lib is distributed in the hope that it will be useful,
00013  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  GNU Lesser General Public License for more details.
00016 
00017  You should have received a copy of the GNU Lesser General Public License
00018  along with GLC-lib; if not, write to the Free Software
00019  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00020 
00021  *****************************************************************************/
00022 
00023 #include "glc_3drep.h"
00024 #include "../glc_factory.h"
00025 #include "glc_mesh.h"
00026 #include "glc_errorlog.h"
00027 
00028 // Class chunk id
00029 quint32 GLC_3DRep::m_ChunkId= 0xA702;
00030 
00031 // Default constructor
00032 GLC_3DRep::GLC_3DRep()
00033 : GLC_Rep()
00034 , m_pGeomList(new QList<GLC_Geometry*>)
00035 , m_pType(new int(GLC_Rep::GLC_VBOGEOM))
00036 {
00037 
00038 }
00039 
00040 // Construct a 3DRep with a geometry
00041 GLC_3DRep::GLC_3DRep(GLC_Geometry* pGeom)
00042 : GLC_Rep()
00043 , m_pGeomList(new QList<GLC_Geometry*>)
00044 , m_pType(new int(GLC_Rep::GLC_VBOGEOM))
00045 {
00046         m_pGeomList->append(pGeom);
00047         *m_pIsLoaded= true;
00048         setName(pGeom->name());
00049 }
00050 
00051 // Copy Constructor
00052 GLC_3DRep::GLC_3DRep(const GLC_3DRep& rep)
00053 : GLC_Rep(rep)
00054 , m_pGeomList(rep.m_pGeomList)
00055 , m_pType(rep.m_pType)
00056 {
00057 
00058 }
00059 
00060 // Assignement operator
00061 GLC_3DRep& GLC_3DRep::operator=(const GLC_Rep& rep)
00062 {
00063         const GLC_3DRep* p3DRep= dynamic_cast<const GLC_3DRep*>(&rep);
00064         Q_ASSERT(NULL != p3DRep);
00065         if (this != &rep)
00066         {
00067                 clear();
00068                 GLC_Rep::operator=(rep);
00069                 m_pGeomList= p3DRep->m_pGeomList;
00070                 m_pType= p3DRep->m_pType;
00071         }
00072 
00073         return *this;
00074 }
00075 
00076 // Clone the representation
00077 GLC_Rep* GLC_3DRep::clone() const
00078 {
00079         return new GLC_3DRep(*this);
00080 }
00081 
00082 // Make a deep copy of the 3DRep
00083 GLC_Rep* GLC_3DRep::deepCopy() const
00084 {
00085         GLC_3DRep* pCloneRep= new GLC_3DRep;
00086         // Copy fields of the base class
00087         pCloneRep->setFileName(fileName());
00088         pCloneRep->setName(name());
00089         // Copy representation geometries
00090         const int size= m_pGeomList->size();
00091         for (int i= 0; i < size; ++i)
00092         {
00093                 pCloneRep->addGeom(m_pGeomList->at(i)->clone());
00094         }
00095         return pCloneRep;
00096 }
00097 
00098 // Destructor
00099 GLC_3DRep::~GLC_3DRep()
00100 {
00101         clear();
00102 }
00103 
00105 // Get functions
00107 // Return the class Chunk ID
00108 quint32 GLC_3DRep::chunckID()
00109 {
00110         return m_ChunkId;
00111 }
00112 
00113 // Return the type of representation
00114 int GLC_3DRep::type() const
00115 {
00116         return (*m_pType);
00117 }
00118 
00120 // Get functions
00122 
00123 // Return true if the rep bounding box is valid
00124 bool GLC_3DRep::boundingBoxIsValid() const
00125 {
00126         bool result= !m_pGeomList->isEmpty();
00127         const int max= m_pGeomList->size();
00128         int index= 0;
00129         while (result && (index < max))
00130         {
00131                 result= result && m_pGeomList->at(index)->boundingBoxIsValid();
00132                 ++index;
00133         }
00134         return result;
00135 }
00136 
00137 // Return the 3DRep bounding Box
00138 GLC_BoundingBox GLC_3DRep::boundingBox() const
00139 {
00140         GLC_BoundingBox resultBox;
00141         const int size= m_pGeomList->size();
00142         for (int i= 0; i < size; ++i)
00143         {
00144                 resultBox.combine(m_pGeomList->at(i)->boundingBox());
00145         }
00146         return resultBox;
00147 }
00148 
00149 // Get number of faces
00150 unsigned int GLC_3DRep::faceCount() const
00151 {
00152         unsigned int result= 0;
00153         if (!m_pGeomList->isEmpty())
00154         {
00155                 const int size= m_pGeomList->size();
00156                 for (int i= 0; i < size; ++i)
00157                 {
00158                         result+= m_pGeomList->at(i)->faceCount();
00159                 }
00160         }
00161 
00162         return result;
00163 }
00164 
00165 // Get number of vertex
00166 unsigned int GLC_3DRep::vertexCount() const
00167 {
00168         unsigned int result= 0;
00169         if (!m_pGeomList->isEmpty())
00170         {
00171                 const int size= m_pGeomList->size();
00172                 for (int i= 0; i < size; ++i)
00173                 {
00174                         result+= m_pGeomList->at(i)->VertexCount();
00175                 }
00176         }
00177 
00178         return result;
00179 }
00180 
00181 // Get number of materials
00182 unsigned int GLC_3DRep::materialCount() const
00183 {
00184         unsigned int result= 0;
00185         if (!m_pGeomList->isEmpty())
00186         {
00187                 const int size= m_pGeomList->size();
00188                 for (int i= 0; i < size; ++i)
00189                 {
00190                         result+= m_pGeomList->at(i)->materialCount();
00191                 }
00192         }
00193 
00194         return result;
00195 }
00196 
00197 // Get materials List
00198 QSet<GLC_Material*> GLC_3DRep::materialSet() const
00199 {
00200         QSet<GLC_Material*> result;
00201         if (!m_pGeomList->isEmpty())
00202         {
00203                 const int size= m_pGeomList->size();
00204                 for (int i= 0; i < size; ++i)
00205                 {
00206                         result.unite(m_pGeomList->at(i)->materialSet());
00207                 }
00208         }
00209 
00210         return result;
00211 }
00212 
00213 // Remove empty geometries
00214 void GLC_3DRep::clean()
00215 {
00216         QList<GLC_Geometry*>::iterator iGeomList= m_pGeomList->begin();
00217         while(iGeomList != m_pGeomList->constEnd())
00218         {
00219                 if ((*iGeomList)->VertexCount() == 0)
00220                 {
00221                         qDebug() << "Delete empty geom--------------------";
00222                         delete (*iGeomList);
00223                         iGeomList= m_pGeomList->erase(iGeomList);
00224                 }
00225                 else
00226                 {
00227                         ++iGeomList;
00228                 }
00229         }
00230 }
00231 
00232 // Reverse geometries normals
00233 void GLC_3DRep::reverseNormals()
00234 {
00235         const int size= m_pGeomList->size();
00236         for (int i= 0; i < size; ++i)
00237         {
00238                 (*m_pGeomList)[i]->reverseNormals();
00239         }
00240 }
00241 
00242 // Load the representation
00243 bool GLC_3DRep::load()
00244 {
00245         bool loadSucces= false;
00246 
00247         if(!(*m_pIsLoaded))
00248         {
00249                 Q_ASSERT(m_pGeomList->isEmpty());
00250                 if (fileName().isEmpty())
00251                 {
00252                         QStringList stringList("GLC_3DRep::load");
00253                         stringList.append("Representation : " + GLC_Rep::name());
00254                         stringList.append("Empty File Name");
00255                         GLC_ErrorLog::addError(stringList);
00256                 }
00257                 else
00258                 {
00259                         GLC_3DRep newRep= GLC_Factory::instance()->create3DRepFromFile(fileName());
00260                         if (!newRep.isEmpty())
00261                         {
00262                                 const int size= newRep.m_pGeomList->size();
00263                                 for (int i= 0; i < size; ++i)
00264                                 {
00265                                         m_pGeomList->append(newRep.m_pGeomList->at(i));
00266                                 }
00267                                 newRep.m_pGeomList->clear();
00268                                 (*m_pIsLoaded)= true;
00269                                 loadSucces= true;
00270                         }
00271                 }
00272         }
00273 
00274         return loadSucces;
00275 
00276 }
00277 // Replace the representation
00278 void GLC_3DRep::replace(GLC_Rep* pRep)
00279 {
00280         GLC_3DRep* p3DRep= dynamic_cast<GLC_3DRep*>(pRep);
00281         Q_ASSERT(NULL != p3DRep);
00282 
00283         setFileName(p3DRep->fileName());
00284         setName(p3DRep->name());
00285 
00286         if (!p3DRep->isEmpty())
00287         {
00288                 const int size= p3DRep->m_pGeomList->size();
00289                 for (int i= 0; i < size; ++i)
00290                 {
00291                         m_pGeomList->append(p3DRep->m_pGeomList->at(i));
00292                 }
00293                 p3DRep->m_pGeomList->clear();
00294                 (*m_pIsLoaded)= true;
00295         }
00296 }
00297 
00298 // Replace the specified material by a new one
00299 void GLC_3DRep::replaceMaterial(GLC_uint oldId, GLC_Material* pNewMaterial)
00300 {
00301         //qDebug() << "GLC_3DRep::replaceMaterial";
00302         const int size= m_pGeomList->size();
00303         for (int i= 0; i < size; ++i)
00304         {
00305                 GLC_Geometry* pGeom= m_pGeomList->at(i);
00306                 if (pGeom->containsMaterial(oldId))
00307                 {
00308                         Q_ASSERT(!pGeom->containsMaterial(pNewMaterial->id()));
00309                         GLC_Mesh* pMesh= dynamic_cast<GLC_Mesh*>(m_pGeomList->at(i));
00310                         if (NULL != pMesh)
00311                         {
00312                                 pMesh->replaceMaterial(oldId, pNewMaterial);
00313                         }
00314                 }
00315         }
00316 }
00317 
00318 // Merge this 3Drep with another 3DRep
00319 void GLC_3DRep::merge(const GLC_3DRep* pRep)
00320 {
00321         // Get the number of geometry of pRep
00322         const int pRepSize= pRep->m_pGeomList->size();
00323         for (int i= 0; i < pRepSize; ++i)
00324         {
00325                 addGeom(pRep->geomAt(i)->clone());
00326         }
00327 }
00328 
00329 void GLC_3DRep::take(GLC_3DRep* pSource)
00330 {
00331         // Get the number of geometry of pRep
00332         const int pRepSize= pSource->m_pGeomList->size();
00333         for (int i= 0; i < pRepSize; ++i)
00334         {
00335                 addGeom(pSource->geomAt(i));
00336         }
00337         pSource->m_pGeomList->clear();
00338 }
00339 
00340 void GLC_3DRep::copyVboToClientSide()
00341 {
00342         // Get the number of geometry of pRep
00343         const int pRepSize= m_pGeomList->size();
00344         for (int i= 0; i < pRepSize; ++i)
00345         {
00346                 geomAt(i)->copyVboToClientSide();
00347         }
00348 }
00349 
00350 void GLC_3DRep::releaseVboClientSide(bool update)
00351 {
00352         // Get the number of geometry of pRep
00353         const int pRepSize= m_pGeomList->size();
00354         for (int i= 0; i < pRepSize; ++i)
00355         {
00356                 geomAt(i)->releaseVboClientSide(update);
00357         }
00358 }
00359 
00360 void GLC_3DRep::transformSubGeometries(const GLC_Matrix4x4& matrix)
00361 {
00362         // Get the number of geometry of pRep
00363         const int repCount= m_pGeomList->size();
00364         qDebug() << "repCount " << repCount;
00365         for (int i= 0; i < repCount; ++i)
00366         {
00367                 GLC_Mesh* pCurrentMesh= dynamic_cast<GLC_Mesh*>(geomAt(i));
00368                 if (NULL != pCurrentMesh)
00369                 {
00370                         pCurrentMesh->transformVertice(matrix);
00371                 }
00372         }
00373 }
00374 
00375 // UnLoad the representation
00376 bool GLC_3DRep::unload()
00377 {
00378         bool unloadSucess= false;
00379         if ((NULL != m_pGeomList) && !m_pGeomList->isEmpty())
00380         {
00381                 if (fileName().isEmpty())
00382                 {
00383                         QStringList stringList("GLC_3DRep::unload()");
00384                         stringList.append("Cannot unload rep without filename");
00385                         GLC_ErrorLog::addError(stringList);
00386                 }
00387                 else
00388                 {
00389                         const int size= m_pGeomList->size();
00390                         for (int i= 0; i < size; ++i)
00391                         {
00392                                 delete (*m_pGeomList)[i];
00393                         }
00394                         m_pGeomList->clear();
00395 
00396                         (*m_pIsLoaded)= false;
00397                         unloadSucess= true;
00398                 }
00399         }
00400         return unloadSucess;
00401 }
00402 
00404 // private services functions
00406 
00407 // Clear the 3D representation
00408 void GLC_3DRep::clear()
00409 {
00410         if (isTheLast())
00411         {
00412                 const int size= m_pGeomList->size();
00413                 for (int i= 0; i < size; ++i)
00414                 {
00415                         delete (*m_pGeomList)[i];
00416                 }
00417                 delete m_pGeomList;
00418                 m_pGeomList= NULL;
00419 
00420                 delete m_pType;
00421                 m_pType= NULL;
00422         }
00423 }
00424 // Non Member methods
00425 // Non-member stream operator
00426 QDataStream &operator<<(QDataStream & stream, const GLC_3DRep & rep)
00427 {
00428         quint32 chunckId= GLC_3DRep::m_ChunkId;
00429         stream << chunckId;
00430 
00431         // The representation name
00432         stream << rep.name();
00433 
00434         // Save the list of 3DRep materials
00435         QList<GLC_Material> materialsList;
00436         QList<GLC_Material*> sourceMaterialsList= rep.materialSet().toList();
00437         const int materialNumber= sourceMaterialsList.size();
00438         for (int i= 0; i < materialNumber; ++i)
00439         {
00440                 materialsList.append(*(sourceMaterialsList.at(i)));
00441                 materialsList[i].setId(sourceMaterialsList.at(i)->id());
00442         }
00443         // Save the list of materials
00444         stream << materialsList;
00445 
00446         // Save the list of mesh
00447         const int meshNumber= rep.m_pGeomList->size();
00448         stream << meshNumber;
00449         for (int i= 0; i < meshNumber; ++i)
00450         {
00451                 GLC_Mesh* pMesh= dynamic_cast<GLC_Mesh*>(rep.m_pGeomList->at(i));
00452                 if (NULL != pMesh)
00453                 {
00454                         pMesh->saveToDataStream(stream);
00455                 }
00456         }
00457 
00458         return stream;
00459 }
00460 QDataStream &operator>>(QDataStream & stream, GLC_3DRep & rep)
00461 {
00462         Q_ASSERT(rep.isEmpty());
00463 
00464         quint32 chunckId;
00465         stream >> chunckId;
00466         Q_ASSERT(chunckId == GLC_3DRep::m_ChunkId);
00467 
00468         // The rep name
00469         QString name;
00470         stream >> name;
00471         rep.setName(name);
00472 
00473         // Retrieve the list of rep materials
00474         QList<GLC_Material> materialsList;
00475         stream >> materialsList;
00476         MaterialHash materialHash;
00477         // Update mesh materials hash table
00478         QHash<GLC_uint, GLC_uint> materialIdMap;
00479         const int materialsCount= materialsList.size();
00480         for (int i= 0; i < materialsCount; ++i)
00481         {
00482                 GLC_Material* pMaterial= new GLC_Material(materialsList.at(i));
00483                 pMaterial->setId(glc::GLC_GenID());
00484                 materialIdMap.insert(materialsList.at(i).id(), pMaterial->id());
00485                 materialHash.insert(pMaterial->id(), pMaterial);
00486         }
00487 
00488         int meshNumber;
00489         stream >> meshNumber;
00490         for (int i= 0; i < meshNumber; ++i)
00491         {
00492                 GLC_Mesh* pMesh= new GLC_Mesh();
00493                 pMesh->loadFromDataStream(stream, materialHash, materialIdMap);
00494 
00495                 rep.addGeom(pMesh);
00496         }
00497 
00498         return stream;
00499 }

SourceForge.net Logo

©2005-2011 Laurent Ribon