GLC_lib  2.5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
glc_3drep.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 
23 #include "glc_3drep.h"
24 #include "../glc_factory.h"
25 #include "glc_mesh.h"
26 #include "glc_errorlog.h"
27 
28 // Class chunk id
29 quint32 GLC_3DRep::m_ChunkId= 0xA702;
30 
32 : GLC_Rep()
33 , m_pGeomList(new QList<GLC_Geometry*>)
34 , m_pType(new int(GLC_Rep::GLC_VBOGEOM))
35 {
36 
37 }
38 
40 : GLC_Rep()
41 , m_pGeomList(new QList<GLC_Geometry*>)
42 , m_pType(new int(GLC_Rep::GLC_VBOGEOM))
43 {
44  m_pGeomList->append(pGeom);
45  *m_pIsLoaded= true;
46  setName(pGeom->name());
47 }
48 
50 : GLC_Rep(rep)
51 , m_pGeomList(rep.m_pGeomList)
52 , m_pType(rep.m_pType)
53 {
54 
55 }
56 
58 {
59  const GLC_3DRep* p3DRep= dynamic_cast<const GLC_3DRep*>(&rep);
60  Q_ASSERT(NULL != p3DRep);
61  if (this != &rep)
62  {
63  if (isTheLast())
64  {
65  GLC_Rep::operator=(rep);
67  delete m_pGeomList;
68  m_pGeomList= NULL;
69  delete m_pType;
70  m_pType= NULL;
71  }
72 
73  m_pGeomList= p3DRep->m_pGeomList;
74  m_pType= p3DRep->m_pType;
75  }
76 
77  return *this;
78 }
79 
81 {
82  return new GLC_3DRep(*this);
83 }
84 
86 {
87  GLC_3DRep* pCloneRep= new GLC_3DRep;
88  // Copy fields of the base class
89  pCloneRep->setFileName(fileName());
90  pCloneRep->setName(name());
91  // Copy representation geometries
92  const int size= m_pGeomList->size();
93  for (int i= 0; i < size; ++i)
94  {
95  pCloneRep->addGeom(m_pGeomList->at(i)->clone());
96  }
97  return pCloneRep;
98 }
99 
101 {
102  if (isTheLast())
103  {
104  clear3DRepGeom();
105 
106  delete m_pGeomList;
107  m_pGeomList= NULL;
108 
109  delete m_pType;
110  m_pType= NULL;
111  }
112 }
113 
115 // Get functions
118 {
119  return m_ChunkId;
120 }
121 
122 int GLC_3DRep::type() const
123 {
124  return (*m_pType);
125 }
126 
128 // Get functions
130 
132 {
133  bool result= !m_pGeomList->isEmpty();
134  const int max= m_pGeomList->size();
135  int index= 0;
136  while (result && (index < max))
137  {
138  result= result && m_pGeomList->at(index)->boundingBoxIsValid();
139  ++index;
140  }
141  return result;
142 }
143 
145 {
146  GLC_BoundingBox resultBox;
147  const int size= m_pGeomList->size();
148  for (int i= 0; i < size; ++i)
149  {
150  resultBox.combine(m_pGeomList->at(i)->boundingBox());
151  }
152  return resultBox;
153 }
154 
155 unsigned int GLC_3DRep::faceCount() const
156 {
157  unsigned int result= 0;
158  if (!m_pGeomList->isEmpty())
159  {
160  const int size= m_pGeomList->size();
161  for (int i= 0; i < size; ++i)
162  {
163  result+= m_pGeomList->at(i)->faceCount();
164  }
165  }
166 
167  return result;
168 }
169 
170 unsigned int GLC_3DRep::vertexCount() const
171 {
172  unsigned int result= 0;
173  if (!m_pGeomList->isEmpty())
174  {
175  const int size= m_pGeomList->size();
176  for (int i= 0; i < size; ++i)
177  {
178  result+= m_pGeomList->at(i)->VertexCount();
179  }
180  }
181 
182  return result;
183 }
184 
185 unsigned int GLC_3DRep::materialCount() const
186 {
187  unsigned int result= 0;
188  if (!m_pGeomList->isEmpty())
189  {
190  const int size= m_pGeomList->size();
191  for (int i= 0; i < size; ++i)
192  {
193  result+= m_pGeomList->at(i)->materialCount();
194  }
195  }
196 
197  return result;
198 }
199 
200 QSet<GLC_Material*> GLC_3DRep::materialSet() const
201 {
202  QSet<GLC_Material*> result;
203  if (!m_pGeomList->isEmpty())
204  {
205  const int size= m_pGeomList->size();
206  for (int i= 0; i < size; ++i)
207  {
208  result.unite(m_pGeomList->at(i)->materialSet());
209  }
210  }
211 
212  return result;
213 }
214 
215 double GLC_3DRep::volume() const
216 {
217  double resultVolume= 0.0;
218  const int geomCount= m_pGeomList->count();
219  for (int i= 0; i < geomCount; ++i)
220  {
221  resultVolume+= m_pGeomList->at(i)->volume();
222  }
223 
224  return resultVolume;
225 }
226 
228 {
229  QList<GLC_Geometry*>::iterator iGeomList= m_pGeomList->begin();
230  while(iGeomList != m_pGeomList->constEnd())
231  {
232  if ((*iGeomList)->VertexCount() == 0)
233  {
234  qDebug() << "Delete empty geom--------------------";
235  delete (*iGeomList);
236  iGeomList= m_pGeomList->erase(iGeomList);
237  }
238  else
239  {
240  ++iGeomList;
241  }
242  }
243 }
244 
246 {
247  const int size= m_pGeomList->size();
248  for (int i= 0; i < size; ++i)
249  {
250  (*m_pGeomList)[i]->reverseNormals();
251  }
252 }
253 
255 {
256  bool loadSucces= false;
257 
258  if(!(*m_pIsLoaded))
259  {
260  Q_ASSERT(m_pGeomList->isEmpty());
261  if (fileName().isEmpty())
262  {
263  QStringList stringList("GLC_3DRep::load");
264  stringList.append("Representation : " + GLC_Rep::name());
265  stringList.append("Empty File Name");
266  GLC_ErrorLog::addError(stringList);
267  }
268  else
269  {
271  if (!newRep.isEmpty())
272  {
273  const int size= newRep.m_pGeomList->size();
274  for (int i= 0; i < size; ++i)
275  {
276  m_pGeomList->append(newRep.m_pGeomList->at(i));
277  }
278  newRep.m_pGeomList->clear();
279  (*m_pIsLoaded)= true;
280  loadSucces= true;
281  }
282  }
283  }
284 
285  return loadSucces;
286 
287 }
288 
290 {
291  GLC_3DRep* p3DRep= dynamic_cast<GLC_3DRep*>(pRep);
292  Q_ASSERT(NULL != p3DRep);
293 
294  (*m_pType)= *(p3DRep->m_pType);
295 
296  clear3DRepGeom();
297  setFileName(p3DRep->fileName());
298  setName(p3DRep->name());
299 
300  if (!p3DRep->isEmpty())
301  {
302  const int size= p3DRep->m_pGeomList->size();
303  for (int i= 0; i < size; ++i)
304  {
305  m_pGeomList->append(p3DRep->m_pGeomList->at(i));
306  }
307  p3DRep->m_pGeomList->clear();
308  (*m_pIsLoaded)= true;
309  }
310 }
311 
313 {
314  //qDebug() << "GLC_3DRep::replaceMaterial";
315  const int size= m_pGeomList->size();
316  for (int i= 0; i < size; ++i)
317  {
318  GLC_Geometry* pGeom= m_pGeomList->at(i);
319  if (pGeom->containsMaterial(oldId))
320  {
321  Q_ASSERT(!pGeom->containsMaterial(pNewMaterial->id()));
322  GLC_Mesh* pMesh= dynamic_cast<GLC_Mesh*>(m_pGeomList->at(i));
323  if (NULL != pMesh)
324  {
325  pMesh->replaceMaterial(oldId, pNewMaterial);
326  }
327  }
328  }
329 }
330 
331 void GLC_3DRep::merge(const GLC_3DRep* pRep)
332 {
333  // Get the number of geometry of pRep
334  const int pRepSize= pRep->m_pGeomList->size();
335  for (int i= 0; i < pRepSize; ++i)
336  {
337  addGeom(pRep->geomAt(i)->clone());
338  }
339 }
340 
342 {
343  // Get the number of geometry of pRep
344  const int pRepSize= pSource->m_pGeomList->size();
345  for (int i= 0; i < pRepSize; ++i)
346  {
347  addGeom(pSource->geomAt(i));
348  }
349  pSource->m_pGeomList->clear();
350 }
351 
353 {
354  // Get the number of geometry of pRep
355  const int pRepSize= m_pGeomList->size();
356  for (int i= 0; i < pRepSize; ++i)
357  {
359  }
360 }
361 
363 {
364  // Get the number of geometry of pRep
365  const int pRepSize= m_pGeomList->size();
366  for (int i= 0; i < pRepSize; ++i)
367  {
368  geomAt(i)->releaseVboClientSide(update);
369  }
370 }
371 
373 {
374  // Get the number of geometry of pRep
375  const int repCount= m_pGeomList->size();
376  for (int i= 0; i < repCount; ++i)
377  {
378  GLC_Mesh* pCurrentMesh= dynamic_cast<GLC_Mesh*>(geomAt(i));
379  if (NULL != pCurrentMesh)
380  {
381  pCurrentMesh->transformVertice(matrix);
382  }
383  }
384 }
385 
386 void GLC_3DRep::setVboUsage(bool usage)
387 {
388  // Get the number of geometry of pRep
389  const int repCount= m_pGeomList->size();
390  for (int i= 0; i < repCount; ++i)
391  {
392  m_pGeomList->at(i)->setVboUsage(usage);
393  }
394 }
395 
397 {
398  bool unloadSucess= false;
399  if ((NULL != m_pGeomList) && !m_pGeomList->isEmpty())
400  {
401  if (fileName().isEmpty())
402  {
403  QStringList stringList("GLC_3DRep::unload()");
404  stringList.append("Cannot unload rep without filename");
405  GLC_ErrorLog::addError(stringList);
406  }
407  else
408  {
409  const int size= m_pGeomList->size();
410  for (int i= 0; i < size; ++i)
411  {
412  delete (*m_pGeomList)[i];
413  }
414  m_pGeomList->clear();
415 
416  (*m_pIsLoaded)= false;
417  unloadSucess= true;
418  }
419  }
420  return unloadSucess;
421 }
422 
424 // private services functions
426 
428 {
429  const int size= m_pGeomList->size();
430  for (int i= 0; i < size; ++i)
431  {
432  delete (*m_pGeomList)[i];
433  }
434  m_pGeomList->clear();
435 }
436 
437 // Non Member methods
438 QDataStream &operator<<(QDataStream & stream, const GLC_3DRep & rep)
439 {
440  quint32 chunckId= GLC_3DRep::m_ChunkId;
441  stream << chunckId;
442 
443  // The representation name
444  stream << rep.name();
445 
446  // Save the list of 3DRep materials
447  QList<GLC_Material> materialsList;
448  QList<GLC_Material*> sourceMaterialsList= rep.materialSet().toList();
449  const int materialNumber= sourceMaterialsList.size();
450  for (int i= 0; i < materialNumber; ++i)
451  {
452  materialsList.append(*(sourceMaterialsList.at(i)));
453  materialsList[i].setId(sourceMaterialsList.at(i)->id());
454  }
455  // Save the list of materials
456  stream << materialsList;
457 
458  // Save the list of mesh
459  const int meshNumber= rep.m_pGeomList->size();
460  stream << meshNumber;
461  for (int i= 0; i < meshNumber; ++i)
462  {
463  GLC_Mesh* pMesh= dynamic_cast<GLC_Mesh*>(rep.m_pGeomList->at(i));
464  if (NULL != pMesh)
465  {
466  pMesh->saveToDataStream(stream);
467  }
468  }
469 
470  return stream;
471 }
472 
473 QDataStream &operator>>(QDataStream & stream, GLC_3DRep & rep)
474 {
475  Q_ASSERT(rep.isEmpty());
476 
477  quint32 chunckId;
478  stream >> chunckId;
479  Q_ASSERT(chunckId == GLC_3DRep::m_ChunkId);
480 
481  // The rep name
482  QString name;
483  stream >> name;
484  rep.setName(name);
485 
486  // Retrieve the list of rep materials
487  QList<GLC_Material> materialsList;
488  stream >> materialsList;
489  MaterialHash materialHash;
490  // Update mesh materials hash table
491  QHash<GLC_uint, GLC_uint> materialIdMap;
492  const int materialsCount= materialsList.size();
493  for (int i= 0; i < materialsCount; ++i)
494  {
495  GLC_Material* pMaterial= new GLC_Material(materialsList.at(i));
496  pMaterial->setId(glc::GLC_GenID());
497  materialIdMap.insert(materialsList.at(i).id(), pMaterial->id());
498  materialHash.insert(pMaterial->id(), pMaterial);
499  }
500 
501  int meshNumber;
502  stream >> meshNumber;
503  for (int i= 0; i < meshNumber; ++i)
504  {
505  GLC_Mesh* pMesh= new GLC_Mesh();
506  pMesh->loadFromDataStream(stream, materialHash, materialIdMap);
507 
508  rep.addGeom(pMesh);
509  }
510 
511  return stream;
512 }

©2005-2013 Laurent Ribon