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, packaged on July 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 Lesser General Public License as published by
00011  the Free Software Foundation; either version 3 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 Lesser General Public License for more details.
00018 
00019  You should have received a copy of the GNU Lesser 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(NULL)
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                 m_pNumberOfOccurence= structOccurence.m_pNumberOfOccurence;
00138                 ++(*m_pNumberOfOccurence);
00139         }
00140         else
00141         {
00142                 m_pNumberOfOccurence= new int(1);
00143                 m_pStructInstance= new GLC_StructInstance(structOccurence.m_pStructInstance);
00144         }
00145 
00146 
00147         // Test if structOccurence has representation and has a shader
00148         GLuint shaderId= 0;
00149         bool instanceIsSelected= false;
00150         if ((m_HasRepresentation) && (NULL != m_pWorldHandle) && (NULL != structOccurence.m_pWorldHandle))
00151         {
00152                 GLC_3DViewInstance* p3DViewInstance= structOccurence.m_pWorldHandle->collection()->instanceHandle(structOccurence.id());
00153 
00154                 if(structOccurence.m_pWorldHandle->collection()->isInAShadingGroup(structOccurence.id()))
00155                 {
00156                         shaderId= structOccurence.m_pWorldHandle->collection()->shadingGroup(structOccurence.id());
00157                 }
00158 
00159                 instanceIsSelected= p3DViewInstance->isSelected();
00160                 // Test the rendering properties
00161                 if (! p3DViewInstance->renderPropertiesHandle()->isDefault())
00162                 {
00163                         m_pRenderProperties= new GLC_RenderProperties(*(p3DViewInstance->renderPropertiesHandle()));
00164                 }
00165         }
00166         else if (NULL != structOccurence.m_pRenderProperties)
00167         {
00168                 m_pRenderProperties= new GLC_RenderProperties(*(structOccurence.m_pRenderProperties));
00169         }
00170 
00171         // Inform the world Handle
00172         if (NULL != m_pWorldHandle)
00173         {
00174                 m_pWorldHandle->addOccurence(this, instanceIsSelected, shaderId);
00175                 if (NULL != m_pRenderProperties)
00176                 {
00177                         m_pWorldHandle->collection()->instanceHandle(id())->setRenderProperties(*m_pRenderProperties);
00178                         delete m_pRenderProperties;
00179                         m_pRenderProperties= NULL;
00180                 }
00181         }
00182 
00183         // Update Absolute matrix
00184         updateAbsoluteMatrix();
00185 
00186 
00187         // Create childs
00188         const int size= structOccurence.childCount();
00189         for (int i= 0; i < size; ++i)
00190         {
00191                 GLC_StructOccurence* pChild= structOccurence.child(i)->clone(m_pWorldHandle, true);
00192                 addChild(pChild);
00193         }
00194         updateChildrenAbsoluteMatrix();
00195         // Update instance
00196         m_pStructInstance->structOccurenceCreated(this);
00197 }
00198 
00199 // Destructor
00200 GLC_StructOccurence::~GLC_StructOccurence()
00201 {
00202         //qDebug() << "Delete " << id();
00203         Q_ASSERT(m_pNumberOfOccurence != NULL);
00204         // Remove from the GLC_WorldHandle
00205         if (NULL != m_pWorldHandle)
00206         {
00207                 m_pWorldHandle->removeOccurence(this);
00208         }
00209 
00210         // Remove Childs
00211         const int size= m_Childs.size();
00212         for (int i= 0; i < size; ++i)
00213         {
00214                 GLC_StructOccurence* pChild= m_Childs.first();
00215                 removeChild(pChild);
00216                 delete pChild;
00217         }
00218         // Update number of occurence and instance
00219         if ((--(*m_pNumberOfOccurence)) == 0)
00220         {
00221                 delete m_pStructInstance;
00222                 delete m_pNumberOfOccurence;
00223         }
00224         else
00225         {
00226                 m_pStructInstance->structOccurenceDeleted(this);
00227         }
00228 
00229         delete m_pRenderProperties;
00230 }
00231 
00233 // Get Functions
00235 
00236 // Get number of faces
00237 unsigned int GLC_StructOccurence::numberOfFaces() const
00238 {
00239         unsigned int result= 0;
00240         if (m_HasRepresentation)
00241         {
00242                 result= structInstance()->structReference()->numberOfFaces();
00243         }
00244         else
00245         {
00246                 const int size= m_Childs.size();
00247                 for (int i= 0; i < size; ++i)
00248                 {
00249                         result+= m_Childs.at(i)->numberOfFaces();
00250                 }
00251         }
00252         return result;
00253 }
00254 
00255 // Get number of vertex
00256 unsigned int GLC_StructOccurence::numberOfVertex() const
00257 {
00258         unsigned int result= 0;
00259         if (m_HasRepresentation)
00260         {
00261                 result= structInstance()->structReference()->numberOfVertex();
00262         }
00263         else
00264         {
00265                 const int size= m_Childs.size();
00266                 for (int i= 0; i < size; ++i)
00267                 {
00268                         result+= m_Childs.at(i)->numberOfVertex();
00269                 }
00270         }
00271         return result;
00272 }
00273 
00274 // Get number of materials
00275 unsigned int GLC_StructOccurence::numberOfMaterials() const
00276 {
00277         unsigned int result= 0;
00278         QSet<GLC_Material*> materialSet;
00279         if (m_HasRepresentation)
00280         {
00281                 result= structInstance()->structReference()->numberOfMaterials();
00282         }
00283         else
00284         {
00285                 const int size= m_Childs.size();
00286                 for (int i= 0; i < size; ++i)
00287                 {
00288                         materialSet.unite(m_Childs.at(i)->materialSet());
00289                 }
00290                 result= static_cast<unsigned int>(materialSet.size());
00291         }
00292         return result;
00293 }
00294 
00295 // Get materials List
00296 QSet<GLC_Material*> GLC_StructOccurence::materialSet() const
00297 {
00298         QSet<GLC_Material*> materialSet;
00299         if (m_HasRepresentation)
00300         {
00301                 materialSet= structInstance()->structReference()->materialSet();
00302         }
00303         else
00304         {
00305                 const int size= m_Childs.size();
00306                 for (int i= 0; i < size; ++i)
00307                 {
00308                         materialSet.unite(m_Childs.at(i)->materialSet());
00309                 }
00310         }
00311         return materialSet;
00312 }
00313 
00314 // Clone the occurence
00315 GLC_StructOccurence* GLC_StructOccurence::clone(GLC_WorldHandle* pWorldHandle, bool shareInstance) const
00316 {
00317         return new GLC_StructOccurence(pWorldHandle, *this, shareInstance);
00318 }
00319 
00320 // Return true if the occurence is visible
00321 bool GLC_StructOccurence::isVisible() const
00322 {
00323         bool isHidden= true;
00324         if (m_HasRepresentation)
00325         {
00326                 isHidden= !m_pWorldHandle->collection()->instanceHandle(id())->isVisible();
00327         }
00328         else if (childCount() > 0)
00329         {
00330                 const int size= childCount();
00331                 int i= 0;
00332                 while ((i < size) && isHidden)
00333                 {
00334                         isHidden= isHidden && !child(i)->isVisible();
00335                         ++i;
00336                 }
00337         }
00338         else
00339         {
00340                 isHidden= !m_IsVisible;
00341         }
00342         return !isHidden;
00343 }
00344 
00345 // Return the occurence Bounding Box
00346 GLC_BoundingBox GLC_StructOccurence::boundingBox() const
00347 {
00348         GLC_BoundingBox boundingBox;
00349 
00350         if (!isOrphan() && (NULL != m_pWorldHandle))
00351         {
00352                 if (m_HasRepresentation)
00353                 {
00354                         Q_ASSERT(m_pWorldHandle->collection()->contains(id()));
00355                         boundingBox= m_pWorldHandle->collection()->instanceHandle(id())->boundingBox();
00356                 }
00357                 else
00358                 {
00359                         if (hasChild())
00360                         {
00361                                 QList<GLC_StructOccurence*> childrenList= children();
00362                                 const int size= childrenList.size();
00363 
00364                                 for (int i= 0; i < size; ++i)
00365                                 {
00366                                         boundingBox.combine(childrenList.at(i)->boundingBox());
00367                                 }
00368                         }
00369                 }
00370         }
00371         return boundingBox;
00372 }
00373 
00374 unsigned int GLC_StructOccurence::nodeCount() const
00375 {
00376         unsigned int result= 1;
00377         const int size= m_Childs.size();
00378         for (int i= 0; i < size; ++i)
00379         {
00380                 result+= m_Childs.at(i)->nodeCount();
00381         }
00382         return result;
00383 }
00384 
00386 // Set Functions
00388 
00389 // Update the absolute matrix
00390 GLC_StructOccurence* GLC_StructOccurence::updateAbsoluteMatrix()
00391 {
00392         if (NULL != m_pParent)
00393         {
00394                 m_AbsoluteMatrix= m_pParent->absoluteMatrix() * m_pStructInstance->relativeMatrix();
00395         }
00396         else
00397         {
00398                 m_AbsoluteMatrix= m_pStructInstance->relativeMatrix();
00399         }
00400         // If the occurence have a representation, update it.
00401         if ((NULL != m_pWorldHandle) && m_HasRepresentation)
00402         {
00403                 m_pWorldHandle->collection()->instanceHandle(id())->setMatrix(m_AbsoluteMatrix);
00404         }
00405         return this;
00406 }
00407 
00408 // Update children obsolute Matrix
00409 GLC_StructOccurence* GLC_StructOccurence::updateChildrenAbsoluteMatrix()
00410 {
00411         updateAbsoluteMatrix();
00412         const int size= m_Childs.size();
00413         for (int i= 0; i < size; ++i)
00414         {
00415                 m_Childs[i]->updateChildrenAbsoluteMatrix();
00416         }
00417         return this;
00418 }
00419 
00420 // Add Child
00421 void GLC_StructOccurence::addChild(GLC_StructOccurence* pChild)
00422 {
00423         Q_ASSERT(pChild->isOrphan());
00424         Q_ASSERT((NULL == pChild->m_pWorldHandle) || (m_pWorldHandle == pChild->m_pWorldHandle));
00425 
00426         //qDebug() << "Add Child " << pChild->name() << "id=" << pChild->id() << " to " << name() << " id=" << id();
00427         // Add the child to the list of child
00428         // Get occurence reference
00429         m_Childs.append(pChild);
00430         pChild->m_pParent= this;
00431         if (NULL == pChild->m_pWorldHandle)
00432         {
00433                 pChild->setWorldHandle(m_pWorldHandle);
00434         }
00435         pChild->updateChildrenAbsoluteMatrix();
00436 }
00437 
00438 // Add Child instance and returns the newly created occurence
00439 GLC_StructOccurence* GLC_StructOccurence::addChild(GLC_StructInstance* pInstance)
00440 {
00441         GLC_StructOccurence* pOccurence;
00442         pOccurence= new GLC_StructOccurence(pInstance, m_pWorldHandle);
00443 
00444         addChild(pOccurence);
00445 
00446         return pOccurence;
00447 }
00448 
00449 // make the occurence orphan
00450 void GLC_StructOccurence::makeOrphan()
00451 {
00452         //qDebug() << "GLC_StructOccurence::makeOrphan() " << id();
00453         //qDebug() << name() << " " << id();
00454         Q_ASSERT(!isOrphan());
00455         m_pParent->removeChild(this);
00456         //qDebug() << "GLC_StructOccurence::makeOrphan() DONE!";
00457 }
00458 
00459 // Remove the specified child
00460 bool GLC_StructOccurence::removeChild(GLC_StructOccurence* pChild)
00461 {
00462         Q_ASSERT(pChild->m_pParent == this);
00463         Q_ASSERT(m_Childs.contains(pChild));
00464         pChild->m_pParent= NULL;
00465         pChild->detach();
00466 
00467         return m_Childs.removeOne(pChild);
00468 }
00469 
00470 // Detach the occurence from the GLC_World
00471 void GLC_StructOccurence::detach()
00472 {
00473         //qDebug() << "GLC_StructOccurence::detach() " << id();
00474         if (NULL != m_pWorldHandle)
00475         {
00476                 // retrieve renderProperties if needed
00477                 if (m_HasRepresentation)
00478                 {
00479                         GLC_3DViewInstance* pInstance= m_pWorldHandle->collection()->instanceHandle(m_Uid);
00480                         if (!pInstance->renderPropertiesHandle()->isDefault())
00481                         {
00482                                 Q_ASSERT(NULL == m_pRenderProperties);
00483                                 m_pRenderProperties= new GLC_RenderProperties(*(pInstance->renderPropertiesHandle()));
00484                         }
00485                 }
00486                 m_pWorldHandle->removeOccurence(this);
00487                 m_pWorldHandle= NULL;
00488                 if (!m_Childs.isEmpty())
00489                 {
00490                         const int size= m_Childs.size();
00491                         for (int i= 0; i < size; ++i)
00492                         {
00493                                 m_Childs[i]->detach();
00494                         }
00495                 }
00496         }
00497 }
00498 
00499 // Reverse Normals of this Occurence and childs
00500 void GLC_StructOccurence::reverseNormals()
00501 {
00502         if (m_HasRepresentation)
00503         {
00504                 m_pWorldHandle->collection()->instanceHandle(id())->reverseGeometriesNormals();
00505         }
00506 }
00507 
00508 // Check the presence of representation
00509 void GLC_StructOccurence::checkForRepresentation()
00510 {
00511         if (NULL != m_pStructInstance)
00512         {
00513                 GLC_StructReference* pRef= m_pStructInstance->structReference();
00514                 if (NULL != pRef)
00515                 {
00516                         if (pRef->hasRepresentation())
00517                         {
00518                                 GLC_3DRep* p3DRep= dynamic_cast<GLC_3DRep*>(pRef->representationHandle());
00519                                 GLC_3DViewInstance instance(*p3DRep);
00520                                 instance.setName(name());
00521                                 // Force instance representation id
00522                                 instance.setId(id());
00523                                 m_pWorldHandle->collection()->add(instance);
00524                         }
00525                         m_HasRepresentation= true;
00526                 }
00527         }
00528 }
00529 
00530 // Set the occurence world Handle
00531 void GLC_StructOccurence::setWorldHandle(GLC_WorldHandle* pWorldHandle)
00532 {
00533         // Check if world handles are equal
00534         if (m_pWorldHandle == pWorldHandle) return;
00535 
00536         if (NULL != m_pWorldHandle)
00537         {
00538                 m_pWorldHandle->removeOccurence(this);
00539         }
00540 
00541         m_pWorldHandle= pWorldHandle;
00542 
00543         if (NULL != m_pWorldHandle)
00544         {
00545                 m_pWorldHandle->addOccurence(this);
00546                 m_pWorldHandle->collection()->setVisibility(m_Uid, m_IsVisible);
00547 
00548                 const int size= m_Childs.size();
00549                 for (int i= 0; i < size; ++i)
00550                 {
00551                         m_Childs[i]->setWorldHandle(m_pWorldHandle);
00552                 }
00553         }
00554 }
00555 
00556 // Load the representation and return true if success
00557 bool GLC_StructOccurence::loadRepresentation()
00558 {
00559         bool loadSucces= false;
00560         if (m_HasRepresentation)
00561         {
00562                 loadSucces=  m_pStructInstance->structReference()->representationHandle()->load();
00563                 if (NULL != m_pWorldHandle)
00564                 {
00565                         m_pWorldHandle->addOccurence(this);
00566                         m_pWorldHandle->collection()->setVisibility(m_Uid, m_IsVisible);
00567                 }
00568 
00569         }
00570         return loadSucces;
00571 }
00572 
00573 // UnLoad the representation and return true if success
00574 bool GLC_StructOccurence::unloadRepresentation()
00575 {
00576         if (m_HasRepresentation)
00577         {
00578                 return m_pStructInstance->structReference()->representationHandle()->unload();
00579         }
00580         else return false;
00581 }
00582 
00583 unsigned int GLC_StructOccurence::updateOccurenceNumber(unsigned int n)
00584 {
00585         m_OccurenceNumber= n++;
00586         const int childCount= m_Childs.size();
00587         for (int i= 0; i < childCount; ++i)
00588         {
00589                 n= m_Childs[i]->updateOccurenceNumber(n);
00590         }
00591         return n;
00592 }
00593 
00594 void GLC_StructOccurence::setVisibility(bool visibility)
00595 {
00596         m_IsVisible= visibility;
00597         if (m_HasRepresentation && (NULL != m_pWorldHandle))
00598         {
00599                 m_pWorldHandle->collection()->setVisibility(m_Uid, m_IsVisible);
00600         }
00601         const int childCount= m_Childs.size();
00602         for (int i= 0; i < childCount; ++i)
00603         {
00604                 m_Childs[i]->setVisibility(m_IsVisible);
00605         }
00606 }
00607 
00608 void GLC_StructOccurence::setRenderProperties(const GLC_RenderProperties& renderProperties)
00609 {
00610         delete m_pRenderProperties;
00611         if (m_HasRepresentation && (NULL != m_pWorldHandle))
00612         {
00613                 m_pWorldHandle->collection()->instanceHandle(m_Uid)->setRenderProperties(renderProperties);
00614         }
00615         else if (hasChild())
00616         {
00617                 const int childCount= m_Childs.size();
00618                 for (int i= 0; i < childCount; ++i)
00619                 {
00620                         m_Childs[i]->setRenderProperties(renderProperties);
00621                 }
00622         }
00623         else
00624         {
00625                 m_pRenderProperties= new GLC_RenderProperties(renderProperties);
00626         }
00627 }
00628 
00629 void GLC_StructOccurence::removeEmptyChildren()
00630 {
00631         QList<GLC_StructOccurence*>::iterator iChild= m_Childs.begin();
00632         while (m_Childs.constEnd() != iChild)
00633         {
00634                 if (!((*iChild)->hasChild()) && !((*iChild)->hasRepresentation()))
00635                 {
00636                         delete *iChild;
00637                         iChild= m_Childs.erase(iChild);
00638                 }
00639                 else
00640                 {
00641                         (*iChild)->removeEmptyChildren();
00642                         ++iChild;
00643                 }
00644         }
00645 }

SourceForge.net Logo

©2005-2010 Laurent Ribon