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 GLC_3DRep::GLC_3DRep()
00032 : GLC_Rep()
00033 , m_pGeomList(new QList<GLC_Geometry*>)
00034 , m_pType(new int(GLC_Rep::GLC_VBOGEOM))
00035 {
00036 
00037 }
00038 
00039 GLC_3DRep::GLC_3DRep(GLC_Geometry* pGeom)
00040 : GLC_Rep()
00041 , m_pGeomList(new QList<GLC_Geometry*>)
00042 , m_pType(new int(GLC_Rep::GLC_VBOGEOM))
00043 {
00044         m_pGeomList->append(pGeom);
00045         *m_pIsLoaded= true;
00046         setName(pGeom->name());
00047 }
00048 
00049 GLC_3DRep::GLC_3DRep(const GLC_3DRep& rep)
00050 : GLC_Rep(rep)
00051 , m_pGeomList(rep.m_pGeomList)
00052 , m_pType(rep.m_pType)
00053 {
00054 
00055 }
00056 
00057 GLC_3DRep& GLC_3DRep::operator=(const GLC_Rep& rep)
00058 {
00059         const GLC_3DRep* p3DRep= dynamic_cast<const GLC_3DRep*>(&rep);
00060         Q_ASSERT(NULL != p3DRep);
00061         if (this != &rep)
00062         {
00063                 clear();
00064                 GLC_Rep::operator=(rep);
00065                 m_pGeomList= p3DRep->m_pGeomList;
00066                 m_pType= p3DRep->m_pType;
00067         }
00068 
00069         return *this;
00070 }
00071 
00072 GLC_Rep* GLC_3DRep::clone() const
00073 {
00074         return new GLC_3DRep(*this);
00075 }
00076 
00077 GLC_Rep* GLC_3DRep::deepCopy() const
00078 {
00079         GLC_3DRep* pCloneRep= new GLC_3DRep;
00080         // Copy fields of the base class
00081         pCloneRep->setFileName(fileName());
00082         pCloneRep->setName(name());
00083         // Copy representation geometries
00084         const int size= m_pGeomList->size();
00085         for (int i= 0; i < size; ++i)
00086         {
00087                 pCloneRep->addGeom(m_pGeomList->at(i)->clone());
00088         }
00089         return pCloneRep;
00090 }
00091 
00092 GLC_3DRep::~GLC_3DRep()
00093 {
00094         clear();
00095 }
00096 
00098 // Get functions
00100 quint32 GLC_3DRep::chunckID()
00101 {
00102         return m_ChunkId;
00103 }
00104 
00105 int GLC_3DRep::type() const
00106 {
00107         return (*m_pType);
00108 }
00109 
00111 // Get functions
00113 
00114 bool GLC_3DRep::boundingBoxIsValid() const
00115 {
00116         bool result= !m_pGeomList->isEmpty();
00117         const int max= m_pGeomList->size();
00118         int index= 0;
00119         while (result && (index < max))
00120         {
00121                 result= result && m_pGeomList->at(index)->boundingBoxIsValid();
00122                 ++index;
00123         }
00124         return result;
00125 }
00126 
00127 GLC_BoundingBox GLC_3DRep::boundingBox() const
00128 {
00129         GLC_BoundingBox resultBox;
00130         const int size= m_pGeomList->size();
00131         for (int i= 0; i < size; ++i)
00132         {
00133                 resultBox.combine(m_pGeomList->at(i)->boundingBox());
00134         }
00135         return resultBox;
00136 }
00137 
00138 unsigned int GLC_3DRep::faceCount() const
00139 {
00140         unsigned int result= 0;
00141         if (!m_pGeomList->isEmpty())
00142         {
00143                 const int size= m_pGeomList->size();
00144                 for (int i= 0; i < size; ++i)
00145                 {
00146                         result+= m_pGeomList->at(i)->faceCount();
00147                 }
00148         }
00149 
00150         return result;
00151 }
00152 
00153 unsigned int GLC_3DRep::vertexCount() const
00154 {
00155         unsigned int result= 0;
00156         if (!m_pGeomList->isEmpty())
00157         {
00158                 const int size= m_pGeomList->size();
00159                 for (int i= 0; i < size; ++i)
00160                 {
00161                         result+= m_pGeomList->at(i)->VertexCount();
00162                 }
00163         }
00164 
00165         return result;
00166 }
00167 
00168 unsigned int GLC_3DRep::materialCount() const
00169 {
00170         unsigned int result= 0;
00171         if (!m_pGeomList->isEmpty())
00172         {
00173                 const int size= m_pGeomList->size();
00174                 for (int i= 0; i < size; ++i)
00175                 {
00176                         result+= m_pGeomList->at(i)->materialCount();
00177                 }
00178         }
00179 
00180         return result;
00181 }
00182 
00183 QSet<GLC_Material*> GLC_3DRep::materialSet() const
00184 {
00185         QSet<GLC_Material*> result;
00186         if (!m_pGeomList->isEmpty())
00187         {
00188                 const int size= m_pGeomList->size();
00189                 for (int i= 0; i < size; ++i)
00190                 {
00191                         result.unite(m_pGeomList->at(i)->materialSet());
00192                 }
00193         }
00194 
00195         return result;
00196 }
00197 
00198 double GLC_3DRep::volume() const
00199 {
00200         double resultVolume= 0.0;
00201         const int geomCount= m_pGeomList->count();
00202         for (int i= 0; i < geomCount; ++i)
00203         {
00204                 resultVolume+= m_pGeomList->at(i)->volume();
00205         }
00206 
00207         return resultVolume;
00208 }
00209 
00210 void GLC_3DRep::clean()
00211 {
00212         QList<GLC_Geometry*>::iterator iGeomList= m_pGeomList->begin();
00213         while(iGeomList != m_pGeomList->constEnd())
00214         {
00215                 if ((*iGeomList)->VertexCount() == 0)
00216                 {
00217                         qDebug() << "Delete empty geom--------------------";
00218                         delete (*iGeomList);
00219                         iGeomList= m_pGeomList->erase(iGeomList);
00220                 }
00221                 else
00222                 {
00223                         ++iGeomList;
00224                 }
00225         }
00226 }
00227 
00228 void GLC_3DRep::reverseNormals()
00229 {
00230         const int size= m_pGeomList->size();
00231         for (int i= 0; i < size; ++i)
00232         {
00233                 (*m_pGeomList)[i]->reverseNormals();
00234         }
00235 }
00236 
00237 bool GLC_3DRep::load()
00238 {
00239         bool loadSucces= false;
00240 
00241         if(!(*m_pIsLoaded))
00242         {
00243                 Q_ASSERT(m_pGeomList->isEmpty());
00244                 if (fileName().isEmpty())
00245                 {
00246                         QStringList stringList("GLC_3DRep::load");
00247                         stringList.append("Representation : " + GLC_Rep::name());
00248                         stringList.append("Empty File Name");
00249                         GLC_ErrorLog::addError(stringList);
00250                 }
00251                 else
00252                 {
00253                         GLC_3DRep newRep= GLC_Factory::instance()->create3DRepFromFile(fileName());
00254                         if (!newRep.isEmpty())
00255                         {
00256                                 const int size= newRep.m_pGeomList->size();
00257                                 for (int i= 0; i < size; ++i)
00258                                 {
00259                                         m_pGeomList->append(newRep.m_pGeomList->at(i));
00260                                 }
00261                                 newRep.m_pGeomList->clear();
00262                                 (*m_pIsLoaded)= true;
00263                                 loadSucces= true;
00264                         }
00265                 }
00266         }
00267 
00268         return loadSucces;
00269 
00270 }
00271 
00272 void GLC_3DRep::replace(GLC_Rep* pRep)
00273 {
00274         GLC_3DRep* p3DRep= dynamic_cast<GLC_3DRep*>(pRep);
00275         Q_ASSERT(NULL != p3DRep);
00276 
00277         setFileName(p3DRep->fileName());
00278         setName(p3DRep->name());
00279 
00280         if (!p3DRep->isEmpty())
00281         {
00282                 const int size= p3DRep->m_pGeomList->size();
00283                 for (int i= 0; i < size; ++i)
00284                 {
00285                         m_pGeomList->append(p3DRep->m_pGeomList->at(i));
00286                 }
00287                 p3DRep->m_pGeomList->clear();
00288                 (*m_pIsLoaded)= true;
00289         }
00290 }
00291 
00292 void GLC_3DRep::replaceMaterial(GLC_uint oldId, GLC_Material* pNewMaterial)
00293 {
00294         //qDebug() << "GLC_3DRep::replaceMaterial";
00295         const int size= m_pGeomList->size();
00296         for (int i= 0; i < size; ++i)
00297         {
00298                 GLC_Geometry* pGeom= m_pGeomList->at(i);
00299                 if (pGeom->containsMaterial(oldId))
00300                 {
00301                         Q_ASSERT(!pGeom->containsMaterial(pNewMaterial->id()));
00302                         GLC_Mesh* pMesh= dynamic_cast<GLC_Mesh*>(m_pGeomList->at(i));
00303                         if (NULL != pMesh)
00304                         {
00305                                 pMesh->replaceMaterial(oldId, pNewMaterial);
00306                         }
00307                 }
00308         }
00309 }
00310 
00311 void GLC_3DRep::merge(const GLC_3DRep* pRep)
00312 {
00313         // Get the number of geometry of pRep
00314         const int pRepSize= pRep->m_pGeomList->size();
00315         for (int i= 0; i < pRepSize; ++i)
00316         {
00317                 addGeom(pRep->geomAt(i)->clone());
00318         }
00319 }
00320 
00321 void GLC_3DRep::take(GLC_3DRep* pSource)
00322 {
00323         // Get the number of geometry of pRep
00324         const int pRepSize= pSource->m_pGeomList->size();
00325         for (int i= 0; i < pRepSize; ++i)
00326         {
00327                 addGeom(pSource->geomAt(i));
00328         }
00329         pSource->m_pGeomList->clear();
00330 }
00331 
00332 void GLC_3DRep::copyVboToClientSide()
00333 {
00334         // Get the number of geometry of pRep
00335         const int pRepSize= m_pGeomList->size();
00336         for (int i= 0; i < pRepSize; ++i)
00337         {
00338                 geomAt(i)->copyVboToClientSide();
00339         }
00340 }
00341 
00342 void GLC_3DRep::releaseVboClientSide(bool update)
00343 {
00344         // Get the number of geometry of pRep
00345         const int pRepSize= m_pGeomList->size();
00346         for (int i= 0; i < pRepSize; ++i)
00347         {
00348                 geomAt(i)->releaseVboClientSide(update);
00349         }
00350 }
00351 
00352 void GLC_3DRep::transformSubGeometries(const GLC_Matrix4x4& matrix)
00353 {
00354         // Get the number of geometry of pRep
00355         const int repCount= m_pGeomList->size();
00356         for (int i= 0; i < repCount; ++i)
00357         {
00358                 GLC_Mesh* pCurrentMesh= dynamic_cast<GLC_Mesh*>(geomAt(i));
00359                 if (NULL != pCurrentMesh)
00360                 {
00361                         pCurrentMesh->transformVertice(matrix);
00362                 }
00363         }
00364 }
00365 
00366 void GLC_3DRep::setVboUsage(bool usage)
00367 {
00368         // Get the number of geometry of pRep
00369         const int repCount= m_pGeomList->size();
00370         for (int i= 0; i < repCount; ++i)
00371         {
00372                 m_pGeomList->at(i)->setVboUsage(usage);
00373         }
00374 }
00375 
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 void GLC_3DRep::clear()
00408 {
00409         if (isTheLast())
00410         {
00411                 const int size= m_pGeomList->size();
00412                 for (int i= 0; i < size; ++i)
00413                 {
00414                         delete (*m_pGeomList)[i];
00415                 }
00416                 delete m_pGeomList;
00417                 m_pGeomList= NULL;
00418 
00419                 delete m_pType;
00420                 m_pType= NULL;
00421         }
00422 }
00423 // Non Member methods
00424 QDataStream &operator<<(QDataStream & stream, const GLC_3DRep & rep)
00425 {
00426         quint32 chunckId= GLC_3DRep::m_ChunkId;
00427         stream << chunckId;
00428 
00429         // The representation name
00430         stream << rep.name();
00431 
00432         // Save the list of 3DRep materials
00433         QList<GLC_Material> materialsList;
00434         QList<GLC_Material*> sourceMaterialsList= rep.materialSet().toList();
00435         const int materialNumber= sourceMaterialsList.size();
00436         for (int i= 0; i < materialNumber; ++i)
00437         {
00438                 materialsList.append(*(sourceMaterialsList.at(i)));
00439                 materialsList[i].setId(sourceMaterialsList.at(i)->id());
00440         }
00441         // Save the list of materials
00442         stream << materialsList;
00443 
00444         // Save the list of mesh
00445         const int meshNumber= rep.m_pGeomList->size();
00446         stream << meshNumber;
00447         for (int i= 0; i < meshNumber; ++i)
00448         {
00449                 GLC_Mesh* pMesh= dynamic_cast<GLC_Mesh*>(rep.m_pGeomList->at(i));
00450                 if (NULL != pMesh)
00451                 {
00452                         pMesh->saveToDataStream(stream);
00453                 }
00454         }
00455 
00456         return stream;
00457 }
00458 
00459 QDataStream &operator>>(QDataStream & stream, GLC_3DRep & rep)
00460 {
00461         Q_ASSERT(rep.isEmpty());
00462 
00463         quint32 chunckId;
00464         stream >> chunckId;
00465         Q_ASSERT(chunckId == GLC_3DRep::m_ChunkId);
00466 
00467         // The rep name
00468         QString name;
00469         stream >> name;
00470         rep.setName(name);
00471 
00472         // Retrieve the list of rep materials
00473         QList<GLC_Material> materialsList;
00474         stream >> materialsList;
00475         MaterialHash materialHash;
00476         // Update mesh materials hash table
00477         QHash<GLC_uint, GLC_uint> materialIdMap;
00478         const int materialsCount= materialsList.size();
00479         for (int i= 0; i < materialsCount; ++i)
00480         {
00481                 GLC_Material* pMaterial= new GLC_Material(materialsList.at(i));
00482                 pMaterial->setId(glc::GLC_GenID());
00483                 materialIdMap.insert(materialsList.at(i).id(), pMaterial->id());
00484                 materialHash.insert(pMaterial->id(), pMaterial);
00485         }
00486 
00487         int meshNumber;
00488         stream >> meshNumber;
00489         for (int i= 0; i < meshNumber; ++i)
00490         {
00491                 GLC_Mesh* pMesh= new GLC_Mesh();
00492                 pMesh->loadFromDataStream(stream, materialHash, materialIdMap);
00493 
00494                 rep.addGeom(pMesh);
00495         }
00496 
00497         return stream;
00498 }

SourceForge.net Logo

©2005-2011 Laurent Ribon