OSGNode.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *           Copyright (C) 2003 by the OpenSG Forum                          *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037 \*---------------------------------------------------------------------------*/
00038
00039 //---------------------------------------------------------------------------
00040 //  Includes
00041 //---------------------------------------------------------------------------
00042
00043 #include <cstdlib>
00044 #include <cstdio>
00045
00046 #include "OSGConfig.h"
00047
00048 #include "OSGLog.h"
00049 #include "OSGNode.h"
00050 #include "OSGNodeCore.h"
00051
00052 #include "OSGTypeBasePredicates.h"
00053 #include "OSGReflexiveContainerTypePredicates.h"
00054
00055 #include "boost/bind.hpp"
00056
00057 #ifdef WIN32 // turn of 'this' : used in base member initializer lits warning
00058 #pragma warning(disable:4355)
00059 #endif
00060 
00061 OSG_BEGIN_NAMESPACE
00062
00063 /***************************************************************************\
00064  *                            Description                                  *
00065 \***************************************************************************/
00066
00073 /***************************************************************************\
00074  *                         Field Description                               *
00075 \***************************************************************************/
00076
00100 void Node::classDescInserter(TypeObject &oType)
00101 {
00102     FieldDescriptionBase *pDesc = NULL;
00103
00104     pDesc = new SFBoxVolume::Description(
00105         SFBoxVolume::getClassType(),
00106         "volume",
00107         "Bounding volume for the node.",
00108         OSG_RC_FIELD_DESC(Node::Volume),
00109         true,
00110         Field::SFDefaultFlags,
00111         static_cast<FieldEditMethodSig>(&Node::editHandleVolume),
00112         static_cast<FieldGetMethodSig >(&Node::getHandleVolume ));
00113
00114     oType.addInitialDesc(pDesc);
00115
00116
00117     pDesc = new SFUInt32::Description(
00118         SFUInt32::getClassType(),
00119         "travMask",
00120         "Traversal mask for the node.",
00121         OSG_RC_FIELD_DESC(Node::TravMask),
00122         false,
00123         Field::SFDefaultFlags,
00124         static_cast<FieldEditMethodSig>(&Node::editHandleTravMask),
00125         static_cast<FieldGetMethodSig >(&Node::getHandleTravMask ));
00126
00127     oType.addInitialDesc(pDesc);
00128
00129
00130     pDesc = new SFParentNodePtr::Description(
00131         SFParentNodePtr::getClassType(),
00132         "parent",
00133         "This node's parent.",
00134         OSG_RC_FIELD_DESC(Node::Parent),
00135         true,
00136         Field::SFDefaultFlags,
00137         static_cast<FieldEditMethodSig>(&Node::invalidEditField),
00138         static_cast<FieldGetMethodSig >(&Node::getHandleParent ));
00139
00140     oType.addInitialDesc(pDesc);
00141
00142
00143     pDesc = new SFUnrecChildNodeCorePtr::Description(
00144         SFUnrecChildNodeCorePtr::getClassType(),
00145         "core",
00146         "The core to use for this node.",
00147         OSG_RC_FIELD_DESC(Node::Core),
00148         false,
00149         (Field::SFDefaultFlags | Field::FStdAccess),
00150         static_cast<FieldEditMethodSig>(&Node::editHandleCore),
00151         static_cast<FieldGetMethodSig >(&Node::getHandleCore ));
00152
00153     oType.addInitialDesc(pDesc);
00154
00155
00156     pDesc = new MFUnrecChildNodePtr::Description(
00157         MFUnrecChildNodePtr::getClassType(),
00158         "children",
00159         "A list of our children in the scene graph.",
00160         OSG_RC_FIELD_DESC(Node::Children),
00161         false,
00162         (Field::MFDefaultFlags | Field::FNullCheckAccess),
00163         static_cast<FieldEditMethodSig>(&Node::editHandleChildren),
00164         static_cast<FieldGetMethodSig >(&Node::getHandleChildren));
00165
00166     oType.addInitialDesc(pDesc);
00167 }
00168
00169 Node::TypeObject Node::_type(
00170     Node     ::getClassname(),
00171     Inherited::getClassname(),
00172     "Node",
00173     0,
00174     reinterpret_cast<PrototypeCreateF>(&Node::createEmptyLocal),
00175     NULL,
00176     NULL,
00177     reinterpret_cast<InitalInsertDescFunc>(&Node::classDescInserter),
00178     false,
00179     0);
00180
00181
00182 OSG_FIELD_CONTAINER_DEF(Node)
00183
00184
00185
00186 /*-------------------------------------------------------------------------*/
00187 /*                             Children                                    */
00188
00189 void Node::addChild(Node * const childP)
00190 {
00191     if(childP != NULL)
00192     {
00193         // do the ref early, to prevent destroys on getParent(a)->addChild(a)
00194
00195         editMField(ChildrenFieldMask, _mfChildren);
00196
00197         _mfChildren.push_back(childP);
00198     }
00199 }
00200
00201 void Node::addChild(NodeTransitPtr childP)
00202 {
00203     if(childP != NULL)
00204     {
00205         editMField(ChildrenFieldMask, _mfChildren);
00206
00207         NodeUnrecPtr tmpChild = childP;
00208
00209         _mfChildren.push_back(tmpChild);
00210     }
00211 }
00212
00223 void Node::insertChild(UInt32 childIndex, Node * const childP)
00224 {
00225     OSG_ASSERT((childIndex <= getNChildren()) && "Child index out of range");
00226
00227     if(childP != NULL)
00228     {
00229
00230         editMField(ChildrenFieldMask, _mfChildren);
00231
00232         MFUnrecChildNodePtr::iterator childIt = _mfChildren.begin_nc();
00233
00234         childIt += childIndex;
00235
00236         _mfChildren.insert(childIt, childP);
00237     }
00238 }
00239
00240 void Node::replaceChild(UInt32 childIndex, Node * const childP)
00241 {
00242     const Node *pThis = this;
00243
00244     if(childP     != NULL                           &&
00245        childIndex <  pThis->_mfChildren.size()      &&
00246        childP     != pThis->_mfChildren[childIndex]  )
00247     {
00248         editMField(ChildrenFieldMask, _mfChildren);
00249
00250         _mfChildren.replace(childIndex, childP);
00251     }
00252 }
00253
00255
00256 bool Node::replaceChildBy(Node * const childP,
00257                           Node * const newChildP)
00258 {
00259     if(newChildP != NULL && childP != newChildP)
00260     {
00261         Int32 childIdx = findChild(childP);
00262
00263         if(childIdx != -1)
00264         {
00265             // do the ref early, to prevent destroys on
00266             editMField(ChildrenFieldMask, _mfChildren);
00267
00268             _mfChildren.replace(childIdx, newChildP);
00269
00270             return true;
00271         }
00272     }
00273
00274     return false;
00275 }
00276
00277 Int32 Node::findChild(Node * const childP) const
00278 {
00279     UInt32 index;
00280
00281     for(index = 0; index < _mfChildren.size(); index++)
00282     {
00283         if( _mfChildren[index] == childP)
00284             break;
00285     }
00286
00287     if(index < _mfChildren.size())
00288     {
00289         return index;
00290     }
00291     else
00292     {
00293         return -1;
00294     }
00295 }
00296
00297 void Node::subChild(Node * const childP)
00298 {
00299     Int32 childIdx = findChild(childP);
00300
00301     if(childIdx != -1)
00302     {
00303         editMField(ChildrenFieldMask, _mfChildren);
00304
00305 //        MFUnrecChildNodePtr::iterator childIt = _mfChildren.begin_nc();
00306
00307 //        childIt += childIdx;
00308
00309         _mfChildren.erase(childIdx);
00310     }
00311     else
00312     {
00313         SWARNING << "Node(" << this << ")::subChild: " << childP
00314                  << " is not one of my children!" << std::endl;
00315     }
00316 }
00317
00318 void Node::subChild(UInt32 childIndex)
00319 {
00320     if(childIndex < _mfChildren.size())
00321     {
00322         editMField(ChildrenFieldMask, _mfChildren);
00323
00324 //        MFUnrecChildNodePtr::iterator childIt = _mfChildren.begin_nc();
00325
00326 //        childIt += childIndex;
00327
00328         _mfChildren.erase(childIndex);
00329     }
00330 }
00331
00332 void Node::clearChildren(void)
00333 {
00334     editMField(ChildrenFieldMask, _mfChildren);
00335
00336     _mfChildren.clear();
00337 }
00338
00339 UInt32 Node::getBinSize(ConstFieldMaskArg whichField)
00340 {
00341     UInt32 returnValue = Inherited::getBinSize(whichField);
00342
00343     if(FieldBits::NoField != (VolumeFieldMask & whichField))
00344     {
00345         returnValue += _sfVolume.getBinSize();
00346     }
00347
00348     if(FieldBits::NoField != (TravMaskFieldMask & whichField))
00349     {
00350         returnValue += _sfTravMask.getBinSize();
00351     }
00352
00353     if(FieldBits::NoField != (ParentFieldMask & whichField))
00354     {
00355         returnValue += _sfParent.getBinSize();
00356     }
00357
00358     if(FieldBits::NoField != (ChildrenFieldMask & whichField))
00359     {
00360         returnValue += _mfChildren.getBinSize();
00361     }
00362
00363     if(FieldBits::NoField != (CoreFieldMask & whichField))
00364     {
00365         returnValue += _sfCore.getBinSize();
00366     }
00367
00368     return returnValue;
00369 }
00370
00371 void Node::copyToBin(BinaryDataHandler &pMem,
00372                      ConstFieldMaskArg  whichField)
00373 {
00374     Inherited::copyToBin(pMem, whichField);
00375
00376     if(FieldBits::NoField != (VolumeFieldMask & whichField))
00377     {
00378         _sfVolume.copyToBin(pMem);
00379     }
00380
00381     if(FieldBits::NoField != (TravMaskFieldMask & whichField))
00382     {
00383         _sfTravMask.copyToBin(pMem);
00384     }
00385
00386     if(FieldBits::NoField != (ParentFieldMask & whichField))
00387     {
00388         _sfParent.copyToBin(pMem);
00389     }
00390
00391     if(FieldBits::NoField != (ChildrenFieldMask & whichField))
00392     {
00393         _mfChildren.copyToBin(pMem);
00394     }
00395
00396     if(FieldBits::NoField != (CoreFieldMask & whichField))
00397     {
00398         _sfCore.copyToBin(pMem);
00399     }
00400 }
00401
00402 void Node::copyFromBin(BinaryDataHandler &pMem,
00403                        ConstFieldMaskArg  whichField)
00404 {
00405     Inherited::copyFromBin(pMem, whichField);
00406
00407     if(FieldBits::NoField != (VolumeFieldMask & whichField))
00408     {
00409         _sfVolume.copyFromBin(pMem);
00410     }
00411
00412     if(FieldBits::NoField != (TravMaskFieldMask & whichField))
00413     {
00414         _sfTravMask.copyFromBin(pMem);
00415     }
00416
00417     if(FieldBits::NoField != (ParentFieldMask & whichField))
00418     {
00419         _sfParent.copyFromBin(pMem);
00420     }
00421
00422     if(FieldBits::NoField != (ChildrenFieldMask & whichField))
00423     {
00424         _mfChildren.copyFromBin(pMem);
00425     }
00426
00427     if(FieldBits::NoField != (CoreFieldMask & whichField))
00428     {
00429         _sfCore.copyFromBin(pMem);
00430     }
00431 }
00432
00433 /*-------------------------------------------------------------------------*/
00434 /*                           Get Transformation                            */
00435
00436 Matrixr Node::getToWorld(void)
00437 {
00438     Matrixr tmp;
00439
00440     getToWorld(tmp);
00441
00442     return tmp;
00443 }
00444
00445 void Node::getToWorld(Matrixr &result)
00446 {
00447     if(getParent() != NULL)
00448     {
00449         getParent()->getToWorld(result);
00450     }
00451     else
00452     {
00453         result.setIdentity();
00454     }
00455
00456     if(getCore() != NULL)
00457         getCore()->accumulateMatrix(result);
00458 }
00459
00460 /*-------------------------------------------------------------------------*/
00461 /*                           Volume                                        */
00462
00463 void Node::getWorldVolume(BoxVolume &result)
00464 {
00465     Matrixr m;
00466
00467     if(getParent() != NULL)
00468     {
00469         getParent()->getToWorld(m);
00470     }
00471     else
00472     {
00473         m.setIdentity();
00474     }
00475
00476     updateVolume();
00477
00478     result = getVolume();
00479     result.transform(m);
00480 }
00481
00482 void Node::updateVolume(void)
00483 {
00484     // still valid, nothing to do
00485     if(_sfVolume.getValue().isValid() == true ||
00486        getTravMask()                  == 0x0000)
00487     {
00488         return;
00489     }
00490
00491     // be careful to not change the real volume. If two threads
00492     // are updating the same aspect this will lead to chaos
00493
00494     BoxVolume vol = _sfVolume.getValue();
00495
00496     MFUnrecChildNodePtr::const_iterator cIt  =
00497         this->getMFChildren()->begin();
00498
00499     MFUnrecChildNodePtr::const_iterator cEnd =
00500         this->getMFChildren()->end();
00501
00502     vol.setEmpty();
00503
00504     for(; cIt != cEnd; ++cIt)
00505     {
00506         if(*cIt != NULL && (*cIt)->getTravMask())
00507         {
00508             (*cIt)->updateVolume();
00509             vol.extendBy((*cIt)->getVolume());
00510         }
00511     }
00512
00513     // test for null core. Shouldn't happen, but just in case...
00514     if(getCore() != NULL)
00515     {
00516         getCore()->adjustVolume(vol);
00517     }
00518
00519     editSField(VolumeFieldMask);
00520
00521     _sfVolume.setValue(vol);
00522 }
00523
00524 /*-------------------------------------------------------------------------*/
00525 /*                            Constructors                                 */
00526
00527 Node::Node(void) :
00528      Inherited (                            ),
00529     _sfVolume  (                            ),
00530     _sfTravMask(TypeTraits<UInt32>::getMax()),
00531     _sfParent  (NULL                        ),
00532     _mfChildren(this,
00533                 ChildrenFieldId,
00534                 Node::ParentFieldId         ),
00535     _sfCore    (NULL,
00536                 this,
00537                 CoreFieldId,
00538                 NodeCore::ParentsFieldId    )
00539 #ifdef OSG_1_COMPAT
00540    ,_occlusionMask(0)
00541 #endif
00542 {
00543 }
00544
00545 Node::Node(const Node &source) :
00546      Inherited    (source                   ),
00547     _sfVolume     (                         ),
00548
00549     _sfTravMask   (source._sfTravMask       ),
00550
00551     _sfParent     (NULL                     ),
00552     _mfChildren   (this,
00553                    ChildrenFieldId,
00554                    Node::ParentFieldId      ),
00555
00556     _sfCore       (NULL,
00557                    this,
00558                    CoreFieldId,
00559                    NodeCore::ParentsFieldId )
00560 #ifdef OSG_1_COMPAT
00561    ,_occlusionMask(source._occlusionMask)
00562 #endif
00563 {
00564 }
00565 /*-------------------------------------------------------------------------*/
00566 /*                             Destructor                                  */
00567
00568 Node::~Node(void)
00569 {
00570 }
00571
00572 bool Node::linkParent  (FieldContainer * const pParent,
00573                         UInt16           const childFieldId,
00574                         UInt16           const parentFieldId)
00575 {
00576     if(parentFieldId == ParentFieldId)
00577     {
00578         Node *pTypedParent = dynamic_cast<Node *>(pParent);
00579
00580         if(pTypedParent != NULL)
00581         {
00582             Node *pOldParent      = _sfParent.getValue         ();
00583
00584             if(pOldParent != NULL)
00585             {
00586                 pOldParent->unlinkChild(this, ChildrenFieldId);
00587             }
00588
00589             editSField(ParentFieldMask);
00590
00591             _sfParent.setValue(pTypedParent, childFieldId);
00592
00593             return true;
00594         }
00595
00596         return false;
00597     }
00598
00599     return Inherited::linkParent(pParent, childFieldId, parentFieldId);
00600 }
00601
00602 bool Node::unlinkParent(FieldContainer * const pParent,
00603                         UInt16           const parentFieldId)
00604 {
00605     if(parentFieldId == ParentFieldId)
00606     {
00607         Node *pTypedParent = dynamic_cast<Node *>(pParent);
00608
00609         if(pTypedParent != NULL)
00610         {
00611             editSField(ParentFieldMask);
00612
00613             _sfParent.setValue(NULL, 0xFFFF);
00614
00615             return true;
00616         }
00617
00618         return false;
00619     }
00620
00621     return Inherited::unlinkParent(pParent, parentFieldId);
00622 }
00623
00624 bool Node::unlinkChild (FieldContainer * const pChild,
00625                         UInt16           const childFieldId )
00626 {
00627     if(childFieldId == ChildrenFieldId)
00628     {
00629         FINFO(("Node::unlinkChild: this [%p] [%u] pChild [%p] [%u]\n",
00630                this, this->getId(), pChild,
00631                pChild != NULL ? pChild->getId() : 0));
00632
00633         Node *pTypedChild = dynamic_cast<Node *>(pChild);
00634
00635         if(pTypedChild != NULL)
00636         {
00637             Int32 iChildIdx = _mfChildren.findIndex(pTypedChild);
00638
00639             if(iChildIdx != -1)
00640             {
00641                 editMField(ParentFieldMask, _mfChildren);
00642
00643                 _mfChildren.erase(iChildIdx);
00644
00645                 return true;
00646             }
00647
00648             FWARNING(("Node::unlinkChild: Child <-> Parent link "
00649                       "inconsistent.\n"));
00650
00651             return false;
00652         }
00653
00654         return false;
00655     }
00656
00657     if(childFieldId == CoreFieldId)
00658     {
00659         NodeCore *pTypedChild = dynamic_cast<NodeCore *>(pChild);
00660
00661         if(pTypedChild != NULL)
00662         {
00663             if(pTypedChild == getCore())
00664             {
00665                 editSField(CoreFieldMask);
00666
00667                 _sfCore.setValue(NULL);
00668
00669                 return true;
00670             }
00671
00672             FWARNING(("Node::unlinkChild: Child <-> Parent link "
00673                       "inconsistent.\n"));
00674
00675             return false;
00676         }
00677
00678         return false;
00679     }
00680
00681     return Inherited::unlinkChild(pChild, childFieldId);
00682 }
00683
00684 void Node::invalidateVolume(void)
00685 {
00686     BoxVolume &vol = _sfVolume.getValue();
00687
00688     if(vol.isValid() == true && vol.isStatic() == false)
00689     {
00690         editSField(VolumeFieldMask);
00691
00692         vol.setValid(false);
00693
00694         if(getParent() != NULL)
00695         {
00696             getParent()->invalidateVolume();
00697         }
00698     }
00699 }
00700
00701 void Node::changed(ConstFieldMaskArg whichField,
00702                    UInt32            origin,
00703                    BitVector         details    )
00704 {
00705     Inherited::changed(whichField, origin, details);
00706
00707     if(whichField & (CoreFieldMask | ChildrenFieldMask))
00708     {
00709         invalidateVolume();
00710     }
00711
00712     if(whichField & TravMaskFieldMask)
00713     {
00714         if(getParent() != NULL)
00715         {
00716             getParent()->invalidateVolume();
00717         }
00718         else
00719         {
00720             invalidateVolume();
00721         }
00722     }
00723 }
00724
00725 void Node::dump(      UInt32    uiIndent,
00726                 const BitVector bvFlags ) const
00727 {
00728     UInt32 i;
00729
00730     indentLog(uiIndent, PLOG);
00731
00732     PLOG << "Node"
00733          << "("
00734          << this->getId()
00735          << ") : "
00736          << _mfChildren.size()
00737          << " children | "
00738 //         << _attachmentMap.getValue().size()
00739          << " attachments | "
00740          << "Parent : " << std::hex;
00741
00742     if(_sfParent.getValue() != NULL)
00743     {
00744         PLOG << _sfParent.getValue()->getId() << " | ";
00745     }
00746     else
00747     {
00748         PLOG << "NULL | ";
00749     }
00750
00751     PLOG << this << std::dec << std::endl;
00752
00753     indentLog(uiIndent, PLOG);
00754
00755     PLOG << "[" << std::endl;
00756
00757     if(_sfCore.getValue() != NULL)
00758     {
00759         _sfCore.getValue()->dump(uiIndent + 4, bvFlags);
00760     }
00761     else
00762     {
00763         indentLog(uiIndent + 4, PLOG);
00764         PLOG << "Core : " << "NULL" << std::endl;
00765     }
00766
00767     Inherited::dump(uiIndent + 4, bvFlags);
00768
00769     indentLog(uiIndent, PLOG);
00770     PLOG << "]" << std::endl;
00771
00772     indentLog(uiIndent, PLOG);
00773
00774     PLOG << "{" << std::endl;
00775
00776     for(i = 0; i < _mfChildren.size(); i++)
00777     {
00778         _mfChildren[i]->dump(uiIndent + 4, bvFlags);
00779         PLOG << std::endl;
00780     }
00781
00782
00783     indentLog(uiIndent, PLOG);
00784
00785     PLOG << "}" << std::endl;
00786 }
00787
00788 /*-------------------------------------------------------------------------*/
00789 /*                             Assignment                                  */
00790
00791 SFBoxVolume *Node::editSFVolume(void)
00792 {
00793     editSField(VolumeFieldMask);
00794
00795     return &_sfVolume;
00796 }
00797
00798 const SFBoxVolume *Node::getSFVolume(void) const
00799 {
00800     return &_sfVolume;
00801 }
00802
00803 SFUInt32 *Node::editSFTravMask(void)
00804 {
00805     editSField(TravMaskFieldMask);
00806
00807     return &_sfTravMask;
00808 }
00809
00810 const SFUInt32 *Node::getSFTravMask(void) const
00811 {
00812     return &_sfTravMask;
00813 }
00814
00815 const SFParentNodePtr *Node::getSFParent(void) const
00816 {
00817     return &_sfParent;
00818 }
00819
00820 const SFUnrecChildNodeCorePtr *Node::getSFCore(void) const
00821 {
00822     return &_sfCore;
00823 }
00824
00825 const MFUnrecChildNodePtr *Node::getMFChildren(void) const
00826 {
00827     return &_mfChildren;
00828 }
00829
00830 #ifdef OSG_MT_CPTR_ASPECT
00831 FieldContainer *Node::createAspectCopy(const FieldContainer *pRefAspect) const
00832 {
00833     Node *returnValue = NULL;
00834
00835     newAspectCopy(returnValue,
00836                   dynamic_cast<const Node *>(pRefAspect),
00837                   dynamic_cast<const Node *>(this));
00838
00839     return returnValue;
00840 }
00841 #endif
00842 
00843 #ifdef OSG_MT_CPTR_ASPECT
00844 void Node::execSyncV(      FieldContainer     &oFrom,
00845                             ConstFieldMaskArg  whichField,
00846                             AspectOffsetStore &oOffsets,
00847                             ConstFieldMaskArg  syncMode  ,
00848                       const UInt32             uiSyncInfo)
00849 {
00850     this->execSync(static_cast<Node *>(&oFrom),
00851                    whichField,
00852                    oOffsets,
00853                    syncMode,
00854                    uiSyncInfo);
00855 }
00856 #endif
00857 
00858 EditFieldHandlePtr Node::editHandleVolume(void)
00859 {
00860     SFBoxVolume::EditHandlePtr returnValue(
00861         new  SFBoxVolume::EditHandle(
00862              &_sfVolume,
00863              this->getType().getFieldDesc(VolumeFieldId),
00864              this));
00865
00866     editSField(VolumeFieldMask);
00867
00868     return returnValue;
00869 }
00870
00871 GetFieldHandlePtr  Node::getHandleVolume(void) const
00872 {
00873     SFBoxVolume::GetHandlePtr returnValue(
00874         new  SFBoxVolume::GetHandle(
00875              &_sfVolume,
00876              this->getType().getFieldDesc(VolumeFieldId),
00877              const_cast<Node *>(this)));
00878
00879     return returnValue;
00880 }
00881
00882 EditFieldHandlePtr Node::editHandleTravMask(void)
00883 {
00884     SFUInt32::EditHandlePtr returnValue(
00885         new  SFUInt32::EditHandle(
00886              &_sfTravMask,
00887              this->getType().getFieldDesc(TravMaskFieldId),
00888              this));
00889
00890     editSField(TravMaskFieldMask);
00891
00892     return returnValue;
00893 }
00894
00895 GetFieldHandlePtr Node::getHandleTravMask(void) const
00896 {
00897     SFUInt32::GetHandlePtr returnValue(
00898         new  SFUInt32::GetHandle(
00899              &_sfTravMask,
00900              this->getType().getFieldDesc(TravMaskFieldId),
00901              const_cast<Node *>(this)));
00902
00903     return returnValue;
00904 }
00905
00906 GetFieldHandlePtr Node::getHandleParent(void) const
00907 {
00908     SFParentNodePtr::GetHandlePtr returnValue(
00909         new SFParentNodePtr::GetHandle(
00910              &_sfParent,
00911              this->getType().getFieldDesc(ParentFieldId),
00912              const_cast<Node *>(this)));
00913
00914     return returnValue;
00915 }
00916
00917 EditFieldHandlePtr Node::editHandleCore(void)
00918 {
00919     SFUnrecChildNodeCorePtr::EditHandlePtr returnValue(
00920         new SFUnrecChildNodeCorePtr::EditHandle(
00921              &_sfCore,
00922              this->getType().getFieldDesc(CoreFieldId),
00923              this));
00924
00925     typedef void (Node::*SetCoreF)(NodeCore * const);
00926
00927     SetCoreF fFunc = &Node::setCore;
00928
00929     returnValue->setSetMethod(boost::bind(fFunc, this, _1));
00930
00931     editSField(CoreFieldMask);
00932
00933     return returnValue;
00934 }
00935
00936 GetFieldHandlePtr Node::getHandleCore(void) const
00937 {
00938     SFUnrecChildNodeCorePtr::GetHandlePtr returnValue(
00939         new SFUnrecChildNodeCorePtr::GetHandle(
00940              &_sfCore,
00941              this->getType().getFieldDesc(CoreFieldId),
00942              const_cast<Node *>(this)));
00943
00944     return returnValue;
00945 }
00946
00947 EditFieldHandlePtr Node::editHandleChildren(void)
00948 {
00949     MFUnrecChildNodePtr::EditHandlePtr returnValue(
00950         new  MFUnrecChildNodePtr::EditHandle(
00951              &_mfChildren,
00952              this->getType().getFieldDesc(ChildrenFieldId),
00953              this));
00954
00955     typedef void (Node::*AddChildF)(Node * const);
00956
00957     AddChildF fFunc = &Node::addChild;
00958
00959     returnValue->setAddMethod(boost::bind(fFunc, this, _1));
00960
00961     editMField(ChildrenFieldMask, _mfChildren);
00962
00963     return returnValue;
00964 }
00965
00966 GetFieldHandlePtr  Node::getHandleChildren(void) const
00967 {
00968     MFUnrecChildNodePtr::GetHandlePtr returnValue(
00969         new  MFUnrecChildNodePtr::GetHandle(
00970              &_mfChildren,
00971              this->getType().getFieldDesc(ChildrenFieldId),
00972              const_cast<Node *>(this)));
00973
00974     return returnValue;
00975 }
00976
00977 void Node::resolveLinks(void)
00978 {
00979     FINFO(("Node::resolveLinks [%p] [%u]\n", this, this->getId()));
00980
00981     Inherited::resolveLinks();
00982
00983     _sfCore.setValue(NULL);
00984
00985     _mfChildren.clear();
00986 }
00987
00988 /*---------------------------------------------------------------------*/
01009 NodeTransitPtr cloneTree(const OSG::Node                *rootNode,
01010                          const std::vector<std::string> &cloneTypeNames,
01011                          const std::vector<std::string> &ignoreTypeNames,
01012                          const std::vector<std::string> &cloneGroupNames,
01013                          const std::vector<std::string> &ignoreGroupNames)
01014 {
01015     std::vector<const ReflexiveContainerType *> cloneTypes;
01016     std::vector<const ReflexiveContainerType *> ignoreTypes;
01017     std::vector<UInt16>                         cloneGroupIds;
01018     std::vector<UInt16>                         ignoreGroupIds;
01019
01020     appendTypesVector (cloneTypeNames,   cloneTypes    );
01021     appendTypesVector (ignoreTypeNames,  ignoreTypes   );
01022     appendGroupsVector(cloneGroupNames,  cloneGroupIds );
01023     appendGroupsVector(ignoreGroupNames, ignoreGroupIds);
01024
01025     return cloneTree(rootNode, cloneTypes,    ignoreTypes,
01026                                cloneGroupIds, ignoreGroupIds);
01027 }
01028
01043 NodeTransitPtr cloneTree(const OSG::Node                *rootNode,
01044                          const std::vector<OSG::UInt16> &cloneGroupIds,
01045                          const std::vector<OSG::UInt16> &ignoreGroupIds)
01046 {
01047     std::vector<const ReflexiveContainerType *> cloneTypes;
01048     std::vector<const ReflexiveContainerType *> ignoreTypes;
01049
01050     return cloneTree(rootNode, cloneTypes,    ignoreTypes,
01051                                cloneGroupIds, ignoreGroupIds);
01052 }
01053
01070 NodeTransitPtr cloneTree(const OSG::Node       *rootNode,
01071                          const std::string     &cloneTypesString,
01072                          const std::string     &ignoreTypesString)
01073 {
01074     std::vector<const ReflexiveContainerType *> cloneTypes;
01075     std::vector<const ReflexiveContainerType *> ignoreTypes;
01076     std::vector<UInt16>                         cloneGroupIds;
01077     std::vector<UInt16>                         ignoreGroupIds;
01078
01079     appendTypesString(cloneTypesString,  cloneTypes);
01080     appendTypesString(ignoreTypesString, ignoreTypes);
01081
01082     return cloneTree(rootNode, cloneTypes,    ignoreTypes,
01083                                cloneGroupIds, ignoreGroupIds);
01084 }
01085
01103 NodeTransitPtr cloneTree(
01104     const OSG::Node                                        *rootNode,
01105     const std::vector<const OSG::ReflexiveContainerType *> &cloneTypes,
01106     const std::vector<const OSG::ReflexiveContainerType *> &ignoreTypes,
01107     const std::vector<OSG::UInt16>                         &cloneGroupIds,
01108     const std::vector<OSG::UInt16>                         &ignoreGroupIds)
01109 {
01110     NodeUnrecPtr rootClone(NULL);
01111
01112     if(rootNode != NULL)
01113     {
01114         NodeUnrecPtr  childClone;
01115         NodeCore     *core       = rootNode->getCore();
01116
01117         rootClone = Node::create();
01118         rootClone->setTravMask(rootNode->getTravMask());
01119
01120         cloneAttachments(rootNode,      rootClone,
01121                          cloneTypes,    ignoreTypes,
01122                          cloneGroupIds, ignoreGroupIds);
01123
01124         if(core != NULL)
01125         {
01126                   NodeCoreUnrecPtr    coreClone  = NULL;
01127             const FieldContainerType &coreType   = core->getType();
01128
01129             // test if core type should NOT be ignored
01130             if(!TypePredicates::typeInGroupIds(
01131                     ignoreGroupIds.begin(),
01132                     ignoreGroupIds.end(), coreType) &&
01133                !TypePredicates::typeDerivedFrom(
01134                     ignoreTypes.begin(),
01135                     ignoreTypes.end(),    coreType)   )
01136             {
01137                 // test if core should cloned
01138                 if(TypePredicates::typeInGroupIds (
01139                        cloneGroupIds.begin(),
01140                        cloneGroupIds.end(), coreType) ||
01141                    TypePredicates::typeDerivedFrom(
01142                        cloneTypes.begin(),
01143                        cloneTypes.end(),    coreType)   )
01144                 {
01145                     // clone core
01146                     coreClone =
01147                         dynamic_pointer_cast<NodeCore>(
01148                             deepClone(core,
01149                                       cloneTypes,    ignoreTypes,
01150                                       cloneGroupIds, ignoreGroupIds));
01151                 }
01152                 else
01153                 {
01154                     // share core
01155                     coreClone = core;
01156                 }
01157             }
01158
01159             rootClone->setCore(coreClone);
01160         }
01161
01162         for(UInt32 i = 0; i < rootNode->getNChildren(); ++i)
01163         {
01164             childClone = cloneTree(rootNode->getChild(i),
01165                                    cloneTypes,    ignoreTypes,
01166                                    cloneGroupIds, ignoreGroupIds);
01167
01168             rootClone->addChild(childClone);
01169         }
01170     }
01171
01172     return NodeTransitPtr(rootClone);
01173 }
01174
01192 NodeTransitPtr deepCloneTree(const OSG::Node                *rootNode,
01193                              const std::vector<std::string> &shareTypeNames,
01194                              const std::vector<std::string> &ignoreTypeNames,
01195                              const std::vector<std::string> &shareGroupNames,
01196                              const std::vector<std::string> &ignoreGroupNames)
01197 {
01198     std::vector<const ReflexiveContainerType *> shareTypes;
01199     std::vector<const ReflexiveContainerType *> ignoreTypes;
01200     std::vector<UInt16>                         shareGroupIds;
01201     std::vector<UInt16>                         ignoreGroupIds;
01202
01203     appendTypesVector (shareTypeNames,   shareTypes    );
01204     appendTypesVector (ignoreTypeNames,  ignoreTypes   );
01205     appendGroupsVector(shareGroupNames,  shareGroupIds );
01206     appendGroupsVector(ignoreGroupNames, ignoreGroupIds);
01207
01208     return deepCloneTree(rootNode, shareTypes,    ignoreTypes,
01209                                    shareGroupIds, ignoreGroupIds);
01210 }
01211
01226 NodeTransitPtr deepCloneTree(const OSG::Node                *rootNode,
01227                              const std::vector<OSG::UInt16> &shareGroupIds,
01228                              const std::vector<OSG::UInt16> &ignoreGroupIds)
01229 {
01230     std::vector<const ReflexiveContainerType *> shareTypes;
01231     std::vector<const ReflexiveContainerType *> ignoreTypes;
01232
01233     return deepCloneTree(rootNode, shareTypes,    ignoreTypes,
01234                                    shareGroupIds, ignoreGroupIds);
01235 }
01236
01253 NodeTransitPtr deepCloneTree(const Node            *rootNode,
01254                              const std::string     &shareTypesString,
01255                              const std::string     &ignoreTypesString)
01256 {
01257     std::vector<const ReflexiveContainerType *> shareTypes;
01258     std::vector<const ReflexiveContainerType *> ignoreTypes;
01259     std::vector<UInt16>                         shareGroupIds;
01260     std::vector<UInt16>                         ignoreGroupIds;
01261
01262     appendTypesString(shareTypesString,  shareTypes);
01263     appendTypesString(ignoreTypesString, ignoreTypes);
01264
01265     return deepCloneTree(rootNode, shareTypes,    ignoreTypes,
01266                                    shareGroupIds, ignoreGroupIds);
01267 }
01268
01286 NodeTransitPtr deepCloneTree(
01287     const OSG::Node                                        *rootNode,
01288     const std::vector<const OSG::ReflexiveContainerType *> &shareTypes,
01289     const std::vector<const OSG::ReflexiveContainerType *> &ignoreTypes,
01290     const std::vector<OSG::UInt16>                         &shareGroupIds,
01291     const std::vector<OSG::UInt16>                         &ignoreGroupIds)
01292 {
01293     NodeUnrecPtr rootClone(NULL);
01294
01295     if(rootNode != NULL)
01296     {
01297         NodeUnrecPtr  childClone;
01298         NodeCore     *core       = rootNode->getCore();
01299
01300         rootClone = Node::create();
01301         rootClone->setTravMask(rootNode->getTravMask());
01302
01303         deepCloneAttachments(rootNode,      rootClone,
01304                              shareTypes,    ignoreTypes,
01305                              shareGroupIds, ignoreGroupIds);
01306
01307         if(core != NULL)
01308         {
01309                   NodeCoreUnrecPtr    coreClone(NULL);
01310             const FieldContainerType &coreType   = core->getType();
01311
01312             // test if core type should NOT be ignored
01313             if(!TypePredicates::typeInGroupIds (
01314                     ignoreGroupIds.begin(),
01315                     ignoreGroupIds.end(), coreType) &&
01316                !TypePredicates::typeDerivedFrom(
01317                     ignoreTypes.begin(),
01318                     ignoreTypes.end(),    coreType)   )
01319             {
01320                 // test if core should be shared
01321                 if(TypePredicates::typeInGroupIds (
01322                        shareGroupIds.begin(),
01323                        shareGroupIds.end(), coreType) ||
01324                    TypePredicates::typeDerivedFrom(
01325                        shareTypes.begin(),
01326                        shareTypes.end(),    coreType)   )
01327                 {
01328                     // share core
01329                     coreClone = core;
01330                 }
01331                 else
01332                 {
01333                     // clone core
01334                     coreClone =
01335                         dynamic_pointer_cast<NodeCore>(
01336                             deepClone(core,
01337                                       shareTypes,    ignoreTypes,
01338                                       shareGroupIds, ignoreGroupIds));
01339                 }
01340             }
01341
01342             rootClone->setCore(coreClone);
01343         }
01344
01345         for(UInt32 i = 0; i < rootNode->getNChildren(); ++i)
01346         {
01347             childClone = deepCloneTree(rootNode->getChild(i),
01348                                        shareTypes,    ignoreTypes,
01349                                        shareGroupIds, ignoreGroupIds);
01350
01351             rootClone->addChild(childClone);
01352         }
01353     }
01354
01355     return NodeTransitPtr(rootClone);
01356 }
01357
01359 /*---------------------------------------------------------------------*/
01360
01361 OSG_END_NAMESPACE