00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
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
00047 m_pStructInstance->structOccurenceCreated(this);
00048 }
00049
00050
00051
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
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
00087 if (NULL != m_pWorldHandle)
00088 {
00089 m_pWorldHandle->addOccurence(this, shaderId);
00090 }
00091
00092
00093 updateAbsoluteMatrix();
00094
00095
00096 m_pStructInstance->structOccurenceCreated(this);
00097 }
00098
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
00117 m_pStructInstance->structOccurenceCreated(this);
00118 }
00119
00120
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
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
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
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
00184 updateAbsoluteMatrix();
00185
00186
00187
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
00196 m_pStructInstance->structOccurenceCreated(this);
00197 }
00198
00199
00200 GLC_StructOccurence::~GLC_StructOccurence()
00201 {
00202
00203 Q_ASSERT(m_pNumberOfOccurence != NULL);
00204
00205 if (NULL != m_pWorldHandle)
00206 {
00207 m_pWorldHandle->removeOccurence(this);
00208 }
00209
00210
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
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
00235
00236
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
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
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
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
00315 GLC_StructOccurence* GLC_StructOccurence::clone(GLC_WorldHandle* pWorldHandle, bool shareInstance) const
00316 {
00317 return new GLC_StructOccurence(pWorldHandle, *this, shareInstance);
00318 }
00319
00320
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
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
00388
00389
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
00401 if ((NULL != m_pWorldHandle) && m_HasRepresentation)
00402 {
00403 m_pWorldHandle->collection()->instanceHandle(id())->setMatrix(m_AbsoluteMatrix);
00404 }
00405 return this;
00406 }
00407
00408
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
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
00427
00428
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
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
00450 void GLC_StructOccurence::makeOrphan()
00451 {
00452
00453
00454 Q_ASSERT(!isOrphan());
00455 m_pParent->removeChild(this);
00456
00457 }
00458
00459
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
00471 void GLC_StructOccurence::detach()
00472 {
00473
00474 if (NULL != m_pWorldHandle)
00475 {
00476
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
00500 void GLC_StructOccurence::reverseNormals()
00501 {
00502 if (m_HasRepresentation)
00503 {
00504 m_pWorldHandle->collection()->instanceHandle(id())->reverseGeometriesNormals();
00505 }
00506 }
00507
00508
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
00522 instance.setId(id());
00523 m_pWorldHandle->collection()->add(instance);
00524 }
00525 m_HasRepresentation= true;
00526 }
00527 }
00528 }
00529
00530
00531 void GLC_StructOccurence::setWorldHandle(GLC_WorldHandle* pWorldHandle)
00532 {
00533
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
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
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 }