glc_structoccurence.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 
00026 
00027 #include "glc_structoccurence.h"
00028 #include "glc_3dviewcollection.h"
00029 #include "glc_structreference.h"
00030 #include "glc_worldhandle.h"
00031 
00032 // Default constructor
00033 GLC_StructOccurence::GLC_StructOccurence()
00034 : m_Uid(glc::GLC_GenID())
00035 , m_pWorldHandle(NULL)
00036 , m_pNumberOfOccurence(new int(1))
00037 , m_pStructInstance(new GLC_StructInstance())
00038 , m_pParent(NULL)
00039 , m_Childs()
00040 , m_AbsoluteMatrix()
00041 , m_HasRepresentation(m_pStructInstance->structReference()->hasRepresentation())
00042 , m_OccurenceNumber(0)
00043 , m_IsVisible(true)
00044 , m_pRenderProperties(NULL)
00045 {
00046         // Update instance
00047         m_pStructInstance->structOccurenceCreated(this);
00048 }
00049 
00050 
00051 // Default constructor
00052 GLC_StructOccurence::GLC_StructOccurence(GLC_StructInstance* pStructInstance, GLC_WorldHandle* pWorldHandle, GLuint shaderId)
00053 : m_Uid(glc::GLC_GenID())
00054 , m_pWorldHandle(pWorldHandle)
00055 , m_pNumberOfOccurence(NULL)
00056 , m_pStructInstance(pStructInstance)
00057 , m_pParent(NULL)
00058 , m_Childs()
00059 , m_AbsoluteMatrix()
00060 , m_HasRepresentation(pStructInstance->structReference()->hasRepresentation())
00061 , m_OccurenceNumber(0)
00062 , m_IsVisible(true)
00063 , m_pRenderProperties(NULL)
00064 {
00065         // Update the number of occurences
00066         if (pStructInstance->hasStructOccurence())
00067         {
00068                 GLC_StructOccurence* pFirstOccurence= pStructInstance->firstOccurenceHandle();
00069                 m_pNumberOfOccurence= pFirstOccurence->m_pNumberOfOccurence;
00070                 ++(*m_pNumberOfOccurence);
00071                 QList<GLC_StructOccurence*> childs= pFirstOccurence->m_Childs;
00072                 const int size= childs.size();
00073                 for (int i= 0; i < size; ++i)
00074                 {
00075                         GLC_StructOccurence* pChild= childs.at(i)->clone(m_pWorldHandle, true);
00076                         addChild(pChild);
00077                 }
00078         }
00079         else
00080         {
00081                 m_pNumberOfOccurence= new int(1);
00082         }
00083 
00084         setName(m_pStructInstance->name());
00085 
00086         // Inform the world Handle
00087         if (NULL != m_pWorldHandle)
00088         {
00089                 m_pWorldHandle->addOccurence(this, shaderId);
00090         }
00091 
00092         // Update Absolute matrix
00093         updateAbsoluteMatrix();
00094 
00095         // Update instance
00096         m_pStructInstance->structOccurenceCreated(this);
00097 }
00098 // Construct Occurence withe the specified GLC_3DRep
00099 GLC_StructOccurence::GLC_StructOccurence(GLC_3DRep* pRep)
00100 : m_Uid(glc::GLC_GenID())
00101 , m_pWorldHandle(NULL)
00102 , m_pNumberOfOccurence(new int(1))
00103 , m_pStructInstance(NULL)
00104 , m_pParent(NULL)
00105 , m_Childs()
00106 , m_AbsoluteMatrix()
00107 , m_HasRepresentation()
00108 , m_OccurenceNumber(0)
00109 , m_IsVisible(true)
00110 , m_pRenderProperties(NULL)
00111 {
00112         m_pStructInstance= new GLC_StructInstance(pRep);
00113         m_HasRepresentation= m_pStructInstance->structReference()->hasRepresentation();
00114         setName(m_pStructInstance->name());
00115 
00116         // Update instance
00117         m_pStructInstance->structOccurenceCreated(this);
00118 }
00119 
00120 // Copy constructor
00121 GLC_StructOccurence::GLC_StructOccurence(GLC_WorldHandle* pWorldHandle, const GLC_StructOccurence& structOccurence, bool shareInstance)
00122 : m_Uid(glc::GLC_GenID())
00123 , m_pWorldHandle(pWorldHandle)
00124 , m_pNumberOfOccurence(structOccurence.m_pNumberOfOccurence)
00125 , m_pStructInstance(NULL)
00126 , m_pParent(NULL)
00127 , m_Childs()
00128 , m_AbsoluteMatrix(structOccurence.m_AbsoluteMatrix)
00129 , m_HasRepresentation(structOccurence.m_HasRepresentation)
00130 , m_OccurenceNumber(0)
00131 , m_IsVisible(structOccurence.m_IsVisible)
00132 , m_pRenderProperties(NULL)
00133 {
00134         if (shareInstance)
00135         {
00136                 m_pStructInstance= structOccurence.m_pStructInstance;
00137         }
00138         else
00139         {
00140                 m_pStructInstance= new GLC_StructInstance(structOccurence.m_pStructInstance);
00141         }
00142 
00143         ++(*m_pNumberOfOccurence);
00144         // Test if structOccurence has representation and has a shader
00145         GLuint shaderId= 0;
00146         bool instanceIsSelected= false;
00147         if ((m_HasRepresentation) && (NULL != m_pWorldHandle) && (NULL != structOccurence.m_pWorldHandle))
00148         {
00149                 GLC_3DViewInstance* p3DViewInstance= structOccurence.m_pWorldHandle->collection()->instanceHandle(structOccurence.id());
00150 
00151                 if(structOccurence.m_pWorldHandle->collection()->isInAShadingGroup(structOccurence.id()))
00152                 {
00153                         shaderId= structOccurence.m_pWorldHandle->collection()->shadingGroup(structOccurence.id());
00154                 }
00155 
00156                 instanceIsSelected= p3DViewInstance->isSelected();
00157                 // Test the rendering properties
00158                 if (! p3DViewInstance->renderPropertiesHandle()->isDefault())
00159                 {
00160                         m_pRenderProperties= new GLC_RenderProperties(*(p3DViewInstance->renderPropertiesHandle()));
00161                 }
00162         }
00163         else if (NULL != structOccurence.m_pRenderProperties)
00164         {
00165                 m_pRenderProperties= new GLC_RenderProperties(*(structOccurence.m_pRenderProperties));
00166         }
00167 
00168         // Inform the world Handle
00169         if (NULL != m_pWorldHandle)
00170         {
00171                 m_pWorldHandle->addOccurence(this, instanceIsSelected, shaderId);
00172                 if (NULL != m_pRenderProperties)
00173                 {
00174                         m_pWorldHandle->collection()->instanceHandle(id())->setRenderProperties(*m_pRenderProperties);
00175                         delete m_pRenderProperties;
00176                         m_pRenderProperties= NULL;
00177                 }
00178         }
00179 
00180         // Update Absolute matrix
00181         updateAbsoluteMatrix();
00182 
00183 
00184         // Create childs
00185         const int size= structOccurence.childCount();
00186         for (int i= 0; i < size; ++i)
00187         {
00188                 GLC_StructOccurence* pChild= structOccurence.child(i)->clone(m_pWorldHandle, true);
00189                 addChild(pChild);
00190         }
00191         updateChildrenAbsoluteMatrix();
00192         // Update instance
00193         m_pStructInstance->structOccurenceCreated(this);
00194 }
00195 
00196 // Destructor
00197 GLC_StructOccurence::~GLC_StructOccurence()
00198 {
00199         //qDebug() << "Delete " << id();
00200         Q_ASSERT(m_pNumberOfOccurence != NULL);
00201         // Remove from the GLC_WorldHandle
00202         if (NULL != m_pWorldHandle)
00203         {
00204                 m_pWorldHandle->removeOccurence(this);
00205         }
00206 
00207         // Remove Childs
00208         const int size= m_Childs.size();
00209         for (int i= 0; i < size; ++i)
00210         {
00211                 GLC_StructOccurence* pChild= m_Childs.first();
00212                 removeChild(pChild);
00213                 delete pChild;
00214         }
00215         // Update number of occurence and instance
00216         if ((--(*m_pNumberOfOccurence)) == 0)
00217         {
00218                 delete m_pStructInstance;
00219                 delete m_pNumberOfOccurence;
00220         }
00221         else
00222         {
00223                 m_pStructInstance->structOccurenceDeleted(this);
00224         }
00225 
00226         delete m_pRenderProperties;
00227 }
00228 
00230 // Get Functions
00232 
00233 // Get number of faces
00234 unsigned int GLC_StructOccurence::numberOfFaces() const
00235 {
00236         unsigned int result= 0;
00237         if (m_HasRepresentation)
00238         {
00239                 result= structInstance()->structReference()->numberOfFaces();
00240         }
00241         else
00242         {
00243                 const int size= m_Childs.size();
00244                 for (int i= 0; i < size; ++i)
00245                 {
00246                         result+= m_Childs.at(i)->numberOfFaces();
00247                 }
00248         }
00249         return result;
00250 }
00251 
00252 // Get number of vertex
00253 unsigned int GLC_StructOccurence::numberOfVertex() const
00254 {
00255         unsigned int result= 0;
00256         if (m_HasRepresentation)
00257         {
00258                 result= structInstance()->structReference()->numberOfVertex();
00259         }
00260         else
00261         {
00262                 const int size= m_Childs.size();
00263                 for (int i= 0; i < size; ++i)
00264                 {
00265                         result+= m_Childs.at(i)->numberOfVertex();
00266                 }
00267         }
00268         return result;
00269 }
00270 
00271 // Get number of materials
00272 unsigned int GLC_StructOccurence::numberOfMaterials() const
00273 {
00274         unsigned int result= 0;
00275         QSet<GLC_Material*> materialSet;
00276         if (m_HasRepresentation)
00277         {
00278                 result= structInstance()->structReference()->numberOfMaterials();
00279         }
00280         else
00281         {
00282                 const int size= m_Childs.size();
00283                 for (int i= 0; i < size; ++i)
00284                 {
00285                         materialSet.unite(m_Childs.at(i)->materialSet());
00286                 }
00287                 result= static_cast<unsigned int>(materialSet.size());
00288         }
00289         return result;
00290 }
00291 
00292 // Get materials List
00293 QSet<GLC_Material*> GLC_StructOccurence::materialSet() const
00294 {
00295         QSet<GLC_Material*> materialSet;
00296         if (m_HasRepresentation)
00297         {
00298                 materialSet= structInstance()->structReference()->materialSet();
00299         }
00300         else
00301         {
00302                 const int size= m_Childs.size();
00303                 for (int i= 0; i < size; ++i)
00304                 {
00305                         materialSet.unite(m_Childs.at(i)->materialSet());
00306                 }
00307         }
00308         return materialSet;
00309 }
00310 
00311 // Clone the occurence
00312 GLC_StructOccurence* GLC_StructOccurence::clone(GLC_WorldHandle* pWorldHandle, bool shareInstance) const
00313 {
00314         return new GLC_StructOccurence(pWorldHandle, *this, shareInstance);
00315 }
00316 
00317 // Return true if the occurence is visible
00318 bool GLC_StructOccurence::isVisible() const
00319 {
00320         bool isHidden= true;
00321         if (m_HasRepresentation)
00322         {
00323                 isHidden= !m_pWorldHandle->collection()->instanceHandle(id())->isVisible();
00324         }
00325         else if (childCount() > 0)
00326         {
00327                 const int size= childCount();
00328                 int i= 0;
00329                 while ((i < size) && isHidden)
00330                 {
00331                         isHidden= isHidden && !child(i)->isVisible();
00332                         ++i;
00333                 }
00334         }
00335         else
00336         {
00337                 isHidden= !m_IsVisible;
00338         }
00339         return !isHidden;
00340 }
00341 
00342 // Return the occurence Bounding Box
00343 GLC_BoundingBox GLC_StructOccurence::boundingBox() const
00344 {
00345         GLC_BoundingBox boundingBox;
00346 
00347         if (!isOrphan() && (NULL != m_pWorldHandle))
00348         {
00349                 if (m_HasRepresentation)
00350                 {
00351                         Q_ASSERT(m_pWorldHandle->collection()->contains(id()));
00352                         boundingBox= m_pWorldHandle->collection()->instanceHandle(id())->boundingBox();
00353                 }
00354                 else
00355                 {
00356                         if (hasChild())
00357                         {
00358                                 QList<GLC_StructOccurence*> childrenList= children();
00359                                 const int size= childrenList.size();
00360 
00361                                 for (int i= 0; i < size; ++i)
00362                                 {
00363                                         boundingBox.combine(childrenList.at(i)->boundingBox());
00364                                 }
00365                         }
00366                 }
00367         }
00368         return boundingBox;
00369 }
00370 
00371 
00373 // Set Functions
00375 
00376 // Update the absolute matrix
00377 GLC_StructOccurence* GLC_StructOccurence::updateAbsoluteMatrix()
00378 {
00379         if (NULL != m_pParent)
00380         {
00381                 m_AbsoluteMatrix= m_pParent->absoluteMatrix() * m_pStructInstance->relativeMatrix();
00382         }
00383         else
00384         {
00385                 m_AbsoluteMatrix= m_pStructInstance->relativeMatrix();
00386         }
00387         // If the occurence have a representation, update it.
00388         if ((NULL != m_pWorldHandle) && m_HasRepresentation)
00389         {
00390                 m_pWorldHandle->collection()->instanceHandle(id())->setMatrix(m_AbsoluteMatrix);
00391         }
00392         return this;
00393 }
00394 
00395 // Update children obsolute Matrix
00396 GLC_StructOccurence* GLC_StructOccurence::updateChildrenAbsoluteMatrix()
00397 {
00398         updateAbsoluteMatrix();
00399         const int size= m_Childs.size();
00400         for (int i= 0; i < size; ++i)
00401         {
00402                 m_Childs[i]->updateChildrenAbsoluteMatrix();
00403         }
00404         return this;
00405 }
00406 
00407 // Add Child
00408 void GLC_StructOccurence::addChild(GLC_StructOccurence* pChild)
00409 {
00410         Q_ASSERT(pChild->isOrphan());
00411         Q_ASSERT((NULL == pChild->m_pWorldHandle) || (m_pWorldHandle == pChild->m_pWorldHandle));
00412 
00413         //qDebug() << "Add Child " << pChild->name() << "id=" << pChild->id() << " to " << name() << " id=" << id();
00414         // Add the child to the list of child
00415         // Get occurence reference
00416         m_Childs.append(pChild);
00417         pChild->m_pParent= this;
00418         if (NULL == pChild->m_pWorldHandle)
00419         {
00420                 pChild->setWorldHandle(m_pWorldHandle);
00421         }
00422         pChild->updateChildrenAbsoluteMatrix();
00423 }
00424 
00425 // Add Child instance and returns the newly created occurence
00426 GLC_StructOccurence* GLC_StructOccurence::addChild(GLC_StructInstance* pInstance)
00427 {
00428         GLC_StructOccurence* pOccurence;
00429         pOccurence= new GLC_StructOccurence(pInstance, m_pWorldHandle);
00430 
00431         addChild(pOccurence);
00432 
00433         return pOccurence;
00434 }
00435 
00436 // make the occurence orphan
00437 void GLC_StructOccurence::makeOrphan()
00438 {
00439         //qDebug() << "GLC_StructOccurence::makeOrphan() " << id();
00440         //qDebug() << name() << " " << id();
00441         Q_ASSERT(!isOrphan());
00442         m_pParent->removeChild(this);
00443         //qDebug() << "GLC_StructOccurence::makeOrphan() DONE!";
00444 }
00445 
00446 // Remove the specified child
00447 bool GLC_StructOccurence::removeChild(GLC_StructOccurence* pChild)
00448 {
00449         Q_ASSERT(pChild->m_pParent == this);
00450         Q_ASSERT(m_Childs.contains(pChild));
00451         pChild->m_pParent= NULL;
00452         pChild->detach();
00453 
00454         return m_Childs.removeOne(pChild);
00455 }
00456 
00457 // Detach the occurence from the GLC_World
00458 void GLC_StructOccurence::detach()
00459 {
00460         //qDebug() << "GLC_StructOccurence::detach() " << id();
00461         if (NULL != m_pWorldHandle)
00462         {
00463                 // retrieve renderProperties if needed
00464                 if (m_HasRepresentation)
00465                 {
00466                         GLC_3DViewInstance* pInstance= m_pWorldHandle->collection()->instanceHandle(m_Uid);
00467                         if (!pInstance->renderPropertiesHandle()->isDefault())
00468                         {
00469                                 Q_ASSERT(NULL == m_pRenderProperties);
00470                                 m_pRenderProperties= new GLC_RenderProperties(*(pInstance->renderPropertiesHandle()));
00471                         }
00472                 }
00473                 m_pWorldHandle->removeOccurence(this);
00474                 m_pWorldHandle= NULL;
00475                 if (!m_Childs.isEmpty())
00476                 {
00477                         const int size= m_Childs.size();
00478                         for (int i= 0; i < size; ++i)
00479                         {
00480                                 m_Childs[i]->detach();
00481                         }
00482                 }
00483         }
00484 }
00485 
00486 // Reverse Normals of this Occurence and childs
00487 void GLC_StructOccurence::reverseNormals()
00488 {
00489         if (m_HasRepresentation)
00490         {
00491                 m_pWorldHandle->collection()->instanceHandle(id())->reverseGeometriesNormals();
00492         }
00493 }
00494 
00495 // Check the presence of representation
00496 void GLC_StructOccurence::checkForRepresentation()
00497 {
00498         if (NULL != m_pStructInstance)
00499         {
00500                 GLC_StructReference* pRef= m_pStructInstance->structReference();
00501                 if (NULL != pRef)
00502                 {
00503                         if (pRef->hasRepresentation())
00504                         {
00505                                 GLC_3DRep* p3DRep= dynamic_cast<GLC_3DRep*>(pRef->representationHandle());
00506                                 GLC_3DViewInstance instance(*p3DRep);
00507                                 instance.setName(name());
00508                                 // Force instance representation id
00509                                 instance.setId(id());
00510                                 m_pWorldHandle->collection()->add(instance);
00511                         }
00512                         m_HasRepresentation= true;
00513                 }
00514         }
00515 }
00516 
00517 // Set the occurence world Handle
00518 void GLC_StructOccurence::setWorldHandle(GLC_WorldHandle* pWorldHandle)
00519 {
00520         // Check if world handles are equal
00521         if (m_pWorldHandle == pWorldHandle) return;
00522 
00523         if (NULL != m_pWorldHandle)
00524         {
00525                 m_pWorldHandle->removeOccurence(this);
00526         }
00527 
00528         m_pWorldHandle= pWorldHandle;
00529 
00530         if (NULL != m_pWorldHandle)
00531         {
00532                 m_pWorldHandle->addOccurence(this);
00533                 m_pWorldHandle->collection()->setVisibility(m_Uid, m_IsVisible);
00534 
00535                 const int size= m_Childs.size();
00536                 for (int i= 0; i < size; ++i)
00537                 {
00538                         m_Childs[i]->setWorldHandle(m_pWorldHandle);
00539                 }
00540         }
00541 }
00542 
00543 // Load the representation and return true if success
00544 bool GLC_StructOccurence::loadRepresentation()
00545 {
00546         bool loadSucces= false;
00547         if (m_HasRepresentation)
00548         {
00549                 loadSucces=  m_pStructInstance->structReference()->representationHandle()->load();
00550                 if (NULL != m_pWorldHandle)
00551                 {
00552                         m_pWorldHandle->addOccurence(this);
00553                         m_pWorldHandle->collection()->setVisibility(m_Uid, m_IsVisible);
00554                 }
00555 
00556         }
00557         return loadSucces;
00558 }
00559 
00560 // UnLoad the representation and return true if success
00561 bool GLC_StructOccurence::unloadRepresentation()
00562 {
00563         if (m_HasRepresentation)
00564         {
00565                 return m_pStructInstance->structReference()->representationHandle()->unload();
00566         }
00567         else return false;
00568 }
00569 
00570 unsigned int GLC_StructOccurence::updateOccurenceNumber(unsigned int n)
00571 {
00572         m_OccurenceNumber= n++;
00573         const int childCount= m_Childs.size();
00574         for (int i= 0; i < childCount; ++i)
00575         {
00576                 n= m_Childs[i]->updateOccurenceNumber(n);
00577         }
00578         return n;
00579 }
00580 
00581 void GLC_StructOccurence::setVisibility(bool visibility)
00582 {
00583         m_IsVisible= visibility;
00584         if (m_HasRepresentation && (NULL != m_pWorldHandle))
00585         {
00586                 m_pWorldHandle->collection()->setVisibility(m_Uid, m_IsVisible);
00587         }
00588         const int childCount= m_Childs.size();
00589         for (int i= 0; i < childCount; ++i)
00590         {
00591                 m_Childs[i]->setVisibility(m_IsVisible);
00592         }
00593 }
00594 
00595 void GLC_StructOccurence::setRenderProperties(const GLC_RenderProperties& renderProperties)
00596 {
00597         delete m_pRenderProperties;
00598         if (m_HasRepresentation && (NULL != m_pWorldHandle))
00599         {
00600                 m_pWorldHandle->collection()->instanceHandle(m_Uid)->setRenderProperties(renderProperties);
00601         }
00602         else if (hasChild())
00603         {
00604                 const int childCount= m_Childs.size();
00605                 for (int i= 0; i < childCount; ++i)
00606                 {
00607                         m_Childs[i]->setRenderProperties(renderProperties);
00608                 }
00609         }
00610         else
00611         {
00612                 m_pRenderProperties= new GLC_RenderProperties(renderProperties);
00613         }
00614 }
00615 
00616 void GLC_StructOccurence::removeEmptyChildren()
00617 {
00618         QList<GLC_StructOccurence*>::iterator iChild= m_Childs.begin();
00619         while (m_Childs.constEnd() != iChild)
00620         {
00621                 if (!((*iChild)->hasChild()) && !((*iChild)->hasRepresentation()))
00622                 {
00623                         delete *iChild;
00624                         iChild= m_Childs.erase(iChild);
00625                 }
00626                 else
00627                 {
00628                         (*iChild)->removeEmptyChildren();
00629                         ++iChild;
00630                 }
00631         }
00632 }

SourceForge.net Logo

©2005 Laurent Ribon