Show
Ignore:
Timestamp:
01/24/08 15:11:54 (1 year ago)
Author:
cneumann
Message:

fixed: aspect sync for child/parent fields

missing editSField/editMField calls

added: simple test program for MT

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/Carsten_PtrWork2/Source/System/FieldContainer/Node/OSGNode.cpp

    r1034 r1041  
    5858OSG_BEGIN_NAMESPACE 
    5959 
     60/***************************************************************************\ 
     61 *                            Description                                  * 
     62\***************************************************************************/ 
     63 
     64/*! \class OSG::Node 
     65    Node describe the hierarchical tree structure of the scenegraph. Every Node 
     66    can have at most one parent and one core (something derived from NodeCore), but 
     67    an arbitrary number of children. 
     68 */ 
     69 
     70/***************************************************************************\ 
     71 *                         Field Description                               * 
     72\***************************************************************************/ 
     73 
     74/*! \var DynamicVolume   Node::_sfVolume 
     75    The bounding volume of this node. It contains all the nodes children and 
     76    is described in this nodes coordinate system. 
     77*/ 
     78 
     79/*! \var UInt32          Node::_sfTravMask 
     80    The traversal mask is used to selectively exclude subtrees of the scenegraph 
     81    from traversal operations (e.g. GraphOps, RenderAction). Only if 
     82    the bitwise AND of the operation's and node's mask is non-zero the node 
     83    (and it's subtree) considered. 
     84*/ 
     85 
     86/*! \var NodeParentPtr   Node::_sfParent 
     87    The node's single parent. 
     88*/ 
     89 
     90/*! \var NodePtr         Node::_mfChildren 
     91    The node's children. 
     92*/ 
     93 
     94/*! \var NodeCorePtr     Node::_sfCore 
     95     
     96*/ 
     97 
     98     
     99void Node::classDescInserter(TypeObject &oType) 
     100{ 
     101    FieldDescriptionBase *pDesc = NULL; 
     102 
     103    pDesc = new SFDynamicVolume::Description( 
     104        SFDynamicVolume::getClassType(), 
     105        "Volume", 
     106        "The bounding volume of this node. It contains all the nodes children and\n" 
     107        "is described in this nodes coordinate system.\n", 
     108        VolumeFieldId, 
     109        VolumeFieldMask, 
     110        false, 
     111        Field::SFDefaultFlags, 
     112        static_cast<FieldEditMethodSig>(&Node::editHandleVolume), 
     113        static_cast<FieldGetMethodSig >(&Node::getHandleVolume ) ); 
     114         
     115        oType.addInitialDesc(pDesc); 
     116         
     117         
     118    pDesc = new SFUInt32::Description( 
     119        SFUInt32::getClassType(), 
     120        "TravMask", 
     121        "The traversal mask is used to selectively exclude subtrees of the scenegraph\n" 
     122        "from traversal operations (e.g. GraphOps, RenderAction). Only if\n" 
     123        "the bitwise AND of the operation's and node's mask is non-zero the node\n" 
     124        "(and it's subtree) considered.\n", 
     125        TravMaskFieldId, 
     126        TravMaskFieldMask, 
     127        false, 
     128        Field::SFDefaultFlags, 
     129        static_cast<FieldEditMethodSig>(&Node::editHandleTravMask), 
     130        static_cast<FieldGetMethodSig >(&Node::getHandleTravMask ) ); 
     131         
     132        oType.addInitialDesc(pDesc); 
     133         
     134         
     135    pDesc = new SFNodeParentPtr::Description( 
     136        SFNodeParentPtr::getClassType(), 
     137        "Parent", 
     138        "The node's single parent.\n", 
     139        ParentFieldId, 
     140        ParentFieldMask, 
     141        false, 
     142        Field::SFDefaultFlags, 
     143        static_cast<FieldEditMethodSig>(&Node::invalidEditField), 
     144        static_cast<FieldGetMethodSig >(&Node::invalidGetField ) ); 
     145         
     146        oType.addInitialDesc(pDesc); 
     147         
     148         
     149    pDesc = new MFNodeChildPtr::Description( 
     150        MFNodeChildPtr::getClassType(), 
     151        "Children", 
     152        "The node's children.\n", 
     153        ChildrenFieldId, 
     154        ChildrenFieldMask, 
     155        MFNodeChildPtr::Object::ParentFieldId, 
     156        false, 
     157        Field::MFDefaultFlags, 
     158        static_cast<FieldEditMethodSig>(&Node::editHandleChildren), 
     159        static_cast<FieldGetMethodSig >(&Node::getHandleChildren ) ); 
     160         
     161        oType.addInitialDesc(pDesc); 
     162         
     163         
     164    pDesc = new SFNodeCoreChildPtr::Description( 
     165        SFNodeCoreChildPtr::getClassType(), 
     166        "Core", 
     167        "", 
     168        CoreFieldId, 
     169        CoreFieldMask, 
     170        SFNodeCoreChildPtr::Object::ParentsFieldId, 
     171        false, 
     172        Field::SFDefaultFlags, 
     173        static_cast<FieldEditMethodSig>(&Node::editHandleCore), 
     174        static_cast<FieldGetMethodSig >(&Node::getHandleCore ) ); 
     175         
     176        oType.addInitialDesc(pDesc); 
     177         
     178         
     179} 
     180 
     181Node::TypeObject Node::_type( 
     182    Node::getClassname(), 
     183    Inherited::getClassname(), 
     184    "Node", 
     185    0, 
     186    (PrototypeCreateF) &Node::createEmpty, 
     187    Node::initMethod, 
     188    (InitalInsertDescFunc) &Node::classDescInserter, 
     189    false, 
     190    0, 
     191    "<?xml version=\"1.0\" ?>\n" 
     192    "\n" 
     193    "<FieldContainer\n" 
     194    "    name=\"Node\"\n" 
     195    "    parent=\"AttachmentContainer\"\n" 
     196    "    library=\"System\"\n" 
     197    "    structure=\"concrete\"\n" 
     198    "    pointerfieldtypes=\"both\"\n" 
     199    "    systemcomponent=\"true\"\n" 
     200    "    parentsystemcomponent=\"true\"\n" 
     201    "    isNodeCore=\"false\"\n" 
     202    ">\n" 
     203    "Node describe the hierarchical tree structure of the scenegraph. Every Node\n" 
     204    "can have at most one parent and one core (something derived from NodeCore), but\n" 
     205    "an arbitrary number of children.\n" 
     206    "    <Field\n" 
     207    "        name=\"Volume\"\n" 
     208    "        category=\"data\"\n" 
     209    "        type=\"DynamicVolume\"\n" 
     210    "        cardinality=\"single\"\n" 
     211    "        visibility=\"external\"\n" 
     212    "    >\n" 
     213    "    The bounding volume of this node. It contains all the nodes children and\n" 
     214    "    is described in this nodes coordinate system.\n" 
     215    "    </Field>\n" 
     216    "    <Field\n" 
     217    "        name=\"TravMask\"\n" 
     218    "        category=\"data\"\n" 
     219    "        type=\"UInt32\"\n" 
     220    "        cardinality=\"single\"\n" 
     221    "        visibility=\"external\"\n" 
     222    "        defaultValue=\"TypeTraits&lt;UInt32&gt;::getMax()\"\n" 
     223    "    >\n" 
     224    "    The traversal mask is used to selectively exclude subtrees of the scenegraph\n" 
     225    "    from traversal operations (e.g. GraphOps, RenderAction). Only if\n" 
     226    "    the bitwise AND of the operation's and node's mask is non-zero the node\n" 
     227    "    (and it's subtree) considered.\n" 
     228    "    </Field>\n" 
     229    "    <Field\n" 
     230    "        name=\"Parent\"\n" 
     231    "        category=\"parentpointer\"\n" 
     232    "        type=\"Node\"\n" 
     233    "        cardinality=\"single\"\n" 
     234    "        visibility=\"external\"\n" 
     235    "    >\n" 
     236    "    The node's single parent.\n" 
     237    "    </Field>\n" 
     238    "    <Field\n" 
     239    "        name=\"Children\"\n" 
     240    "        category=\"childpointer\"\n" 
     241    "        type=\"Node\"\n" 
     242    "\tparentLinkField=\"Parent\"\n" 
     243    "        cardinality=\"multi\"\n" 
     244    "        visibility=\"external\"\n" 
     245    "    >\n" 
     246    "    The node's children.\n" 
     247    "    </Field>\n" 
     248    "    <Field\n" 
     249    "        name=\"Core\"\n" 
     250    "        category=\"childpointer\"\n" 
     251    "        type=\"NodeCore\"\n" 
     252    "\tparentLinkField=\"Parents\"\n" 
     253    "        cardinality=\"single\"\n" 
     254    "        visibility=\"external\"\n" 
     255    "    >\n" 
     256    "    </Field>\n" 
     257    "</FieldContainer>\n", 
     258    "Node describe the hierarchical tree structure of the scenegraph. Every Node\n" 
     259    "can have at most one parent and one core (something derived from NodeCore), but\n" 
     260    "an arbitrary number of children.\n" 
     261    ); 
     262     
     263/*------------------------------ get -----------------------------------*/ 
     264 
     265FieldContainerType & 
     266Node::getType(void) 
     267{ 
     268    return _type; 
     269} 
     270 
     271FieldContainerType const & 
     272Node::getType(void) const 
     273{ 
     274    return _type; 
     275} 
     276 
     277UInt32 
     278Node::getContainerSize(void) const 
     279{ 
     280    return sizeof(Node); 
     281} 
     282 
     283/*-------------------------------------------------------------------------*/ 
     284/* Field SFVolume                                                          */ 
     285 
     286void Node::getWorldVolume(DynamicVolume &result) 
     287{ 
     288    Matrixr m; 
     289 
     290    if(getParent() != NullFC) 
     291    { 
     292        getParent()->getToWorld(m); 
     293    } 
     294    else 
     295    { 
     296        m.setIdentity(); 
     297    } 
     298 
     299    updateVolume(); 
     300 
     301    result = getVolume(); 
     302    result.transform(m); 
     303} 
     304 
     305void Node::updateVolume(void) 
     306{ 
     307    // still valid, nothing to do 
     308    if(_sfVolume.getValue().getInstance().isValid() == true || 
     309       getTravMask()                                == 0x0000) 
     310    { 
     311        return; 
     312    } 
     313 
     314    // be careful to not change the real volume. If two threads 
     315    // are updating the same aspect this will lead to chaos 
     316 
     317    DynamicVolume vol = _sfVolume.getValue(); 
     318 
     319    ChildrenFieldType::iterator it; 
     320 
     321    vol.getInstance().setEmpty(); 
     322 
     323    for(it = _mfChildren.begin(); it != _mfChildren.end(); ++it) 
     324    { 
     325        if((*it)->getTravMask()) 
     326        { 
     327            (*it)->updateVolume(); 
     328            vol.getInstance().extendBy((*it)->getVolume()); 
     329        } 
     330    } 
     331 
     332    // test for null core. Shouldn't happen, but just in case... 
     333    if(getCore() != NullFC) 
     334    { 
     335        getCore()->adjustVolume(vol.getInstance()); 
     336    } 
     337 
     338    editSField(VolumeFieldMask); 
     339 
     340    vol.instanceChanged(); 
     341 
     342    _sfVolume.setValue(vol); 
     343} 
     344 
     345void Node::invalidateVolume(void) 
     346{ 
     347    Volume &vol=_sfVolume.getValue().getInstance(); 
     348 
     349    if(vol.isValid() == true && vol.isStatic() == false) 
     350    { 
     351        editSField(VolumeFieldMask); 
     352 
     353        vol.setValid(false); 
     354 
     355        _sfVolume.getValue().instanceChanged(); 
     356 
     357        if(getParent() != NullFC) 
     358        { 
     359            getParent()->invalidateVolume(); 
     360        } 
     361    } 
     362} 
     363 
     364/*-------------------------------------------------------------------------*/ 
     365/* Field MFChildren                                                        */ 
     366 
     367void 
     368Node::addChildren(MFNodeChildPtr::ArgumentType value) 
     369{ 
     370    if(value == NullFC) 
     371        return; 
     372 
     373    editMField(ChildrenFieldMask, _mfChildren); 
     374 
     375    _mfChildren.push_back(value); 
     376} 
     377 
     378void 
     379Node::assignChildren(MFNodeChildPtr const &value) 
     380{ 
     381    editMField(ChildrenFieldMask, _mfChildren); 
     382 
     383    _mfChildren.setValues(value); 
     384} 
     385 
     386void 
     387Node::insertChildren( 
     388    UInt32 const uiIndex, 
     389    MFNodeChildPtr::ArgumentType value) 
     390{ 
     391    if(value == NullFC) 
     392        return; 
     393 
     394    editMField(ChildrenFieldMask, _mfChildren); 
     395 
     396    ChildrenFieldType::iterator fieldIt = _mfChildren.begin(); 
     397 
     398    fieldIt += uiIndex; 
     399 
     400    _mfChildren.insert(fieldIt, value); 
     401} 
     402 
     403void 
     404Node::replaceChildren( 
     405    UInt32 const uiIndex, 
     406    MFNodeChildPtr::ArgumentType value) 
     407{ 
     408    if(value == NullFC) 
     409        return; 
     410 
     411    if(uiIndex >= _mfChildren.size()) 
     412        return; 
     413 
     414    editMField(ChildrenFieldMask, _mfChildren); 
     415 
     416    _mfChildren[uiIndex] = value; 
     417} 
     418 
     419bool 
     420Node::replaceChildren( 
     421    MFNodeChildPtr::ArgumentType pOldElem, 
     422    MFNodeChildPtr::ArgumentType pNewElem ) 
     423{ 
     424    bool retVal = false; 
     425 
     426    if(pNewElem == NullFC) 
     427        return retVal; 
     428 
     429    ChildrenFieldType::iterator fieldIt = 
     430        _mfChildren.find(pOldElem); 
     431     
     432    if(fieldIt != _mfChildren.end()) 
     433    { 
     434        retVal = true; 
     435     
     436        editMField(ChildrenFieldMask, _mfChildren); 
     437         
     438        (*fieldIt) = NodePtr(pNewElem); 
     439    } 
     440     
     441    return retVal; 
     442} 
     443 
     444void 
     445Node::subChildren(UInt32 const uiIndex) 
     446{ 
     447    if(uiIndex < _mfChildren.size()) 
     448    { 
     449        editMField(ChildrenFieldMask, _mfChildren); 
     450 
     451        ChildrenFieldType::iterator fieldIt = _mfChildren.begin(); 
     452 
     453        fieldIt += uiIndex; 
     454 
     455        _mfChildren.erase(fieldIt); 
     456    } 
     457} 
     458 
     459bool 
     460Node::subChildren( 
     461    MFNodeChildPtr::ArgumentType value) 
     462{ 
     463    bool retVal = false; 
     464    ChildrenFieldType::iterator fieldIt = 
     465        _mfChildren.find(value); 
     466         
     467    if(fieldIt != _mfChildren.end()) 
     468    { 
     469        retVal = true; 
     470     
     471        editMField(ChildrenFieldMask, _mfChildren); 
     472         
     473        _mfChildren.erase(fieldIt); 
     474    } 
     475     
     476    return retVal; 
     477} 
     478 
     479void 
     480Node::clearChildren(void) 
     481{ 
     482    editMField(ChildrenFieldMask, _mfChildren); 
     483 
     484 
     485    _mfChildren.clear(); 
     486} 
     487 
     488UInt32 Node::getNChildren(void) const 
     489{ 
     490    return _mfChildren.size(); 
     491} 
     492 
     493void Node::addChild(NodePtrConstArg childP) 
     494{ 
     495    addChildren(childP); 
     496} 
     497 
     498void Node::insertChild(UInt32 childIndex, NodePtrConstArg childP) 
     499{ 
     500    insertChildren(childIndex, childP); 
     501} 
     502 
     503void Node::replaceChild(UInt32 childIndex, NodePtrConstArg childP) 
     504{ 
     505    replaceChild(childIndex, childP); 
     506} 
     507 
     508bool Node::replaceChildBy(NodePtrConstArg childP, NodePtrConstArg newChildP) 
     509{ 
     510    return replaceChildren(childP, newChildP); 
     511} 
     512 
     513Int32 Node::findChild(NodePtrConstArg childP) const 
     514{ 
     515    return _mfChildren.findIndex(childP); 
     516} 
     517 
     518bool Node::subChild(NodePtrConstArg childP) 
     519{ 
     520    return subChildren(childP); 
     521} 
     522 
     523void Node::subChild(UInt32 childIndex) 
     524{ 
     525    subChildren(childIndex); 
     526} 
     527 
     528NodePtr Node::getChild(UInt32 childIndex) const 
     529{ 
     530    return _mfChildren[childIndex]; 
     531} 
     532 
     533/*-------------------------------------------------------------------------*/ 
     534/* Transformation Access                                                   */ 
     535 
     536Matrixr Node::getToWorld(void) 
     537{ 
     538    Matrixr tmp; 
     539 
     540    getToWorld(tmp); 
     541 
     542    return tmp; 
     543} 
     544 
     545void Node::getToWorld(Matrixr &result) 
     546{ 
     547    if(getParent() != NullFC) 
     548    { 
     549        getParent()->getToWorld(result); 
     550    } 
     551    else 
     552    { 
     553        result.setIdentity(); 
     554    } 
     555 
     556    if(getCore() != NullFC) 
     557        getCore()->accumulateMatrix(result); 
     558} 
     559 
     560/*-------------------------------------------------------------------------*/ 
     561/* Changed                                                                 */ 
     562 
     563void Node::changed(ConstFieldMaskArg whichField, 
     564                   UInt32            origin, 
     565                   BitVector         details    ) 
     566{ 
     567    Inherited::changed(whichField, origin, details); 
     568 
     569    if(whichField & (CoreFieldMask | ChildrenFieldMask)) 
     570    { 
     571        invalidateVolume(); 
     572    } 
     573 
     574    if(whichField & TravMaskFieldMask) 
     575    { 
     576        if(getParent() != NullFC) 
     577        { 
     578            getParent()->invalidateVolume(); 
     579        } 
     580        else 
     581        { 
     582            invalidateVolume(); 
     583        } 
     584    } 
     585} 
     586 
     587/*-------------------------------------------------------------------------*/ 
     588/* Dump                                                                    */ 
     589 
     590void Node::dump(      UInt32    uiIndent, 
     591                const BitVector bvFlags ) const 
     592{ 
     593    UInt32 i; 
     594 
     595    indentLog(uiIndent, PLOG); 
     596 
     597    PLOG << "Node" 
     598         << "(" 
     599         << getContainerId(this) 
     600         << ") : " 
     601         << _mfChildren.size() 
     602         << " children | " 
     603//         << _attachmentMap.getValue().size() 
     604         << " attachments | " 
     605         << "Parent : " << std::hex; 
     606 
     607    if(_sfParent.getValue() != NullFC) 
     608    { 
     609        PLOG << getContainerId(_sfParent.getValue()) << " | "; 
     610    } 
     611    else 
     612    { 
     613        PLOG << "NULL | "; 
     614    } 
     615 
     616    PLOG << this << std::dec << std::endl; 
     617 
     618    indentLog(uiIndent, PLOG); 
     619 
     620    PLOG << "[" << std::endl; 
     621 
     622    if(_sfCore.getValue() != NullFC) 
     623    { 
     624        _sfCore.getValue()->dump(uiIndent + 4, bvFlags); 
     625    } 
     626    else 
     627    { 
     628        indentLog(uiIndent + 4, PLOG); 
     629        PLOG << "Core : " << "NULL" << std::endl; 
     630    } 
     631 
     632    Inherited::dump(uiIndent + 4, bvFlags); 
     633 
     634    indentLog(uiIndent, PLOG); 
     635    PLOG << "]" << std::endl; 
     636 
     637    indentLog(uiIndent, PLOG); 
     638 
     639    PLOG << "{" << std::endl; 
     640 
     641    for(i = 0; i < _mfChildren.size(); i++) 
     642    { 
     643        _mfChildren[i]->dump(uiIndent + 4, bvFlags); 
     644        PLOG << std::endl; 
     645    } 
     646 
     647 
     648    indentLog(uiIndent, PLOG); 
     649 
     650    PLOG << "}" << std::endl; 
     651} 
     652 
     653/*------------------------------ access -----------------------------------*/ 
     654 
     655UInt32 Node::getBinSize(ConstFieldMaskArg whichField) 
     656{ 
     657    UInt32 returnValue = Inherited::getBinSize(whichField); 
     658 
     659    if(FieldBits::NoField != (VolumeFieldMask & whichField)) 
     660    { 
     661        returnValue += _sfVolume.getBinSize(); 
     662    } 
     663    if(FieldBits::NoField != (TravMaskFieldMask & whichField)) 
     664    { 
     665        returnValue += _sfTravMask.getBinSize(); 
     666    } 
     667    if(FieldBits::NoField != (ParentFieldMask & whichField)) 
     668    { 
     669        returnValue += _sfParent.getBinSize(); 
     670    } 
     671    if(FieldBits::NoField != (ChildrenFieldMask & whichField)) 
     672    { 
     673        returnValue += _mfChildren.getBinSize(); 
     674    } 
     675    if(FieldBits::NoField != (CoreFieldMask & whichField)) 
     676    { 
     677        returnValue += _sfCore.getBinSize(); 
     678    } 
     679 
     680    return returnValue; 
     681} 
     682 
     683void Node::copyToBin(BinaryDataHandler &pMem, 
     684                                  ConstFieldMaskArg  whichField) 
     685{ 
     686    Inherited::copyToBin(pMem, whichField); 
     687 
     688    if(FieldBits::NoField != (VolumeFieldMask & whichField)) 
     689    { 
     690        _sfVolume.copyToBin(pMem); 
     691    } 
     692    if(FieldBits::NoField != (TravMaskFieldMask & whichField)) 
     693    { 
     694        _sfTravMask.copyToBin(pMem); 
     695    } 
     696    if(FieldBits::NoField != (ParentFieldMask & whichField)) 
     697    { 
     698        _sfParent.copyToBin(pMem); 
     699    } 
     700    if(FieldBits::NoField != (ChildrenFieldMask & whichField)) 
     701    { 
     702        _mfChildren.copyToBin(pMem); 
     703    } 
     704    if(FieldBits::NoField != (CoreFieldMask & whichField)) 
     705    { 
     706        _sfCore.copyToBin(pMem); 
     707    } 
     708} 
     709 
     710void Node::copyFromBin(BinaryDataHandler &pMem, 
     711                                    ConstFieldMaskArg  whichField) 
     712{ 
     713    Inherited::copyFromBin(pMem, whichField); 
     714 
     715    if(FieldBits::NoField != (VolumeFieldMask & whichField)) 
     716    { 
     717        _sfVolume.copyFromBin(pMem); 
     718    } 
     719    if(FieldBits::NoField != (TravMaskFieldMask & whichField)) 
     720    { 
     721        _sfTravMask.copyFromBin(pMem); 
     722    } 
     723    if(FieldBits::NoField != (ParentFieldMask & whichField)) 
     724    { 
     725        _sfParent.copyFromBin(pMem); 
     726    } 
     727    if(FieldBits::NoField != (ChildrenFieldMask & whichField)) 
     728    { 
     729        _mfChildren.copyFromBin(pMem); 
     730    } 
     731    if(FieldBits::NoField != (CoreFieldMask & whichField)) 
     732    { 
     733        _sfCore.copyFromBin(pMem); 
     734    } 
     735} 
     736 
     737/*-------------------------------------------------------------------------*/ 
     738/* Parent linking                                                          */ 
     739 
     740bool 
     741Node::linkParent( 
     742    ReflexiveContainer * const pParent, 
     743    UInt16               const childrenFieldId, 
     744    UInt16               const parentFieldId   ) 
     745{ 
     746    bool retVal = Inherited::linkParent( 
     747        pParent, childrenFieldId, parentFieldId); 
     748 
     749    if(parentFieldId == ParentFieldId) 
     750    { 
     751        FINFO(("Node::linkParent: this [%p] [%u] pParent [%p] [%u]\n", 
     752               this, getContainerId(this), pParent, pParent != NULL ? getContainerId(pParent) : 0)); 
     753     
     754        NodeParentPtr pTypedParent( 
     755            dynamic_cast< SFNodeParentPtr::Object * >(pParent), 
     756            childrenFieldId); 
     757                 
     758        if(pTypedParent.getPointer() != NullFC) 
     759        { 
     760            if(_sfParent.getValue().getPointer() != NullFC) 
     761            { 
     762                _sfParent.getValue().getPointer()->unlinkChild( 
     763                    this, _sfParent.getValue().getChildrenFieldId()); 
     764            } 
     765             
     766            editSField(ParentFieldMask); 
     767            _sfParent.setValue(pTypedParent); 
     768        } 
     769        else 
     770        { 
     771            retVal = false; 
     772        } 
     773    } 
     774     
     775    return retVal; 
     776} 
     777     
     778bool 
     779Node::unlinkParent( 
     780    ReflexiveContainer * const pParent, 
     781    UInt16               const childrenFieldId, 
     782    UInt16               const parentFieldId   ) 
     783{ 
     784    bool retVal = Inherited::unlinkParent( 
     785        pParent, childrenFieldId, parentFieldId); 
     786 
     787    if(parentFieldId == ParentFieldId) 
     788    { 
     789        FINFO(("Node::unlinkParent: this [%p] [%u] pParent [%p] [%u]\n", 
     790               this, getContainerId(this), pParent, pParent != NULL ? getContainerId(pParent) : 0)); 
     791     
     792        NodeParentPtr pTypedParent( 
     793            dynamic_cast< SFNodeParentPtr::Object * >(pParent), 
     794            childrenFieldId); 
     795             
     796        if(pTypedParent.getPointer() != NullFC) 
     797        {             
     798            editSField(ParentFieldMask); 
     799            _sfParent.setValue(NodeParentPtr(NullFC, 0xFFFF)); 
     800        } 
     801        else 
     802        { 
     803            retVal = false; 
     804        } 
     805    } 
     806     
     807     
     808    return retVal; 
     809} 
     810 
     811/*-------------------------------------------------------------------------*/ 
     812/* Child linking                                                           */ 
     813 
     814bool 
     815Node::unlinkChild( 
     816    ReflexiveContainer * const pChild, 
     817    UInt16               const childrenFieldId) 
     818{ 
     819    bool retVal = Inherited::unlinkChild(pChild, childrenFieldId); 
     820     
     821    if(childrenFieldId == ChildrenFieldId) 
     822    { 
     823        FINFO(("Node::unlinkChild: this [%p] [%u] pChild [%p] [%u]\n", 
     824               this, getContainerId(this), pChild, pChild != NULL ? getContainerId(pChild) : 0)); 
     825     
     826        NodePtr pTypedChild( 
     827            dynamic_cast< MFNodeChildPtr::ValueType >(pChild)); 
     828             
     829        if(pTypedChild != NullFC) 
     830        { 
     831            MFNodeChildPtr::iterator pI = 
     832                _mfChildren.find(pTypedChild); 
     833                 
     834            if(pI != _mfChildren.end()) 
     835                editChildren().erase(pI); 
     836        } 
     837        else 
     838        { 
     839            retVal = false; 
     840        } 
     841    } 
     842         
     843    if(childrenFieldId == CoreFieldId) 
     844    { 
     845        NodeCorePtr pTypedChild( 
     846            dynamic_cast< SFNodeCoreChildPtr::ValueType >(pChild)); 
     847             
     848        if(pTypedChild != NullFC) 
     849        { 
     850            editCore() = NullFC; 
     851        } 
     852        else 
     853        { 
     854            retVal = false; 
     855        } 
     856    } 
     857         
     858     
     859    return retVal; 
     860} 
     861 
     862//! create a new instance of the class 
     863Node::ObjTransitPtr 
     864Node::create(void) 
     865{ 
     866    ObjTransitPtr pFC; 
     867 
     868    if(getClassType().getPrototype() != NullFC) 
     869    { 
     870        pFC = boost::dynamic_pointer_cast< Node >( 
     871            getClassType().getPrototype()->shallowCopy()); 
     872    } 
     873 
     874    return pFC; 
     875} 
     876 
     877//! create an empty new instance of the class, do not copy the prototype 
     878NodePtr Node::createEmpty(void) 
     879{ 
     880    NodePtr returnValue; 
     881 
     882    newPtr<Node>(returnValue); 
     883 
     884    return returnValue; 
     885} 
     886 
     887FieldContainerTransitPtr 
     888Node::shallowCopy(void) const 
     889{ 
     890    ObjPtr returnValue; 
     891 
     892    newPtr(returnValue, dynamic_cast<const Node *>(this)); 
     893 
     894    return FieldContainerTransitPtr(returnValue); 
     895} 
     896 
     897/*------------------------- constructors ----------------------------------*/ 
     898 
     899Node::Node(void) : 
     900    Inherited  (), 
     901    _sfVolume  (), 
     902    _sfTravMask(UInt32(TypeTraits<UInt32>::getMax())), 
     903    _sfParent  (NodeParentPtr(NullFC)), 
     904    _mfChildren(), 
     905    _sfCore    (NodeCorePtr(NullFC)) 
     906{ 
     907    _mfChildren.setEnclosingFC(this); 
     908    _mfChildren.setFieldDescription( 
     909        dynamic_cast<MFNodeChildPtr::Description *>( 
     910            getClassType().getFieldDesc(ChildrenFieldId))); 
     911             
     912    _sfCore.setEnclosingFC(this); 
     913    _sfCore.setFieldDescription( 
     914        dynamic_cast<SFNodeCoreChildPtr::Description *>( 
     915            getClassType().getFieldDesc(CoreFieldId))); 
     916             
     917} 
     918 
     919Node::Node(const Node &source) : 
     920    Inherited  (source), 
     921    _sfVolume  (source._sfVolume                ), 
     922    _sfTravMask(source._sfTravMask              ), 
     923    _sfParent  (NodeParentPtr()), 
     924    _mfChildren(), 
     925    _sfCore    (NodeCorePtr()) 
     926{ 
     927    _mfChildren.setEnclosingFC(this); 
     928    _mfChildren.setFieldDescription( 
     929        dynamic_cast<MFNodeChildPtr::Description *>( 
     930            getClassType().getFieldDesc(ChildrenFieldId))); 
     931             
     932    _sfCore.setEnclosingFC(this); 
     933    _sfCore.setFieldDescription( 
     934        dynamic_cast<SFNodeCoreChildPtr::Description *>( 
     935            getClassType().getFieldDesc(CoreFieldId))); 
     936             
     937} 
     938 
     939 
     940/*-------------------------- destructors ----------------------------------*/ 
     941 
     942Node::~Node(void) 
     943{ 
     944} 
     945 
     946void Node::onCreate(const Node *source) 
     947{ 
     948    Inherited::onCreate(source); 
     949 
     950    if(source != NULL) 
     951    { 
     952        ChildrenFieldType::const_iterator ChildrenIt  = 
     953            source->_mfChildren.begin(); 
     954        ChildrenFieldType::const_iterator ChildrenEnd = 
     955            source->_mfChildren.end  (); 
     956 
     957        while(ChildrenIt != ChildrenEnd) 
     958        { 
     959            this->addChildren(*ChildrenIt); 
     960 
     961            ++ChildrenIt; 
     962        } 
     963         
     964        this->setCore(source->getCore()); 
     965         
     966    } 
     967} 
     968 
     969GetFieldHandlePtr Node::getHandleVolume(void) const 
     970{ 
     971    SFDynamicVolume::GetHandlePtr returnValue( 
     972        new  SFDynamicVolume::GetHandle( 
     973             &_sfVolume,  
     974             this->getType().getFieldDesc(VolumeFieldId))); 
     975 
     976    return returnValue; 
     977} 
     978 
     979EditFieldHandlePtr Node::editHandleVolume(void) 
     980{ 
     981    SFDynamicVolume::EditHandlePtr returnValue( 
     982        new  SFDynamicVolume::EditHandle( 
     983             &_sfVolume,  
     984             this->getType().getFieldDesc(VolumeFieldId))); 
     985 
     986    editSField(VolumeFieldMask); 
     987 
     988    return returnValue; 
     989} 
     990 
     991GetFieldHandlePtr Node::getHandleTravMask(void) const 
     992{ 
     993    SFUInt32::GetHandlePtr returnValue( 
     994        new  SFUInt32::GetHandle( 
     995             &_sfTravMask,  
     996             this->getType().getFieldDesc(TravMaskFieldId))); 
     997 
     998    return returnValue; 
     999} 
     1000 
     1001EditFieldHandlePtr Node::editHandleTravMask(void) 
     1002{ 
     1003    SFUInt32::EditHandlePtr returnValue( 
     1004        new  SFUInt32::EditHandle( 
     1005             &_sfTravMask,  
     1006             this->getType().getFieldDesc(TravMaskFieldId))); 
     1007 
     1008    editSField(TravMaskFieldMask); 
     1009 
     1010    return returnValue; 
     1011} 
     1012 
     1013GetFieldHandlePtr Node::getHandleParent(void) const 
     1014{ 
     1015    SFNodeParentPtr::GetHandlePtr returnValue( 
     1016        new  SFNodeParentPtr::GetHandle( 
     1017             &_sfParent,  
     1018             this->getType().getFieldDesc(ParentFieldId))); 
     1019 
     1020    return returnValue; 
     1021} 
     1022 
     1023 
     1024GetFieldHandlePtr Node::getHandleChildren(void) const 
     1025{ 
     1026    MFNodeChildPtr::GetHandlePtr returnValue( 
     1027        new  MFNodeChildPtr::GetHandle( 
     1028             &_mfChildren,  
     1029             this->getType().getFieldDesc(ChildrenFieldId))); 
     1030 
     1031    return returnValue; 
     1032} 
     1033 
     1034EditFieldHandlePtr Node::editHandleChildren(void) 
     1035{ 
     1036    MFNodeChildPtr::EditHandlePtr returnValue( 
     1037        new  MFNodeChildPtr::EditHandle( 
     1038             &_mfChildren,  
     1039             this->getType().getFieldDesc(ChildrenFieldId))); 
     1040    returnValue->setAddFunc( 
     1041        boost::bind( 
     1042            &Node::addChildren, 
     1043            static_cast<Node *>(this), _1)); 
     1044    returnValue->setInsertFunc( 
     1045        boost::bind( 
     1046            &Node::insertChildren, 
     1047            static_cast<Node *>(this), _1, _2)); 
     1048             
     1049    void (Node::*replaceChildrenIndexFunc)( 
     1050        UInt32 const, 
     1051        MFNodeChildPtr::ArgumentType) = 
     1052            &Node::replaceChildren; 
     1053    returnValue->setReplaceIndexFunc( 
     1054        boost::bind( 
     1055            replaceChildrenIndexFunc, 
     1056            static_cast<Node *>(this), _1, _2)); 
     1057             
     1058    bool (Node::*replaceChildrenObjectFunc)( 
     1059        MFNodeChildPtr::ArgumentType, 
     1060        MFNodeChildPtr::ArgumentType ) = 
     1061            &Node::replaceChildren; 
     1062    returnValue->setReplaceObjectFunc( 
     1063        boost::bind( 
     1064            replaceChildrenObjectFunc, 
     1065            static_cast<Node *>(this), _1, _2)); 
     1066             
     1067    void (Node::*subChildrenIndexFunc)(UInt32 const) = 
     1068        &Node::subChildren; 
     1069    returnValue->setSubIndexFunc( 
     1070        boost::bind( 
     1071            subChildrenIndexFunc, 
     1072            static_cast<Node *>(this), _1)); 
     1073             
     1074    bool (Node::*subChildrenObjectFunc)( 
     1075        MFNodeChildPtr::ArgumentType) = 
     1076            &Node::subChildren; 
     1077    returnValue->setSubObjectFunc( 
     1078        boost::bind( 
     1079            subChildrenObjectFunc, 
     1080            static_cast<Node *>(this), _1)); 
     1081    returnValue->setClearFunc( 
     1082        boost::bind( 
     1083            &Node::clearChildren, 
     1084            static_cast<Node *>(this))); 
     1085 
     1086    editMField(ChildrenFieldMask, _mfChildren); 
     1087 
     1088    return returnValue; 
     1089} 
     1090 
     1091GetFieldHandlePtr Node::getHandleCore(void) const 
     1092{ 
     1093    SFNodeCoreChildPtr::GetHandlePtr returnValue( 
     1094        new  SFNodeCoreChildPtr::GetHandle( 
     1095             &_sfCore,  
     1096             this->getType().getFieldDesc(CoreFieldId))); 
     1097 
     1098    return returnValue; 
     1099} 
     1100 
     1101EditFieldHandlePtr Node::editHandleCore(void) 
     1102{ 
     1103    SFNodeCoreChildPtr::EditHandlePtr returnValue( 
     1104        new  SFNodeCoreChildPtr::EditHandle( 
     1105             &_sfCore,  
     1106             this->getType().getFieldDesc(CoreFieldId))); 
     1107 
     1108    returnValue->setSetFunc( 
     1109        boost::bind( 
     1110            &Node::setCore, 
     1111            static_cast<Node *>(this), _1)); 
     1112 
     1113    editSField(CoreFieldMask); 
     1114 
     1115    return returnValue; 
     1116} 
     1117 
     1118 
     1119#ifdef OSG_MT_CPTR_ASPECT 
     1120void Node::execSyncV(      FieldContainer    &oFrom, 
     1121                                        ConstFieldMaskArg  whichField, 
     1122                                        AspectOffsetStore &oOffsets, 
     1123                                        ConstFieldMaskArg  syncMode, 
     1124                                  const UInt32             uiSyncInfo) 
     1125{ 
     1126    this->execSync(static_cast<Node *>(&oFrom), 
     1127                   whichField, 
     1128                   oOffsets, 
     1129                   syncMode, 
     1130                   uiSyncInfo); 
     1131} 
     1132#endif 
     1133 
     1134 
     1135#ifdef OSG_MT_CPTR_ASPECT 
     1136FieldContainerPtr Node::createAspectCopy(void) const 
     1137{ 
     1138    NodePtr returnValue; 
     1139