00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifdef OSG_DOC_FILES_IN_MODULE
00038
00041 #endif
00042
00043 #include <stdlib.h>
00044 #include <stdio.h>
00045 #include <ctype.h>
00046
00047 #include <functional>
00048 #include <algorithm>
00049
00050 #include "OSGConfig.h"
00051 #include "OSGFieldContainerPtr.h"
00052 #include "OSGFieldContainerType.h"
00053 #include "OSGNode.h"
00054 #include "OSGNodeCore.h"
00055 #include "OSGBinaryDataHandler.h"
00056 #include "OSGSFFieldContainerPtr.h"
00057 #include "OSGMFFieldContainerPtr.h"
00058
00059 OSG_USING_NAMESPACE
00060
00061 const BitVector Node::VolumeFieldMask =
00062 (TypeTraits<BitVector>::One << Node::VolumeFieldId );
00063 const BitVector Node::TravMaskFieldMask =
00064 (TypeTraits<BitVector>::One << Node::TravMaskFieldId );
00065 const BitVector Node::ParentFieldMask =
00066 (TypeTraits<BitVector>::One << Node::ParentFieldId );
00067 const BitVector Node::ChildrenFieldMask =
00068 (TypeTraits<BitVector>::One << Node::ChildrenFieldId );
00069 const BitVector Node::CoreFieldMask =
00070 (TypeTraits<BitVector>::One << Node::CoreFieldId );
00071
00072 FieldDescription *Node::_desc[] =
00073 {
00074 new FieldDescription(SFDynamicVolume::getClassType(),
00075 "volume",
00076 OSG_FC_FIELD_IDM_DESC(VolumeField),
00077 false,
00078 (FieldAccessMethod) &Node::getSFVolume),
00079
00080
00081
00082
00083 new FieldDescription(SFBool::getClassType(),
00084 "travMask",
00085 OSG_FC_FIELD_IDM_DESC(TravMaskField),
00086 false,
00087 (FieldAccessMethod) &Node::getSFTravMask),
00088
00089 new FieldDescription(SFNodePtr::getClassType(),
00090 "parent",
00091 OSG_FC_FIELD_IDM_DESC(ParentField),
00092 true,
00093 (FieldAccessMethod) &Node::getSFParent),
00094
00095 new FieldDescription(MFNodePtr::getClassType(),
00096 "children",
00097 OSG_FC_FIELD_IDM_DESC(ChildrenField),
00098 false,
00099 (FieldAccessMethod) &Node::getMFChildren),
00100
00101 new FieldDescription(SFNodeCorePtr::getClassType(),
00102 "core",
00103 OSG_FC_FIELD_IDM_DESC(CoreField),
00104 false,
00105 (FieldAccessMethod) &Node::getSFCore)
00106 };
00107
00108 FieldContainerType Node::_type(
00109 "Node",
00110 "AttachmentContainer",
00111 0,
00112 (PrototypeCreateF) &Node::createEmpty,
00113 0,
00114 _desc,
00115 sizeof(_desc));
00116
00117
00118 const NodePtr Node::NullNode(NullFC);
00119
00120 OSG_FIELD_CONTAINER_DEF(Node, NodePtr)
00121
00122
00123
00124
00125 void Node::setCore(const NodeCorePtr &core)
00126 {
00127 NodePtr thisP = getPtr();
00128
00129 thisP.setParentFieldPos(CoreFieldId);
00130
00131 addRefCP(core);
00132
00133 if(_sfCore.getValue() != NullFC)
00134 {
00135 beginEditCP(_sfCore.getValue(), NodeCore::ParentsFieldMask);
00136 {
00137 _sfCore.getValue()->subParent(thisP);
00138 }
00139 endEditCP (_sfCore.getValue(), NodeCore::ParentsFieldMask);
00140
00141 subRefCP(_sfCore.getValue());
00142 }
00143
00144 _sfCore.setValue(core);
00145
00146 if(_sfCore.getValue() != NullFC)
00147 {
00148 beginEditCP(_sfCore.getValue(), NodeCore::ParentsFieldMask);
00149 {
00150 _sfCore.getValue()->addParent(thisP);
00151 }
00152 endEditCP (_sfCore.getValue(), NodeCore::ParentsFieldMask);
00153 }
00154
00155
00156 invalidateVolume();
00157 }
00158
00159
00160
00161
00162 void Node::addChild(const NodePtr &childP)
00163 {
00164 if(childP != NullFC)
00165 {
00166
00167 addRefCP(childP);
00168
00169
00170 NodePtr parent = childP->getParent();
00171 if(parent != NullFC)
00172 {
00173 beginEditCP(parent, Node::ChildrenFieldMask);
00174 parent->subChild(childP);
00175 endEditCP (parent, Node::ChildrenFieldMask);
00176 }
00177
00178 _mfChildren.push_back(childP);
00179
00180 beginEditCP(childP, Node::ParentFieldMask);
00181 {
00182 childP->setParent(getPtr());
00183 }
00184 endEditCP (childP, Node::ParentFieldMask);
00185
00186
00187 #ifndef OSG_GV_BETA
00188 invalidateVolume();
00189 #endif
00190 }
00191 }
00192
00193 void Node::insertChild(UInt32 childIndex, const NodePtr &childP)
00194 {
00195 MFNodePtr::iterator childIt = _mfChildren.begin();
00196
00197 if(childP != NullFC)
00198 {
00199
00200 addRefCP(childP);
00201
00202
00203 NodePtr parent = childP->getParent();
00204 if(parent != NullFC)
00205 {
00206 beginEditCP(parent, Node::ChildrenFieldMask);
00207 parent->subChild(childP);
00208 endEditCP (parent, Node::ChildrenFieldMask);
00209 }
00210
00211 childIt += childIndex;
00212
00213 _mfChildren.insert(childIt, childP);
00214
00215 beginEditCP(childP, Node::ParentFieldMask);
00216 {
00217 childP->setParent(getPtr());
00218 }
00219 endEditCP (childP, Node::ParentFieldMask);
00220 }
00221
00222
00223 #ifndef OSG_GV_BETA
00224 invalidateVolume();
00225 #endif
00226 }
00227
00228 void Node::replaceChild(UInt32 childIndex, const NodePtr &childP)
00229 {
00230 if(childP != NullFC && childIndex < _mfChildren.size())
00231 {
00232
00233 addRefCP(childP);
00234
00235
00236 NodePtr parent = childP->getParent();
00237 if(parent != NullFC)
00238 {
00239 beginEditCP(parent, Node::ChildrenFieldMask);
00240 parent->subChild(childP);
00241 endEditCP (parent, Node::ChildrenFieldMask);
00242 }
00243
00244
00245 beginEditCP(_mfChildren[childIndex], Node::ParentFieldMask);
00246 {
00247 _mfChildren[childIndex]->setParent(NullNode);
00248 }
00249 endEditCP (_mfChildren[childIndex], Node::ParentFieldMask);
00250
00251 subRefCP(_mfChildren[childIndex]);
00252
00253
00254 _mfChildren[childIndex] = childP;
00255
00256 beginEditCP(childP, Node::ParentFieldMask);
00257 {
00258 childP->setParent(getPtr());
00259 }
00260 endEditCP (childP, Node::ParentFieldMask);
00261 }
00262
00263
00264 #ifndef OSG_GV_BETA
00265 invalidateVolume();
00266 #endif
00267 }
00268
00270
00271 bool Node::replaceChildBy(const NodePtr &childP,
00272 const NodePtr &newChildP)
00273 {
00274 MFNodePtr::iterator childIt = _mfChildren.find(childP);
00275
00276 if(newChildP != NullFC)
00277 {
00278 if(childIt != _mfChildren.end())
00279 {
00280
00281
00282
00283 addRefCP(newChildP);
00284
00285
00286 NodePtr parent = newChildP->getParent();
00287 if(parent != NullFC)
00288 {
00289 beginEditCP(parent, Node::ChildrenFieldMask);
00290 parent->subChild(newChildP);
00291 endEditCP (parent, Node::ChildrenFieldMask);
00292 }
00293
00294 beginEditCP(childP, Node::ParentFieldMask);
00295 {
00296 childP->setParent(NullNode);
00297 }
00298 endEditCP (childP, Node::ParentFieldMask);
00299
00300 subRefCP(childP);
00301
00302 (*childIt) = newChildP;
00303
00304 beginEditCP(newChildP, Node::ParentFieldMask);
00305 {
00306 newChildP->setParent(getPtr());
00307 }
00308 endEditCP (newChildP, Node::ParentFieldMask);
00309
00310
00311 #ifndef OSG_GV_BETA
00312 invalidateVolume();
00313 #endif
00314
00315 return true;
00316 }
00317 }
00318
00319 return false;
00320 }
00321
00322 Int32 Node::findChild(const NodePtr &childP) const
00323 {
00324 UInt32 index;
00325
00326 for(index = 0; index < _mfChildren.size(); index++)
00327 {
00328 if( _mfChildren[index] == childP)
00329 break;
00330 }
00331
00332 if(index < _mfChildren.size())
00333 return index;
00334 else
00335 return -1;
00336 }
00337
00338 void Node::subChild(const NodePtr &childP)
00339 {
00340 MFNodePtr::iterator childIt = _mfChildren.find(childP);
00341
00342 if(childIt != _mfChildren.end())
00343 {
00344 beginEditCP(childP, Node::ParentFieldMask);
00345 {
00346 childP->setParent(NullNode);
00347 }
00348 endEditCP (childP, Node::ParentFieldMask);
00349
00350 subRefCP(childP);
00351
00352 _mfChildren.erase(childIt);
00353 }
00354 else
00355 {
00356 SWARNING << "Node(" << this << ")::subChild: " << childP
00357 << " is not one of my children!" << std::endl;
00358 }
00359
00360
00361 #ifndef OSG_GV_BETA
00362 invalidateVolume();
00363 #endif
00364 }
00365
00366 void Node::subChild(UInt32 childIndex)
00367 {
00368 MFNodePtr::iterator childIt = _mfChildren.begin();
00369
00370 childIt += childIndex;
00371
00372 if(childIt != _mfChildren.end())
00373 {
00374 beginEditCP(*childIt, Node::ParentFieldMask);
00375 {
00376 (*childIt)->setParent(NullNode);
00377 }
00378 endEditCP (*childIt, Node::ParentFieldMask);
00379
00380 subRefCP(*childIt);
00381
00382 _mfChildren.erase(childIt);
00383 }
00384
00385
00386 #ifndef OSG_GV_BETA
00387 invalidateVolume();
00388 #endif
00389 }
00390
00391
00392
00393
00394
00395 Matrix Node::getToWorld(void)
00396 {
00397 Matrix tmp;
00398
00399 getToWorld(tmp);
00400
00401 return tmp;
00402 }
00403
00404 void Node::getToWorld(Matrix &result)
00405 {
00406 if(getParent() != NullFC)
00407 {
00408 getParent()->getToWorld(result);
00409 }
00410 else
00411 {
00412 result.setIdentity();
00413 }
00414
00415 if(getCore() != NullFC)
00416 getCore()->accumulateMatrix(result);
00417 }
00418
00419
00420
00421
00422 void Node::getWorldVolume(DynamicVolume &result)
00423 {
00424 Matrix m;
00425
00426 if(getParent() != NullFC)
00427 {
00428 getParent()->getToWorld(m);
00429 }
00430 else
00431 {
00432 m.setIdentity();
00433 }
00434
00435 updateVolume();
00436
00437 result = getVolume();
00438 result.transform(m);
00439
00440
00441
00442
00443
00444
00445
00446
00447 }
00448
00449 void Node::updateVolume(void)
00450 {
00451 if(_sfVolume.getValue().getInstance().isValid() == true ||
00452 getTravMask() == 0x0000)
00453 {
00454 return;
00455 }
00456
00457
00458
00459
00460 DynamicVolume vol = _sfVolume.getValue();
00461
00462
00463
00464 MFNodePtr::iterator it;
00465
00466 vol.getInstance().setEmpty();
00467
00468 for(it = _mfChildren.begin(); it != _mfChildren.end(); ++it)
00469 {
00470 if((*it)->getTravMask())
00471 {
00472 (*it)->updateVolume();
00473 vol.getInstance().extendBy((*it)->getVolume());
00474 }
00475 }
00476
00477
00478 if(getCore() != NullFC)
00479 getCore()->adjustVolume(vol.getInstance());
00480
00481 NodePtr thisP = getPtr();
00482
00483 beginEditCP(thisP, VolumeFieldMask);
00484
00485 vol.instanceChanged();
00486
00487 _sfVolume.setValue(vol);
00488
00489 endEditCP(thisP, VolumeFieldMask);
00490 }
00491
00492 void Node::invalidateVolume(void)
00493 {
00494 Volume &vol=_sfVolume.getValue().getInstance();
00495
00496 if(vol.isValid() == true && vol.isStatic() == false)
00497 {
00498 NodePtr thisP = getPtr();
00499
00500 beginEditCP(thisP, VolumeFieldMask);
00501
00502 vol.setValid(false);
00503 _sfVolume.getValue().instanceChanged();
00504
00505 endEditCP(thisP, VolumeFieldMask);
00506
00507 if(getParent() != NullFC)
00508 {
00509 getParent()->invalidateVolume();
00510 }
00511 }
00512 }
00513
00514
00515
00516
00517 void Node::dump( UInt32 uiIndent,
00518 const BitVector bvFlags) const
00519 {
00520 UInt32 i;
00521
00522 NodePtr thisP = getPtr();
00523
00524 indentLog(uiIndent, PLOG);
00525
00526 PLOG << "Node"
00527 << "("
00528 << thisP.getFieldContainerId()
00529 << ") : "
00530 << _mfChildren.size()
00531 << " children | "
00532 << _attachmentMap.getValue().size()
00533 << " attachments | "
00534 << "Parent : " << std::hex;
00535
00536 if(_sfParent.getValue() != NullFC)
00537 PLOG << "0x" << &(*(_sfParent.getValue())) << " | ";
00538 else
00539 PLOG << "NULL | ";
00540
00541 PLOG << "0x" << this << std::dec << std::endl;
00542
00543 indentLog(uiIndent, PLOG);
00544
00545 PLOG << "[" << std::endl;
00546
00547 if(_sfCore.getValue() != NullFC)
00548 {
00549 _sfCore.getValue()->dump(uiIndent + 4, bvFlags);
00550 }
00551 else
00552 {
00553 indentLog(uiIndent + 4, PLOG);
00554 PLOG << "Core : " << "NULL" << std::endl;
00555 }
00556
00557 Inherited::dump(uiIndent, bvFlags);
00558
00559 indentLog(uiIndent, PLOG);
00560 PLOG << "]" << std::endl;
00561
00562 indentLog(uiIndent, PLOG);
00563
00564 PLOG << "{" << std::endl;
00565
00566 for(i = 0; i < _mfChildren.size(); i++)
00567 {
00568 _mfChildren[i]->dump(uiIndent + 4, bvFlags);
00569 PLOG << std::endl;
00570 }
00571
00572
00573 indentLog(uiIndent, PLOG);
00574
00575 PLOG << "}" << std::endl;
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620 }
00621
00622
00623
00624
00625 Node::Node(void) :
00626 Inherited (),
00627 _sfVolume (),
00628 _sfTravMask (TypeTraits<UInt32>::getMax()),
00629 _sfParent (),
00630 _mfChildren (),
00631 _sfCore (),
00632 _occlusionMask(0)
00633 {
00634 }
00635
00636 Node::Node(const Node &source) :
00637 Inherited (source),
00638 _sfVolume (source._sfVolume),
00639 _sfTravMask (source._sfTravMask),
00640 _sfParent (),
00641 _mfChildren (),
00642 _sfCore (),
00643 _occlusionMask (source._occlusionMask)
00644 {
00645 }
00646
00647
00648
00649
00650 Node::~Node(void)
00651 {
00652 if(_sfCore.getValue() != NullFC)
00653 {
00654 NodePtr thisP = getPtr();
00655
00656 beginEditCP(_sfCore.getValue(), NodeCore::ParentsFieldMask);
00657 {
00658 _sfCore.getValue()->subParent(thisP);
00659 }
00660 endEditCP (_sfCore.getValue(), NodeCore::ParentsFieldMask);
00661
00662 subRefCP(_sfCore.getValue());
00663 }
00664
00665 MFNodePtr::iterator vChildIt = _mfChildren.begin();
00666 MFNodePtr::const_iterator endChildren = _mfChildren.end ();
00667
00668 while(vChildIt != endChildren)
00669 {
00670 beginEditCP(*vChildIt, Node::ParentFieldMask);
00671 {
00672 (*vChildIt)->setParent(NullNode);
00673 }
00674 endEditCP (*vChildIt, Node::ParentFieldMask);
00675
00676 subRefCP(*vChildIt);
00677
00678 ++vChildIt;
00679 }
00680 }
00681
00682 #if defined(OSG_FIXED_MFIELDSYNC)
00683 void Node::onDestroyAspect(UInt32 uiId, UInt32 uiAspect)
00684 {
00685 _mfChildren.terminateShare(uiAspect, this->getContainerSize());
00686 }
00687 #endif
00688
00689 NodePtr OSG::cloneTree(const NodePtr &pRootNode)
00690 {
00691 NodePtr returnValue = NullFC;
00692
00693 if(pRootNode != NullFC)
00694 {
00695 NodePtr pChildClone = NullFC;
00696
00697 returnValue = Node::create();
00698
00699 beginEditCP(returnValue);
00700 {
00701 returnValue->setTravMask(pRootNode->getTravMask());
00702 returnValue->setCore (pRootNode->getCore());
00703
00704 for(UInt32 i = 0; i < pRootNode->getNChildren(); i++)
00705 {
00706 pChildClone = cloneTree(pRootNode->getChild(i));
00707
00708 returnValue->addChild(pChildClone);
00709 }
00710 }
00711 endEditCP (returnValue);
00712 }
00713
00714 return returnValue;
00715 }
00716
00717
00718
00719 FieldContainerPtr OSG::deepClone(const FieldContainerPtr &src,
00720 const std::vector<std::string> &share)
00721 {
00722 if(src == NullFC)
00723 return NullFC;
00724
00725 const FieldContainerType &type = src->getType();
00726
00727
00728
00729 FieldContainerPtr dst = FieldContainerFactory::the()->createFieldContainer(type.getName().str());
00730
00731
00732
00733 UInt32 fcount = osgMin(type.getNumFieldDescs(), dst->getType().getNumFieldDescs());
00734
00735
00736 for(UInt32 i=1;i <= fcount;++i)
00737 {
00738 const FieldDescription* fdesc = type.getFieldDescription(i);
00739
00740 if(fdesc->isInternal())
00741 continue;
00742
00743 BitVector mask = fdesc->getFieldMask();
00744
00745 Field *src_field = src->getField(i);
00746 Field *dst_field = dst->getField(i);
00747
00748 const FieldType &ftype = src_field->getType();
00749
00750 std::string fieldType = ftype.getName().str();
00751
00752
00753 if(strcmp(fdesc->getCName(), "attachments") == 0)
00754 {
00755 SFAttachmentMap *amap = (SFAttachmentMap *) src_field;
00756
00757 AttachmentMap::const_iterator mapIt = amap->getValue().begin();
00758 AttachmentMap::const_iterator mapEnd = amap->getValue().end();
00759
00760 beginEditCP(dst, mask);
00761 for(; mapIt != mapEnd; ++mapIt)
00762 {
00763 FieldContainerPtr fc = mapIt->second;
00764
00765 bool shareit = false;
00766 for(UInt32 k=0;k<share.size();++k)
00767 {
00768 FieldContainerType *fct = FieldContainerFactory::the()
00769 ->findType(share[k].c_str());
00770 if(fc != NullFC && fct != NULL &&
00771 fc->getType().isDerivedFrom(*fct))
00772 {
00773 shareit = true;
00774 break;
00775 }
00776 }
00777
00778 if(!shareit)
00779 fc = OSG::deepClone(fc, share);
00780
00781 if(fc != NullFC)
00782 AttachmentContainerPtr::dcast(dst)->addAttachment(AttachmentPtr::dcast(fc));
00783 }
00784 endEditCP(dst, mask);
00785 continue;
00786 }
00787
00788
00789 if(strstr(ftype.getCName(), "Ptr") == NULL)
00790 {
00791
00792 beginEditCP(dst, mask);
00793 dst_field->setAbstrValue(*src_field);
00794 endEditCP(dst, mask);
00795 }
00796 else
00797 {
00798 if(src_field->getCardinality() == FieldType::SINGLE_FIELD)
00799 {
00800 FieldContainerPtr fc = ((SFFieldContainerPtr *) src_field)->getValue();
00801
00802 bool shareit = false;
00803 for(UInt32 k=0;k<share.size();++k)
00804 {
00805 FieldContainerType *fct = FieldContainerFactory::the()
00806 ->findType(share[k].c_str());
00807 if(fc != NullFC && fct != NULL &&
00808 fc->getType().isDerivedFrom(*fct))
00809 {
00810 shareit = true;
00811 break;
00812 }
00813 }
00814
00815 if(!shareit)
00816 fc = OSG::deepClone(fc, share);
00817
00818 if(fc != NullFC)
00819 {
00820
00821 addRefCP(fc);
00822 beginEditCP(dst);
00823 ((SFFieldContainerPtr *) dst_field)->setValue(fc);
00824 endEditCP(dst);
00825 }
00826 }
00827 else if(src_field->getCardinality() == FieldType::MULTI_FIELD)
00828 {
00829 beginEditCP(dst, mask);
00830 for(UInt32 j=0;j < ((MFFieldContainerPtr*)src_field)->size();++j)
00831 {
00832 FieldContainerPtr fc = (*(((MFFieldContainerPtr *)src_field)))[j];
00833
00834 bool shareit = false;
00835 for(UInt32 k=0;k<share.size();++k)
00836 {
00837 FieldContainerType *fct = FieldContainerFactory::the()
00838 ->findType(share[k].c_str());
00839 if(fc != NullFC && fct != NULL &&
00840 fc->getType().isDerivedFrom(*fct))
00841 {
00842 shareit = true;
00843 break;
00844 }
00845 }
00846
00847 if(!shareit)
00848 fc = OSG::deepClone(fc, share);
00849
00850 if(fc != NullFC)
00851 {
00852
00853 addRefCP(fc);
00854 ((MFFieldContainerPtr *) dst_field)->push_back(fc);
00855 }
00856 }
00857 endEditCP(dst, mask);
00858 }
00859 }
00860 }
00861 return dst;
00862 }
00863
00864 FieldContainerPtr OSG::deepClone(const FieldContainerPtr &src,
00865 const std::vector<UInt16> &shareGroupIds)
00866 {
00867 std::vector<std::string> share;
00868 share.reserve(shareGroupIds.size());
00869 for(UInt32 i=0;i<shareGroupIds.size();++i)
00870 {
00871 const char *name = FieldContainerFactory::the()->findGroupName(shareGroupIds[i]);
00872 if(name != NULL)
00873 share.push_back(name);
00874 }
00875 return OSG::deepClone(src, share);
00876 }
00877
00878
00879
00880 FieldContainerPtr OSG::deepClone(const FieldContainerPtr &src,
00881 const std::string &shareString)
00882 {
00883 std::vector<std::string> share;
00884
00885
00886 std::string::const_iterator nextComma;
00887 std::string::const_iterator curPos = shareString.begin();
00888 while(curPos < shareString.end())
00889 {
00890 nextComma = std::find(curPos, shareString.end(), ',');
00891
00892 curPos = std::find_if(curPos, nextComma, std::not1(std::ptr_fun(isspace)));
00893 share.push_back(std::string(curPos, nextComma));
00894 if(nextComma != shareString.end())
00895 curPos = ++nextComma;
00896 else
00897 break;
00898 }
00899
00900 return OSG::deepClone(src, share);
00901 }
00902
00903
00904 void OSG::deepCloneAttachments(const AttachmentContainerPtr &src,
00905 AttachmentContainerPtr dst,
00906 const std::vector<std::string> &share)
00907 {
00908 SFAttachmentMap *amap = (SFAttachmentMap *) src->getSFAttachments();
00909
00910 AttachmentMap::const_iterator mapIt = amap->getValue().begin();
00911 AttachmentMap::const_iterator mapEnd = amap->getValue().end();
00912
00913 beginEditCP(dst, AttachmentContainer::AttachmentsFieldMask);
00914 for(; mapIt != mapEnd; ++mapIt)
00915 {
00916 FieldContainerPtr fc = mapIt->second;
00917
00918 bool shareit = false;
00919 for(UInt32 k=0;k<share.size();++k)
00920 {
00921 FieldContainerType *fct = FieldContainerFactory::the()
00922 ->findType(share[k].c_str());
00923 if(fc != NullFC && fct != NULL &&
00924 fc->getType().isDerivedFrom(*fct))
00925 {
00926 shareit = true;
00927 break;
00928 }
00929 }
00930
00931 if(!shareit)
00932 fc = OSG::deepClone(fc, share);
00933
00934 if(fc != NullFC)
00935 dst->addAttachment(AttachmentPtr::dcast(fc));
00936 }
00937 endEditCP(dst, AttachmentContainer::AttachmentsFieldMask);
00938 }
00939
00940 void OSG::deepCloneAttachments(const AttachmentContainerPtr &src,
00941 AttachmentContainerPtr dst,
00942 const std::vector<UInt16> &shareGroupIds)
00943 {
00944 std::vector<std::string> share;
00945 share.reserve(shareGroupIds.size());
00946 for(UInt32 i=0;i<shareGroupIds.size();++i)
00947 {
00948 const char *name = FieldContainerFactory::the()
00949 ->findGroupName(shareGroupIds[i]);
00950 if(name != NULL)
00951 share.push_back(name);
00952 }
00953 OSG::deepCloneAttachments(src, dst, share);
00954 }
00955
00956
00957
00958 void OSG::deepCloneAttachments(const NodePtr &src, NodePtr &dst,
00959 const std::string &shareString)
00960 {
00961 std::vector<std::string> share;
00962
00963
00964 std::string::const_iterator nextComma;
00965 std::string::const_iterator curPos = shareString.begin();
00966 while(curPos < shareString.end())
00967 {
00968 nextComma = std::find(curPos, shareString.end(), ',');
00969
00970 curPos = std::find_if(curPos, nextComma, std::not1(std::ptr_fun(isspace)));
00971 share.push_back(std::string(curPos, nextComma));
00972 if(nextComma != shareString.end())
00973 curPos = ++nextComma;
00974 else
00975 break;
00976 }
00977
00978 OSG::deepCloneAttachments(src, dst, share);
00979 }
00980
00981
00982 NodePtr OSG::deepCloneTree(const NodePtr &src,
00983 const std::vector<std::string> &share)
00984 {
00985 NodePtr dst = NullFC;
00986
00987 if(src != NullFC)
00988 {
00989 dst = Node::create();
00990 deepCloneAttachments(src, dst, share);
00991
00992 beginEditCP(dst);
00993 {
00994 dst->setActive(src->getActive());
00995 dst->setTravMask(src->getTravMask());
00996 dst->setCore(NodeCorePtr::dcast(OSG::deepClone(src->getCore(), share)));
00997
00998 for(UInt32 i = 0; i < src->getNChildren(); i++)
00999 dst->addChild(deepCloneTree(src->getChild(i), share));
01000 }
01001 endEditCP (dst);
01002 }
01003
01004 return dst;
01005 }
01006
01007 NodePtr OSG::deepCloneTree(const NodePtr &src,
01008 const std::vector<UInt16> &shareGroupIds)
01009 {
01010 std::vector<std::string> share;
01011 share.reserve(shareGroupIds.size());
01012 for(UInt32 i=0;i<shareGroupIds.size();++i)
01013 {
01014 const char *name = FieldContainerFactory::the()->findGroupName(shareGroupIds[i]);
01015 if(name != NULL)
01016 share.push_back(name);
01017 }
01018 return OSG::deepCloneTree(src, share);
01019 }
01020
01021
01022
01023 NodePtr OSG::deepCloneTree(const NodePtr &src,
01024 const std::string &shareString)
01025 {
01026 std::vector<std::string> share;
01027
01028
01029 std::string::const_iterator nextComma;
01030 std::string::const_iterator curPos = shareString.begin();
01031 while(curPos < shareString.end())
01032 {
01033 nextComma = std::find(curPos, shareString.end(), ',');
01034
01035 curPos = std::find_if(curPos, nextComma, std::not1(std::ptr_fun(isspace)));
01036 share.push_back(std::string(curPos, nextComma));
01037 if(nextComma != shareString.end())
01038 curPos = ++nextComma;
01039 else
01040 break;
01041 }
01042
01043 return OSG::deepCloneTree(src, share);
01044 }
01045
01046
01047
01048
01049
01050 #ifdef __sgi
01051 #pragma set woff 1174
01052 #endif
01053
01054 #ifdef OSG_LINUX_ICC
01055 #pragma warning( disable : 177 )
01056 #endif
01057
01058 namespace
01059 {
01060 static Char8 cvsid_cpp[] = "@(#)$Id: $";
01061 static Char8 cvsid_hpp[] = OSGNODE_HEADER_CVSID;
01062 static Char8 cvsid_inl[] = OSGNODE_INLINE_CVSID;
01063 }