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  Version 2.0.0 Beta 1, packaged on April 2010.
00006 
00007  http://glc-lib.sourceforge.net
00008 
00009  GLC-lib is free software; you can redistribute it and/or modify
00010  it under the terms of the GNU General Public License as published by
00011  the Free Software Foundation; either version 2 of the License, or
00012  (at your option) any later version.
00013 
00014  GLC-lib is distributed in the hope that it will be useful,
00015  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  GNU General Public License for more details.
00018 
00019  You should have received a copy of the GNU General Public License
00020  along with GLC-lib; if not, write to the Free Software
00021  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00022 
00023  *****************************************************************************/
00024 
00025 #include "glc_3drep.h"
00026 #include "../glc_factory.h"
00027 #include "glc_mesh.h"
00028 
00029 // Class chunk id
00030 quint32 GLC_3DRep::m_ChunkId= 0xA702;
00031 
00032 // Default constructor
00033 GLC_3DRep::GLC_3DRep()
00034 : GLC_Rep()
00035 , m_pGeomList(new QList<GLC_Geometry*>)
00036 , m_pType(new int(GLC_Rep::GLC_VBOGEOM))
00037 {
00038 
00039 }
00040 
00041 // Construct a 3DRep with a geometry
00042 GLC_3DRep::GLC_3DRep(GLC_Geometry* pGeom)
00043 : GLC_Rep()
00044 , m_pGeomList(new QList<GLC_Geometry*>)
00045 , m_pType(new int(GLC_Rep::GLC_VBOGEOM))
00046 {
00047         m_pGeomList->append(pGeom);
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_3DRep& rep)
00062 {
00063         clear();
00064         GLC_Rep::operator=(rep);
00065         m_pGeomList= rep.m_pGeomList;
00066         m_pType= rep.m_pType;
00067 
00068         return *this;
00069 }
00070 
00071 // Clone the representation
00072 GLC_Rep* GLC_3DRep::clone() const
00073 {
00074         return new GLC_3DRep(*this);
00075 }
00076 
00077 // Make a deep copy of the 3DRep
00078 GLC_Rep* GLC_3DRep::deepCopy() const
00079 {
00080         GLC_3DRep* pCloneRep= new GLC_3DRep;
00081         // Copy fields of the base class
00082         pCloneRep->setFileName(fileName());
00083         pCloneRep->setName(name());
00084         // Copy representation geometries
00085         const int size= m_pGeomList->size();
00086         for (int i= 0; i < size; ++i)
00087         {
00088                 pCloneRep->addGeom(m_pGeomList->at(i)->clone());
00089         }
00090         return pCloneRep;
00091 }
00092 
00093 // Destructor
00094 GLC_3DRep::~GLC_3DRep()
00095 {
00096         clear();
00097 }
00098 
00100 // Get functions
00102 // Return the class Chunk ID
00103 quint32 GLC_3DRep::chunckID()
00104 {
00105         return m_ChunkId;
00106 }
00107 
00108 // Return the type of representation
00109 int GLC_3DRep::type() const
00110 {
00111         return (*m_pType);
00112 }
00113 
00115 // Get functions
00117 
00118 // Return true if the rep bounding box is valid
00119 bool GLC_3DRep::boundingBoxIsValid() const
00120 {
00121         bool result= !m_pGeomList->isEmpty();
00122         const int max= m_pGeomList->size();
00123         int index= 0;
00124         while (result && (index < max))
00125         {
00126                 result= result && m_pGeomList->at(index)->boundingBoxIsValid();
00127                 ++index;
00128         }
00129         return result;
00130 }
00131 
00132 // Return the 3DRep bounding Box
00133 GLC_BoundingBox GLC_3DRep::boundingBox() const
00134 {
00135         GLC_BoundingBox resultBox;
00136         const int size= m_pGeomList->size();
00137         for (int i= 0; i < size; ++i)
00138         {
00139                 resultBox.combine(m_pGeomList->at(i)->boundingBox());
00140         }
00141         return resultBox;
00142 }
00143 
00144 // Get number of faces
00145 unsigned int GLC_3DRep::faceCount() const
00146 {
00147         unsigned int result= 0;
00148         if (!m_pGeomList->isEmpty())
00149         {
00150                 const int size= m_pGeomList->size();
00151                 for (int i= 0; i < size; ++i)
00152                 {
00153                         result+= m_pGeomList->at(i)->faceCount();
00154                 }
00155         }
00156 
00157         return result;
00158 }
00159 
00160 // Get number of vertex
00161 unsigned int GLC_3DRep::vertexCount() const
00162 {
00163         unsigned int result= 0;
00164         if (!m_pGeomList->isEmpty())
00165         {
00166                 const int size= m_pGeomList->size();
00167                 for (int i= 0; i < size; ++i)
00168                 {
00169                         result+= m_pGeomList->at(i)->VertexCount();
00170                 }
00171         }
00172 
00173         return result;
00174 }
00175 
00176 // Get number of materials
00177 unsigned int GLC_3DRep::materialCount() const
00178 {
00179         unsigned int result= 0;
00180         if (!m_pGeomList->isEmpty())
00181         {
00182                 const int size= m_pGeomList->size();
00183                 for (int i= 0; i < size; ++i)
00184                 {
00185                         result+= m_pGeomList->at(i)->materialCount();
00186                 }
00187         }
00188 
00189         return result;
00190 }
00191 
00192 // Get materials List
00193 QSet<GLC_Material*> GLC_3DRep::materialSet() const
00194 {
00195         QSet<GLC_Material*> result;
00196         if (!m_pGeomList->isEmpty())
00197         {
00198                 const int size= m_pGeomList->size();
00199                 for (int i= 0; i < size; ++i)
00200                 {
00201                         result.unite(m_pGeomList->at(i)->materialSet());
00202                 }
00203         }
00204 
00205         return result;
00206 }
00207 
00208 // Remove empty geometries
00209 void GLC_3DRep::clean()
00210 {
00211         QList<GLC_Geometry*>::iterator iGeomList= m_pGeomList->begin();
00212         while(iGeomList != m_pGeomList->constEnd())
00213         {
00214                 if ((*iGeomList)->VertexCount() == 0)
00215                 {
00216                         qDebug() << "Delete empty geom--------------------";
00217                         delete (*iGeomList);
00218                         iGeomList= m_pGeomList->erase(iGeomList);
00219                 }
00220                 else
00221                 {
00222                         ++iGeomList;
00223                 }
00224         }
00225 }
00226 
00227 // Reverse geometries normals
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 // Load the representation
00238 bool GLC_3DRep::load()
00239 {
00240         Q_ASSERT((!(*m_pIsLoaded)) == m_pGeomList->isEmpty());
00241         if ((*m_pIsLoaded) || fileName().isEmpty())
00242         {
00243                 qDebug() << "GLC_3DRep::load() Allready loaded or empty fileName";
00244                 return false;
00245         }
00246         GLC_3DRep newRep= GLC_Factory::instance()->create3DRepFromFile(fileName());
00247         if (!newRep.isEmpty())
00248         {
00249                 const int size= newRep.m_pGeomList->size();
00250                 for (int i= 0; i < size; ++i)
00251                 {
00252                         m_pGeomList->append(newRep.m_pGeomList->at(i));
00253                 }
00254                 newRep.m_pGeomList->clear();
00255                 (*m_pIsLoaded)= true;
00256                 return true;
00257         }
00258         else
00259         {
00260                 return false;
00261         }
00262 }
00263 // Replace the representation
00264 void GLC_3DRep::replace(GLC_Rep* pRep)
00265 {
00266         GLC_3DRep* p3DRep= dynamic_cast<GLC_3DRep*>(pRep);
00267         Q_ASSERT(NULL != p3DRep);
00268 
00269         setFileName(p3DRep->fileName());
00270         setName(p3DRep->name());
00271 
00272         if (!p3DRep->isEmpty())
00273         {
00274                 const int size= p3DRep->m_pGeomList->size();
00275                 for (int i= 0; i < size; ++i)
00276                 {
00277                         m_pGeomList->append(p3DRep->m_pGeomList->at(i));
00278                 }
00279                 p3DRep->m_pGeomList->clear();
00280                 (*m_pIsLoaded)= true;
00281         }
00282 }
00283 
00284 // Replace the specified material by a new one
00285 void GLC_3DRep::replaceMaterial(GLC_uint oldId, GLC_Material* pNewMaterial)
00286 {
00287         //qDebug() << "GLC_3DRep::replaceMaterial";
00288         const int size= m_pGeomList->size();
00289         for (int i= 0; i < size; ++i)
00290         {
00291                 GLC_Geometry* pGeom= m_pGeomList->at(i);
00292                 if (pGeom->containsMaterial(oldId))
00293                 {
00294                         Q_ASSERT(!pGeom->containsMaterial(pNewMaterial->id()));
00295                         GLC_Mesh* pMesh= dynamic_cast<GLC_Mesh*>(m_pGeomList->at(i));
00296                         if (NULL != pMesh)
00297                         {
00298                                 pMesh->replaceMaterial(oldId, pNewMaterial);
00299                         }
00300                 }
00301         }
00302 }
00303 
00304 // Merge this 3Drep with another 3DRep
00305 void GLC_3DRep::merge(GLC_3DRep* pRep)
00306 {
00307         // Get the number of geometry of pRep
00308         const int pRepSize= pRep->m_pGeomList->size();
00309         for (int i= 0; i < pRepSize; ++i)
00310         {
00311                 addGeom(pRep->geomAt(i)->clone());
00312         }
00313 }
00314 
00315 // UnLoad the representation
00316 bool GLC_3DRep::unload()
00317 {
00318         Q_ASSERT((!(*m_pIsLoaded)) == m_pGeomList->isEmpty());
00319         if (!(*m_pIsLoaded) || fileName().isEmpty())
00320         {
00321                 qDebug() << "GLC_3DRep::unload() Not loaded or empty fileName";
00322                 return false;
00323         }
00324 
00325         const int size= m_pGeomList->size();
00326         for (int i= 0; i < size; ++i)
00327         {
00328                 delete (*m_pGeomList)[i];
00329         }
00330 
00331         (*m_pIsLoaded)= false;
00332         return true;
00333 }
00334 
00336 // private services functions
00338 
00339 // Clear the 3D representation
00340 void GLC_3DRep::clear()
00341 {
00342         if (isTheLast())
00343         {
00344                 const int size= m_pGeomList->size();
00345                 for (int i= 0; i < size; ++i)
00346                 {
00347                         delete (*m_pGeomList)[i];
00348                 }
00349                 delete m_pGeomList;
00350                 m_pGeomList= NULL;
00351 
00352                 delete m_pType;
00353                 m_pType= NULL;
00354         }
00355 }
00356 // Non Member methods
00357 // Non-member stream operator
00358 QDataStream &operator<<(QDataStream & stream, const GLC_3DRep & rep)
00359 {
00360         quint32 chunckId= GLC_3DRep::m_ChunkId;
00361         stream << chunckId;
00362 
00363         // The representation name
00364         stream << rep.name();
00365 
00366         // Save the list of 3DRep materials
00367         QList<GLC_Material> materialsList;
00368         QList<GLC_Material*> sourceMaterialsList= rep.materialSet().toList();
00369         const int materialNumber= sourceMaterialsList.size();
00370         for (int i= 0; i < materialNumber; ++i)
00371         {
00372                 materialsList.append(*(sourceMaterialsList.at(i)));
00373                 materialsList[i].setId(sourceMaterialsList.at(i)->id());
00374         }
00375         // Save the list of materials
00376         stream << materialsList;
00377 
00378         // Save the list of mesh
00379         const int meshNumber= rep.m_pGeomList->size();
00380         stream << meshNumber;
00381         for (int i= 0; i < meshNumber; ++i)
00382         {
00383                 GLC_Mesh* pMesh= dynamic_cast<GLC_Mesh*>(rep.m_pGeomList->at(i));
00384                 if (NULL != pMesh)
00385                 {
00386                         pMesh->saveToDataStream(stream);
00387                 }
00388         }
00389 
00390         return stream;
00391 }
00392 QDataStream &operator>>(QDataStream & stream, GLC_3DRep & rep)
00393 {
00394         Q_ASSERT(rep.isEmpty());
00395 
00396         quint32 chunckId;
00397         stream >> chunckId;
00398         Q_ASSERT(chunckId == GLC_3DRep::m_ChunkId);
00399 
00400         // The rep name
00401         QString name;
00402         stream >> name;
00403         rep.setName(name);
00404 
00405         // Retrieve the list of rep materials
00406         QList<GLC_Material> materialsList;
00407         stream >> materialsList;
00408         MaterialHash materialHash;
00409         // Update mesh materials hash table
00410         QHash<GLC_uint, GLC_uint> materialIdMap;
00411         const int materialsCount= materialsList.size();
00412         for (int i= 0; i < materialsCount; ++i)
00413         {
00414                 GLC_Material* pMaterial= new GLC_Material(materialsList.at(i));
00415                 pMaterial->setId(glc::GLC_GenID());
00416                 materialIdMap.insert(materialsList.at(i).id(), pMaterial->id());
00417                 materialHash.insert(pMaterial->id(), pMaterial);
00418         }
00419 
00420         int meshNumber;
00421         stream >> meshNumber;
00422         for (int i= 0; i < meshNumber; ++i)
00423         {
00424                 GLC_Mesh* pMesh= new GLC_Mesh();
00425                 pMesh->loadFromDataStream(stream, materialHash, materialIdMap);
00426 
00427                 rep.addGeom(pMesh);
00428         }
00429 
00430         return stream;
00431 }

SourceForge.net Logo

©2005 Laurent Ribon