glc_3drep.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00029 quint32 GLC_3DRep::m_ChunkId= 0xA702;
00030
00031
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
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
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
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
00077 GLC_Rep* GLC_3DRep::clone() const
00078 {
00079 return new GLC_3DRep(*this);
00080 }
00081
00082
00083 GLC_Rep* GLC_3DRep::deepCopy() const
00084 {
00085 GLC_3DRep* pCloneRep= new GLC_3DRep;
00086
00087 pCloneRep->setFileName(fileName());
00088 pCloneRep->setName(name());
00089
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
00099 GLC_3DRep::~GLC_3DRep()
00100 {
00101 clear();
00102 }
00103
00105
00107
00108 quint32 GLC_3DRep::chunckID()
00109 {
00110 return m_ChunkId;
00111 }
00112
00113
00114 int GLC_3DRep::type() const
00115 {
00116 return (*m_pType);
00117 }
00118
00120
00122
00123
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
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
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
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
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
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
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
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
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
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
00299 void GLC_3DRep::replaceMaterial(GLC_uint oldId, GLC_Material* pNewMaterial)
00300 {
00301
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
00319 void GLC_3DRep::merge(const GLC_3DRep* pRep)
00320 {
00321
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
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
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
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
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
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
00406
00407
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
00425
00426 QDataStream &operator<<(QDataStream & stream, const GLC_3DRep & rep)
00427 {
00428 quint32 chunckId= GLC_3DRep::m_ChunkId;
00429 stream << chunckId;
00430
00431
00432 stream << rep.name();
00433
00434
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
00444 stream << materialsList;
00445
00446
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
00469 QString name;
00470 stream >> name;
00471 rep.setName(name);
00472
00473
00474 QList<GLC_Material> materialsList;
00475 stream >> materialsList;
00476 MaterialHash materialHash;
00477
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 }