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  http://glc-lib.sourceforge.net
00006 
00007  GLC-lib is free software; you can redistribute it and/or modify
00008  it under the terms of the GNU Lesser General Public License as published by
00009  the Free Software Foundation; either version 3 of the License, or
00010  (at your option) any later version.
00011 
00012  GLC-lib is distributed in the hope that it will be useful,
00013  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  GNU Lesser General Public License for more details.
00016 
00017  You should have received a copy of the GNU Lesser General Public License
00018  along with GLC-lib; if not, write to the Free Software
00019  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00020 
00021 *****************************************************************************/
00022 
00024 
00025 #include "glc_structoccurence.h"
00026 #include "glc_3dviewcollection.h"
00027 #include "glc_structreference.h"
00028 #include "glc_worldhandle.h"
00029 #include "../glc_errorlog.h"
00030 
00031 // Default constructor
00032 GLC_StructOccurence::GLC_StructOccurence()
00033 : m_Uid(glc::GLC_GenID())
00034 , m_pWorldHandle(NULL)
00035 , m_pNumberOfOccurence(new int(1))
00036 , m_pStructInstance(new GLC_StructInstance())
00037 , m_pParent(NULL)
00038 , m_Childs()
00039 , m_AbsoluteMatrix()
00040 , m_OccurenceNumber(0)
00041 , m_IsVisible(true)
00042 , m_pRenderProperties(NULL)
00043 , m_AutomaticCreationOf3DViewInstance(true)
00044 , m_pRelativeMatrix(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_OccurenceNumber(0)
00061 , m_IsVisible(true)
00062 , m_pRenderProperties(NULL)
00063 , m_AutomaticCreationOf3DViewInstance(true)
00064 , m_pRelativeMatrix(NULL)
00065 {
00066         // Update the number of occurences
00067         if (pStructInstance->hasStructOccurence())
00068         {
00069                 GLC_StructOccurence* pFirstOccurence= pStructInstance->firstOccurenceHandle();
00070                 m_pNumberOfOccurence= pFirstOccurence->m_pNumberOfOccurence;
00071                 ++(*m_pNumberOfOccurence);
00072                 QList<GLC_StructOccurence*> childs= pFirstOccurence->m_Childs;
00073                 const int size= childs.size();
00074                 for (int i= 0; i < size; ++i)
00075                 {
00076                         GLC_StructOccurence* pChild= childs.at(i)->clone(m_pWorldHandle, true);
00077                         addChild(pChild);
00078                 }
00079         }
00080         else
00081         {
00082                 m_pNumberOfOccurence= new int(1);
00083         }
00084 
00085         setName(m_pStructInstance->name());
00086 
00087         // Inform the world Handle
00088         if (NULL != m_pWorldHandle)
00089         {
00090                 m_pWorldHandle->addOccurence(this, shaderId);
00091         }
00092 
00093         // Update Absolute matrix
00094         updateAbsoluteMatrix();
00095 
00096         // Update instance
00097         m_pStructInstance->structOccurenceCreated(this);
00098 }
00099 // Construct Occurence with the specified GLC_3DRep
00100 GLC_StructOccurence::GLC_StructOccurence(GLC_3DRep* pRep)
00101 : m_Uid(glc::GLC_GenID())
00102 , m_pWorldHandle(NULL)
00103 , m_pNumberOfOccurence(new int(1))
00104 , m_pStructInstance(NULL)
00105 , m_pParent(NULL)
00106 , m_Childs()
00107 , m_AbsoluteMatrix()
00108 , m_OccurenceNumber(0)
00109 , m_IsVisible(true)
00110 , m_pRenderProperties(NULL)
00111 , m_AutomaticCreationOf3DViewInstance(true)
00112 , m_pRelativeMatrix(NULL)
00113 {
00114         m_pStructInstance= new GLC_StructInstance(pRep);
00115         setName(m_pStructInstance->name());
00116 
00117         // Update instance
00118         m_pStructInstance->structOccurenceCreated(this);
00119 }
00120 
00121 // Copy constructor
00122 GLC_StructOccurence::GLC_StructOccurence(GLC_WorldHandle* pWorldHandle, const GLC_StructOccurence& structOccurence, bool shareInstance)
00123 : m_Uid(glc::GLC_GenID())
00124 , m_pWorldHandle(pWorldHandle)
00125 , m_pNumberOfOccurence(NULL)
00126 , m_pStructInstance(NULL)
00127 , m_pParent(NULL)
00128 , m_Childs()
00129 , m_AbsoluteMatrix(structOccurence.m_AbsoluteMatrix)
00130 , m_OccurenceNumber(0)
00131 , m_IsVisible(structOccurence.m_IsVisible)
00132 , m_pRenderProperties(NULL)
00133 , m_AutomaticCreationOf3DViewInstance(structOccurence.m_AutomaticCreationOf3DViewInstance)
00134 , m_pRelativeMatrix(NULL)
00135 {
00136         if (shareInstance)
00137         {
00138                 m_pStructInstance= structOccurence.m_pStructInstance;
00139                 m_pNumberOfOccurence= structOccurence.m_pNumberOfOccurence;
00140                 ++(*m_pNumberOfOccurence);
00141         }
00142         else
00143         {
00144                 m_pNumberOfOccurence= new int(1);
00145                 m_pStructInstance= new GLC_StructInstance(structOccurence.m_pStructInstance);
00146         }
00147 
00148 
00149         // Test if structOccurence has representation and has a shader
00150         GLuint shaderId= 0;
00151         bool instanceIsSelected= false;
00152         if ((NULL != m_pWorldHandle) && (NULL != structOccurence.m_pWorldHandle) && structOccurence.m_pWorldHandle->collection()->contains(structOccurence.id()))
00153         {
00154                 GLC_3DViewInstance* p3DViewInstance= structOccurence.m_pWorldHandle->collection()->instanceHandle(structOccurence.id());
00155 
00156                 if(structOccurence.m_pWorldHandle->collection()->isInAShadingGroup(structOccurence.id()))
00157                 {
00158                         shaderId= structOccurence.m_pWorldHandle->collection()->shadingGroup(structOccurence.id());
00159                 }
00160 
00161                 instanceIsSelected= p3DViewInstance->isSelected();
00162                 // Test the rendering properties
00163                 if (! p3DViewInstance->renderPropertiesHandle()->isDefault())
00164                 {
00165                         m_pRenderProperties= new GLC_RenderProperties(*(p3DViewInstance->renderPropertiesHandle()));
00166                 }
00167         }
00168         else if (NULL != structOccurence.m_pRenderProperties)
00169         {
00170                 m_pRenderProperties= new GLC_RenderProperties(*(structOccurence.m_pRenderProperties));
00171         }
00172 
00173         // Inform the world Handle
00174         if (NULL != m_pWorldHandle)
00175         {
00176                 m_pWorldHandle->addOccurence(this, instanceIsSelected, shaderId);
00177                 if (NULL != m_pRenderProperties && this->has3DViewInstance())
00178                 {
00179                         m_pWorldHandle->collection()->instanceHandle(id())->setRenderProperties(*m_pRenderProperties);
00180                         delete m_pRenderProperties;
00181                         m_pRenderProperties= NULL;
00182                 }
00183         }
00184 
00185         // Check flexibility
00186         if (NULL != structOccurence.m_pRelativeMatrix)
00187         {
00188                 m_pRelativeMatrix= new GLC_Matrix4x4(*(structOccurence.m_pRelativeMatrix));
00189         }
00190 
00191         // Update Absolute matrix
00192         updateAbsoluteMatrix();
00193 
00194 
00195         // Create childs
00196         const int size= structOccurence.childCount();
00197         for (int i= 0; i < size; ++i)
00198         {
00199                 GLC_StructOccurence* pChild= structOccurence.child(i)->clone(m_pWorldHandle, true);
00200                 addChild(pChild);
00201         }
00202         updateChildrenAbsoluteMatrix();
00203         // Update instance
00204         m_pStructInstance->structOccurenceCreated(this);
00205 }
00206 
00207 // Destructor
00208 GLC_StructOccurence::~GLC_StructOccurence()
00209 {
00210         //qDebug() << "Delete " << id();
00211         Q_ASSERT(m_pNumberOfOccurence != NULL);
00212         // Remove from the GLC_WorldHandle
00213         if (NULL != m_pWorldHandle)
00214         {
00215                 m_pWorldHandle->removeOccurence(this);
00216         }
00217 
00218         // Remove Childs
00219         const int size= m_Childs.size();
00220         for (int i= 0; i < size; ++i)
00221         {
00222                 GLC_StructOccurence* pChild= m_Childs.first();
00223                 removeChild(pChild);
00224                 delete pChild;
00225         }
00226         // Update number of occurence and instance
00227         if ((--(*m_pNumberOfOccurence)) == 0)
00228         {
00229                 delete m_pStructInstance;
00230                 delete m_pNumberOfOccurence;
00231         }
00232         else
00233         {
00234                 m_pStructInstance->structOccurenceDeleted(this);
00235                 if (!m_pStructInstance->hasStructOccurence())
00236                 {
00237 
00238                         QStringList errorList;
00239                         errorList << "StructOccurence count error";
00240                         errorList << ("ref name = " + m_pStructInstance->structReference()->name());
00241                         GLC_ErrorLog::addError(errorList);
00242 
00243                         delete m_pStructInstance;
00244                         //delete m_pNumberOfOccurence;
00245                 }
00246         }
00247 
00248         delete m_pRenderProperties;
00249         delete m_pRelativeMatrix;
00250 }
00251 
00253 // Get Functions
00255 
00256 GLC_Matrix4x4 GLC_StructOccurence::occurrenceRelativeMatrix() const
00257 {
00258         GLC_Matrix4x4 matrix;
00259         if (NULL != m_pRelativeMatrix)
00260         {
00261                 matrix= *m_pRelativeMatrix;
00262         }
00263         return matrix;
00264 }
00265 
00266 bool GLC_StructOccurence::hasRepresentation() const
00267 {
00268         if ((NULL != m_pStructInstance) && (m_pStructInstance->hasStructOccurence()))
00269         {
00270                 return this->structReference()->hasRepresentation();
00271         }
00272         else return false;
00273 }
00274 
00275 bool GLC_StructOccurence::has3DViewInstance() const
00276 {
00277         if ( NULL != m_pWorldHandle)
00278         {
00279                 return m_pWorldHandle->collection()->contains(m_Uid);
00280         }
00281         else return false;
00282 }
00283 
00284 bool GLC_StructOccurence::canBeAddedToChildren(GLC_StructOccurence* pOccurence) const
00285 {
00286         bool canBeAdded= false;
00287         if ((NULL != m_pStructInstance) && (m_pStructInstance->hasStructOccurence()) && (NULL != pOccurence->m_pStructInstance) && (NULL != pOccurence->structReference()))
00288         {
00289                 if (this->structReference() != pOccurence->structReference())
00290                 {
00291                         QSet<GLC_StructReference*> thisRefSet= GLC_StructOccurence::parentsReferences(this);
00292                         thisRefSet << this->structReference();
00293                         QSet<GLC_StructReference*> childRefSet= pOccurence->childrenReferences();
00294 
00295                         canBeAdded= thisRefSet == (thisRefSet - childRefSet);
00296                 }
00297         }
00298         else
00299         {
00300                 canBeAdded= true;
00301         }
00302         return canBeAdded;
00303 }
00304 
00305 QList<GLC_StructOccurence*> GLC_StructOccurence::subOccurenceList() const
00306 {
00307         QList<GLC_StructOccurence*> subOccurence;
00308         const int childCount= m_Childs.size();
00309         for (int i= 0; i < childCount; ++i)
00310         {
00311                 GLC_StructOccurence* pCurrentChild= m_Childs.at(i);
00312                 subOccurence.append(pCurrentChild);
00313                 if (pCurrentChild->hasChild())
00314                 {
00315                         subOccurence.append(pCurrentChild->subOccurenceList());
00316                 }
00317         }
00318 
00319         return subOccurence;
00320 }
00321 
00322 unsigned int GLC_StructOccurence::numberOfFaces() const
00323 {
00324         unsigned int result= 0;
00325         if (hasRepresentation())
00326         {
00327                 result= structInstance()->structReference()->numberOfFaces();
00328         }
00329 
00330         const int size= m_Childs.size();
00331         for (int i= 0; i < size; ++i)
00332         {
00333                 result+= m_Childs.at(i)->numberOfFaces();
00334         }
00335 
00336         return result;
00337 }
00338 
00339 unsigned int GLC_StructOccurence::numberOfVertex() const
00340 {
00341         unsigned int result= 0;
00342         if (hasRepresentation())
00343         {
00344                 result= structInstance()->structReference()->numberOfVertex();
00345         }
00346         const int size= m_Childs.size();
00347         for (int i= 0; i < size; ++i)
00348         {
00349                 result+= m_Childs.at(i)->numberOfVertex();
00350         }
00351 
00352         return result;
00353 }
00354 
00355 // Get number of materials
00356 unsigned int GLC_StructOccurence::numberOfMaterials() const
00357 {
00358         unsigned int result= 0;
00359         QSet<GLC_Material*> materialSet;
00360         if (hasRepresentation())
00361         {
00362                 result= structInstance()->structReference()->numberOfMaterials();
00363         }
00364 
00365         const int size= m_Childs.size();
00366         for (int i= 0; i < size; ++i)
00367         {
00368                 materialSet.unite(m_Childs.at(i)->materialSet());
00369         }
00370         result= static_cast<unsigned int>(materialSet.size());
00371 
00372         return result;
00373 }
00374 
00375 // Get materials List
00376 QSet<GLC_Material*> GLC_StructOccurence::materialSet() const
00377 {
00378         QSet<GLC_Material*> materialSet;
00379         if (hasRepresentation())
00380         {
00381                 materialSet= structInstance()->structReference()->materialSet();
00382         }
00383 
00384         const int size= m_Childs.size();
00385         for (int i= 0; i < size; ++i)
00386         {
00387                 materialSet.unite(m_Childs.at(i)->materialSet());
00388         }
00389 
00390         return materialSet;
00391 }
00392 
00393 // Clone the occurence
00394 GLC_StructOccurence* GLC_StructOccurence::clone(GLC_WorldHandle* pWorldHandle, bool shareInstance) const
00395 {
00396         return new GLC_StructOccurence(pWorldHandle, *this, shareInstance);
00397 }
00398 
00399 // Return true if the occurence is visible
00400 bool GLC_StructOccurence::isVisible() const
00401 {
00402         bool isHidden= true;
00403 
00404         if ((NULL != m_pWorldHandle) && m_pWorldHandle->collection()->contains(m_Uid))
00405         {
00406                 isHidden= !m_pWorldHandle->collection()->instanceHandle(m_Uid)->isVisible();
00407         }
00408         else if (childCount() > 0)
00409         {
00410                 const int size= childCount();
00411                 int i= 0;
00412                 while ((i < size) && isHidden)
00413                 {
00414                         isHidden= isHidden && !child(i)->isVisible();
00415                         ++i;
00416                 }
00417         }
00418         else
00419         {
00420                 isHidden= !m_IsVisible;
00421         }
00422         return !isHidden;
00423 }
00424 
00425 // Return the occurence Bounding Box
00426 GLC_BoundingBox GLC_StructOccurence::boundingBox() const
00427 {
00428         GLC_BoundingBox boundingBox;
00429 
00430         if (NULL != m_pWorldHandle)
00431         {
00432                 if (has3DViewInstance())
00433                 {
00434                         Q_ASSERT(m_pWorldHandle->collection()->contains(id()));
00435                         boundingBox= m_pWorldHandle->collection()->instanceHandle(id())->boundingBox();
00436                 }
00437                 else
00438                 {
00439                         if (hasChild())
00440                         {
00441                                 QList<GLC_StructOccurence*> childrenList= children();
00442                                 const int size= childrenList.size();
00443 
00444                                 for (int i= 0; i < size; ++i)
00445                                 {
00446                                         boundingBox.combine(childrenList.at(i)->boundingBox());
00447                                 }
00448                         }
00449                 }
00450         }
00451 
00452         return boundingBox;
00453 }
00454 
00455 unsigned int GLC_StructOccurence::nodeCount() const
00456 {
00457         unsigned int result= 1;
00458         const int size= m_Childs.size();
00459         for (int i= 0; i < size; ++i)
00460         {
00461                 result+= m_Childs.at(i)->nodeCount();
00462         }
00463         return result;
00464 }
00465 
00466 QSet<GLC_StructReference*> GLC_StructOccurence::childrenReferences() const
00467 {
00468         QSet<GLC_StructReference*> refChildrenSet;
00469         const int childCount= m_Childs.size();
00470         for (int i= 0; i < childCount; ++i)
00471         {
00472                 GLC_StructOccurence* pCurrentChild= m_Childs.at(i);
00473                 if ((NULL != pCurrentChild->structInstance()) && (NULL != pCurrentChild->structReference()))
00474                 {
00475                         refChildrenSet << pCurrentChild->structReference();
00476                 }
00477         }
00478 
00479         return refChildrenSet;
00480 }
00481 
00482 QSet<GLC_StructReference*> GLC_StructOccurence::parentsReferences(const GLC_StructOccurence* pOccurence)
00483 {
00484         QSet<GLC_StructReference*> parentSet;
00485         GLC_StructOccurence* pParent= pOccurence->parent();
00486         if (NULL != pParent)
00487         {
00488                 if ((NULL != pParent->structInstance()) && (NULL != pParent->structReference()))
00489                 {
00490                         parentSet << pParent->structReference();
00491                         parentSet.unite(GLC_StructOccurence::parentsReferences(pParent));
00492                 }
00493         }
00494 
00495         return parentSet;
00496 }
00497 
00499 // Set Functions
00501 
00502 // Update the absolute matrix
00503 GLC_StructOccurence* GLC_StructOccurence::updateAbsoluteMatrix()
00504 {
00505         GLC_Matrix4x4 relativeMatrix;
00506         if (NULL == m_pRelativeMatrix)
00507         {
00508                 relativeMatrix= m_pStructInstance->relativeMatrix();
00509         }
00510         else
00511         {
00512                 relativeMatrix= *m_pRelativeMatrix;
00513         }
00514 
00515         if (NULL != m_pParent)
00516         {
00517                 m_AbsoluteMatrix= m_pParent->absoluteMatrix() * relativeMatrix;
00518         }
00519         else
00520         {
00521                 m_AbsoluteMatrix= relativeMatrix;
00522         }
00523         // If the occurence have a representation, update it.
00524 
00525         if ((NULL != m_pWorldHandle) && m_pWorldHandle->collection()->contains(m_Uid))
00526         {
00527                 m_pWorldHandle->collection()->instanceHandle(m_Uid)->setMatrix(m_AbsoluteMatrix);
00528         }
00529         return this;
00530 }
00531 
00532 // Update children obsolute Matrix
00533 GLC_StructOccurence* GLC_StructOccurence::updateChildrenAbsoluteMatrix()
00534 {
00535         updateAbsoluteMatrix();
00536         const int size= m_Childs.size();
00537         for (int i= 0; i < size; ++i)
00538         {
00539                 m_Childs[i]->updateChildrenAbsoluteMatrix();
00540         }
00541         return this;
00542 }
00543 
00544 // Add Child
00545 void GLC_StructOccurence::addChild(GLC_StructOccurence* pChild)
00546 {
00547         Q_ASSERT(pChild->isOrphan());
00548         Q_ASSERT((NULL == pChild->m_pWorldHandle) || (m_pWorldHandle == pChild->m_pWorldHandle));
00549 
00550         //qDebug() << "Add Child " << pChild->name() << "id=" << pChild->id() << " to " << name() << " id=" << id();
00551         // Add the child to the list of child
00552         // Get occurence reference
00553         m_Childs.append(pChild);
00554         pChild->m_pParent= this;
00555         if (NULL == pChild->m_pWorldHandle)
00556         {
00557                 pChild->setWorldHandle(m_pWorldHandle);
00558         }
00559         pChild->updateChildrenAbsoluteMatrix();
00560 }
00561 
00562 // Add Child instance and returns the newly created occurence
00563 GLC_StructOccurence* GLC_StructOccurence::addChild(GLC_StructInstance* pInstance)
00564 {
00565         GLC_StructOccurence* pOccurence;
00566         pOccurence= new GLC_StructOccurence(pInstance, m_pWorldHandle);
00567 
00568         addChild(pOccurence);
00569 
00570         return pOccurence;
00571 }
00572 
00573 // make the occurence orphan
00574 void GLC_StructOccurence::makeOrphan()
00575 {
00576         //qDebug() << "GLC_StructOccurence::makeOrphan() " << id();
00577         //qDebug() << name() << " " << id();
00578         Q_ASSERT(!isOrphan());
00579         m_pParent->removeChild(this);
00580         //qDebug() << "GLC_StructOccurence::makeOrphan() DONE!";
00581 }
00582 
00583 // Remove the specified child
00584 bool GLC_StructOccurence::removeChild(GLC_StructOccurence* pChild)
00585 {
00586         Q_ASSERT(pChild->m_pParent == this);
00587         Q_ASSERT(m_Childs.contains(pChild));
00588         pChild->m_pParent= NULL;
00589         pChild->detach();
00590 
00591         return m_Childs.removeOne(pChild);
00592 }
00593 
00594 
00595 // Reverse Normals of this Occurence and childs
00596 void GLC_StructOccurence::reverseNormals()
00597 {
00598         if (has3DViewInstance())
00599         {
00600                 m_pWorldHandle->collection()->instanceHandle(id())->reverseGeometriesNormals();
00601         }
00602 }
00603 
00604 // Check the presence of representation
00605 bool GLC_StructOccurence::create3DViewInstance()
00606 {
00607         bool creationSuccess= false;
00608         if ((NULL != m_pWorldHandle) && hasRepresentation())
00609         {
00610                 GLC_3DRep* p3DRep= dynamic_cast<GLC_3DRep*>(structReference()->representationHandle());
00611                 if (NULL != p3DRep)
00612                 {
00613                         GLC_3DViewInstance instance(*p3DRep);
00614                         instance.setName(name());
00615 
00616                         // Force instance representation id
00617                         instance.setId(id());
00618 
00619                         if (NULL != m_pRenderProperties)
00620                         {
00621                                 instance.setRenderProperties(*m_pRenderProperties);
00622                                 delete m_pRenderProperties;
00623                                 m_pRenderProperties= NULL;
00624                         }
00625 
00626                         creationSuccess= m_pWorldHandle->collection()->add(instance);
00627                         m_pWorldHandle->collection()->setVisibility(m_Uid, m_IsVisible);
00628                         if (m_pWorldHandle->selectionSetHandle()->contains(m_Uid))
00629                         {
00630                                 m_pWorldHandle->collection()->select(m_Uid);
00631                         }
00632                 }
00633         }
00634         return creationSuccess;
00635 }
00636 
00637 bool GLC_StructOccurence::remove3DViewInstance()
00638 {
00639         if (NULL != m_pWorldHandle)
00640         {
00641                 return m_pWorldHandle->collection()->remove(m_Uid);
00642         }
00643         else return false;
00644 }
00645 
00646 // Set the occurence world Handle
00647 void GLC_StructOccurence::setWorldHandle(GLC_WorldHandle* pWorldHandle)
00648 {
00649         // Check if world handles are equal
00650         if (m_pWorldHandle == pWorldHandle) return;
00651 
00652         if (NULL != m_pWorldHandle)
00653         {
00654                 m_pWorldHandle->removeOccurence(this);
00655         }
00656 
00657         m_pWorldHandle= pWorldHandle;
00658 
00659         if (NULL != m_pWorldHandle)
00660         {
00661                 m_pWorldHandle->addOccurence(this);
00662                 m_pWorldHandle->collection()->setVisibility(m_Uid, m_IsVisible);
00663 
00664                 const int size= m_Childs.size();
00665                 for (int i= 0; i < size; ++i)
00666                 {
00667                         m_Childs[i]->setWorldHandle(m_pWorldHandle);
00668                 }
00669         }
00670 }
00671 
00672 // Load the representation and return true if success
00673 bool GLC_StructOccurence::loadRepresentation()
00674 {
00675         Q_ASSERT(!this->has3DViewInstance());
00676 
00677         bool loadSuccess= false;
00678         if (hasRepresentation())
00679         {
00680                 GLC_StructReference* pReference= this->structReference();
00681                 if (pReference->representationIsLoaded())
00682                 {
00683                         loadSuccess= create3DViewInstance();
00684                 }
00685                 else
00686                 {
00687                         loadSuccess=  m_pStructInstance->structReference()->loadRepresentation();
00688                         if (loadSuccess && !m_AutomaticCreationOf3DViewInstance)
00689                         {
00690                                 loadSuccess= create3DViewInstance();
00691                         }
00692                 }
00693         }
00694 
00695         return loadSuccess;
00696 }
00697 
00698 // UnLoad the representation and return true if success
00699 bool GLC_StructOccurence::unloadRepresentation()
00700 {
00701         bool unloadResult= false;
00702         if (hasRepresentation())
00703         {
00704                 GLC_StructReference* pRef= this->structReference();
00705                 if (pRef->representationIsLoaded())
00706                 {
00707                         if (this->has3DViewInstance())
00708                         {
00709                                 unloadResult= m_pWorldHandle->collection()->remove(m_Uid);
00710                                 QSet<GLC_StructOccurence*> occurenceSet= pRef->setOfStructOccurence();
00711                                 QSet<GLC_StructOccurence*>::const_iterator iOcc= occurenceSet.constBegin();
00712                                 bool unloadReferenceRep= true;
00713                                 while (occurenceSet.constEnd() != iOcc)
00714                                 {
00715                                         unloadReferenceRep= unloadReferenceRep && !(*iOcc)->has3DViewInstance();
00716                                         ++iOcc;
00717                                 }
00718                                 if (unloadReferenceRep)
00719                                 {
00720                                         pRef->unloadRepresentation();
00721                                 }
00722                         }
00723                 }
00724         }
00725         return unloadResult;
00726 }
00727 
00728 unsigned int GLC_StructOccurence::updateOccurenceNumber(unsigned int n)
00729 {
00730         m_OccurenceNumber= n++;
00731         const int childCount= m_Childs.size();
00732         for (int i= 0; i < childCount; ++i)
00733         {
00734                 n= m_Childs[i]->updateOccurenceNumber(n);
00735         }
00736         return n;
00737 }
00738 
00739 void GLC_StructOccurence::setVisibility(bool visibility)
00740 {
00741         m_IsVisible= visibility;
00742         if (has3DViewInstance())
00743         {
00744                 m_pWorldHandle->collection()->setVisibility(m_Uid, m_IsVisible);
00745         }
00746         const int childCount= m_Childs.size();
00747         for (int i= 0; i < childCount; ++i)
00748         {
00749                 m_Childs[i]->setVisibility(m_IsVisible);
00750         }
00751 }
00752 
00753 void GLC_StructOccurence::setRenderProperties(const GLC_RenderProperties& renderProperties)
00754 {
00755         delete m_pRenderProperties;
00756         if (has3DViewInstance())
00757         {
00758                 m_pWorldHandle->collection()->instanceHandle(m_Uid)->setRenderProperties(renderProperties);
00759         }
00760         else if (hasChild())
00761         {
00762                 const int childCount= m_Childs.size();
00763                 for (int i= 0; i < childCount; ++i)
00764                 {
00765                         m_Childs[i]->setRenderProperties(renderProperties);
00766                 }
00767         }
00768         else
00769         {
00770                 m_pRenderProperties= new GLC_RenderProperties(renderProperties);
00771         }
00772 }
00773 
00774 void GLC_StructOccurence::removeEmptyChildren()
00775 {
00776         QList<GLC_StructOccurence*>::iterator iChild= m_Childs.begin();
00777         while (m_Childs.constEnd() != iChild)
00778         {
00779                 if (!((*iChild)->hasChild()) && !((*iChild)->hasRepresentation()))
00780                 {
00781                         delete *iChild;
00782                         iChild= m_Childs.erase(iChild);
00783                 }
00784                 else
00785                 {
00786                         (*iChild)->removeEmptyChildren();
00787                         ++iChild;
00788                 }
00789         }
00790 }
00791 
00792 void GLC_StructOccurence::setReference(GLC_StructReference* pRef)
00793 {
00794         Q_ASSERT(m_pStructInstance->structReference() == NULL);
00795         Q_ASSERT((*m_pNumberOfOccurence) == 1);
00796 
00797         if (pRef->hasStructInstance())
00798         {
00799                 GLC_StructInstance* pExistingInstance= pRef->firstInstanceHandle();
00800                 if (pExistingInstance->hasStructOccurence())
00801                 {
00802                         GLC_StructOccurence* pFirstOccurence= pExistingInstance->firstOccurenceHandle();
00803                         QList<GLC_StructOccurence*> childs= pFirstOccurence->m_Childs;
00804                         const int size= childs.size();
00805                         for (int i= 0; i < size; ++i)
00806                         {
00807                                 GLC_StructOccurence* pChild= childs.at(i)->clone(m_pWorldHandle, true);
00808                                 addChild(pChild);
00809                         }
00810 
00811                         QList<GLC_StructInstance*> instances= pRef->listOfStructInstances();
00812                         const int instanceCount= instances.size();
00813                         int i= 0;
00814                         bool continu= true;
00815                         while (continu && (i < instanceCount))
00816                         {
00817                                 if (m_pStructInstance == instances.at(i))
00818                                 {
00819                                         continu= false;
00820                                         delete m_pNumberOfOccurence;
00821                                         m_pNumberOfOccurence= instances.at(i)->firstOccurenceHandle()->m_pNumberOfOccurence;
00822                                         ++(*m_pNumberOfOccurence);
00823                                 }
00824                                 ++i;
00825                         }
00826                 }
00827         }
00828 
00829         m_pStructInstance->setReference(pRef);
00830 }
00831 
00832 void GLC_StructOccurence::makeFlexible(const GLC_Matrix4x4& relativeMatrix)
00833 {
00834         delete m_pRelativeMatrix;
00835         m_pRelativeMatrix= new GLC_Matrix4x4(relativeMatrix);
00836 
00837         updateChildrenAbsoluteMatrix();
00838 }
00839 
00840 void GLC_StructOccurence::makeRigid()
00841 {
00842         delete m_pRelativeMatrix;
00843         m_pRelativeMatrix= NULL;
00844 
00845         updateChildrenAbsoluteMatrix();
00846 }
00847 
00848 
00850 // Private services function
00852 
00853 void GLC_StructOccurence::detach()
00854 {
00855         if (NULL != m_pWorldHandle)
00856         {
00857                 // retrieve renderProperties if needed
00858                 if (m_pWorldHandle->collection()->contains(m_Uid))
00859                 {
00860                         GLC_3DViewInstance* pInstance= m_pWorldHandle->collection()->instanceHandle(m_Uid);
00861                         if (!pInstance->renderPropertiesHandle()->isDefault())
00862                         {
00863                                 Q_ASSERT(NULL == m_pRenderProperties);
00864                                 m_pRenderProperties= new GLC_RenderProperties(*(pInstance->renderPropertiesHandle()));
00865                         }
00866                 }
00867                 m_pWorldHandle->removeOccurence(this);
00868                 m_pWorldHandle= NULL;
00869                 if (!m_Childs.isEmpty())
00870                 {
00871                         const int size= m_Childs.size();
00872                         for (int i= 0; i < size; ++i)
00873                         {
00874                                 m_Childs[i]->detach();
00875                         }
00876                 }
00877         }
00878 }

SourceForge.net Logo

©2005-2011 Laurent Ribon