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 if(childP->getParent() != NullFC)
00171 {
00172 beginEditCP(childP->getParent(), Node::ChildrenFieldMask);
00173 childP->getParent()->subChild(childP);
00174 endEditCP(childP->getParent(), Node::ChildrenFieldMask);
00175 }
00176
00177 _mfChildren.push_back(childP);
00178
00179 beginEditCP(childP, Node::ParentFieldMask);
00180 {
00181 childP->setParent(getPtr());
00182 }
00183 endEditCP (childP, Node::ParentFieldMask);
00184
00185
00186 #ifndef OSG_GV_BETA
00187 invalidateVolume();
00188 #endif
00189 }
00190 }
00191
00192 void Node::insertChild(UInt32 childIndex, const NodePtr &childP)
00193 {
00194 MFNodePtr::iterator childIt = _mfChildren.begin();
00195
00196 if(childP != NullFC)
00197 {
00198
00199 addRefCP(childP);
00200
00201
00202 if(childP->getParent() != NullFC)
00203 {
00204 beginEditCP(childP->getParent(), Node::ChildrenFieldMask);
00205 childP->getParent()->subChild(childP);
00206 endEditCP(childP->getParent(), Node::ChildrenFieldMask);
00207 }
00208
00209 childIt += childIndex;
00210
00211 _mfChildren.insert(childIt, childP);
00212
00213 beginEditCP(childP, Node::ParentFieldMask);
00214 {
00215 childP->setParent(getPtr());
00216 }
00217 endEditCP (childP, Node::ParentFieldMask);
00218 }
00219
00220
00221 #ifndef OSG_GV_BETA
00222 invalidateVolume();
00223 #endif
00224 }
00225
00226 void Node::replaceChild(UInt32 childIndex, const NodePtr &childP)
00227 {
00228 if(childP != NullFC && childIndex < _mfChildren.size())
00229 {
00230
00231 addRefCP(childP);
00232
00233
00234 beginEditCP(_mfChildren[childIndex], Node::ParentFieldMask);
00235 {
00236 _mfChildren[childIndex]->setParent(NullNode);
00237 }
00238 endEditCP (_mfChildren[childIndex], Node::ParentFieldMask);
00239
00240 subRefCP(_mfChildren[childIndex]);
00241
00242
00243 if(childP->getParent() != NullNode)
00244 {
00245 beginEditCP(childP->getParent(), Node::ChildrenFieldMask);
00246 childP->getParent()->subChild(childP);
00247 endEditCP(childP->getParent(), Node::ChildrenFieldMask);
00248 }
00249
00250
00251 _mfChildren[childIndex] = childP;
00252
00253 beginEditCP(childP, Node::ParentFieldMask);
00254 {
00255 childP->setParent(getPtr());
00256 }
00257 endEditCP (childP, Node::ParentFieldMask);
00258 }
00259
00260
00261 #ifndef OSG_GV_BETA
00262 invalidateVolume();
00263 #endif
00264 }
00265
00267
00268 bool Node::replaceChildBy(const NodePtr &childP,
00269 const NodePtr &newChildP)
00270 {
00271 MFNodePtr::iterator childIt = _mfChildren.find(childP);
00272
00273 if(newChildP != NullFC)
00274 {
00275 if(childIt != _mfChildren.end())
00276 {
00277
00278
00279
00280 addRefCP(newChildP);
00281
00282 beginEditCP(childP, Node::ParentFieldMask);
00283 {
00284 childP->setParent(NullNode);
00285 }
00286 endEditCP (childP, Node::ParentFieldMask);
00287
00288 subRefCP(childP);
00289
00290
00291 if(newChildP->getParent() != NullFC)
00292 {
00293 beginEditCP(newChildP->getParent(), Node::ChildrenFieldMask);
00294 newChildP->getParent()->subChild(newChildP);
00295 endEditCP(newChildP->getParent(), Node::ChildrenFieldMask);
00296 }
00297
00298 (*childIt) = newChildP;
00299
00300 beginEditCP(newChildP, Node::ParentFieldMask);
00301 {
00302 newChildP->setParent(getPtr());
00303 }
00304 endEditCP (newChildP, Node::ParentFieldMask);
00305
00306
00307 #ifndef OSG_GV_BETA
00308 invalidateVolume();
00309 #endif
00310
00311 return true;
00312 }
00313 }
00314
00315 return false;
00316 }
00317
00318 Int32 Node::findChild(const NodePtr &childP) const
00319 {
00320 UInt32 index;
00321
00322 for(index = 0; index < _mfChildren.size(); index++)
00323 {
00324 if( _mfChildren[index] == childP)
00325 break;
00326 }
00327
00328 if(index < _mfChildren.size())
00329 return index;
00330 else
00331 return -1;
00332 }
00333
00334 void Node::subChild(const NodePtr &childP)
00335 {
00336 MFNodePtr::iterator childIt = _mfChildren.find(childP);
00337
00338 if(childIt != _mfChildren.end())
00339 {
00340 beginEditCP(childP, Node::ParentFieldMask);
00341 {
00342 childP->setParent(NullNode);
00343 }
00344 endEditCP (childP, Node::ParentFieldMask);
00345
00346 subRefCP(childP);
00347
00348 _mfChildren.erase(childIt);
00349 }
00350 else
00351 {
00352 SWARNING << "Node(" << this << ")::subChild: " << childP
00353 << " is not one of my children!" << std::endl;
00354 }
00355
00356
00357 #ifndef OSG_GV_BETA
00358 invalidateVolume();
00359 #endif
00360 }
00361
00362 void Node::subChild(UInt32 childIndex)
00363 {
00364 MFNodePtr::iterator childIt = _mfChildren.begin();
00365
00366 childIt += childIndex;
00367
00368 if(childIt != _mfChildren.end())
00369 {
00370 beginEditCP(*childIt, Node::ParentFieldMask);
00371 {
00372 (*childIt)->setParent(NullNode);
00373 }
00374 endEditCP (*childIt, Node::ParentFieldMask);
00375
00376 subRefCP(*childIt);
00377
00378 _mfChildren.erase(childIt);
00379 }
00380
00381
00382 #ifndef OSG_GV_BETA
00383 invalidateVolume();
00384 #endif
00385 }
00386
00387
00388
00389
00390
00391 Matrix Node::getToWorld(void)
00392 {
00393 Matrix tmp;
00394
00395 getToWorld(tmp);
00396
00397 return tmp;
00398 }
00399
00400 void Node::getToWorld(Matrix &result)
00401 {
00402 if(getParent() != NullFC)
00403 {
00404 getParent()->getToWorld(result);
00405 }
00406 else
00407 {
00408 result.setIdentity();
00409 }
00410
00411 getCore()->accumulateMatrix(result);
00412 }
00413
00414
00415
00416
00417 void Node::getWorldVolume(DynamicVolume &result)
00418 {
00419 Matrix m;
00420
00421 if(getParent() != NullFC)
00422 {
00423 getParent()->getToWorld(m);
00424 }
00425 else
00426 {
00427 m.setIdentity();
00428 }
00429
00430 updateVolume();
00431
00432 result = getVolume();
00433 result.transform(m);
00434
00435
00436
00437
00438
00439
00440
00441
00442 }
00443
00444 void Node::updateVolume(void)
00445 {
00446 if(_sfVolume.getValue().getInstance().isValid() == true)
00447 return;
00448
00449
00450
00451
00452 DynamicVolume vol = _sfVolume.getValue();
00453
00454
00455
00456 MFNodePtr::iterator it;
00457
00458 vol.getInstance().setEmpty();
00459
00460 if(getTravMask())
00461 {
00462 for(it = _mfChildren.begin(); it != _mfChildren.end(); ++it)
00463 {
00464 if((*it)->getTravMask())
00465 {
00466 (*it)->updateVolume();
00467 vol.getInstance().extendBy((*it)->getVolume());
00468 }
00469 }
00470
00471
00472 if(getCore() != NullFC)
00473 getCore()->adjustVolume(vol.getInstance());
00474 }
00475
00476 NodePtr thisP = getPtr();
00477
00478 beginEditCP(thisP, VolumeFieldMask);
00479
00480 vol.instanceChanged();
00481
00482 _sfVolume.setValue(vol);
00483
00484 endEditCP(thisP, VolumeFieldMask);
00485 }
00486
00487 void Node::invalidateVolume(void)
00488 {
00489 Volume &vol=_sfVolume.getValue().getInstance();
00490
00491 if(vol.isValid() == true && vol.isStatic() == false)
00492 {
00493 NodePtr thisP = getPtr();
00494
00495 beginEditCP(thisP, VolumeFieldMask);
00496
00497 vol.setValid(false);
00498 _sfVolume.getValue().instanceChanged();
00499
00500 endEditCP(thisP, VolumeFieldMask);
00501
00502 if(getParent() != NullFC)
00503 {
00504 getParent()->invalidateVolume();
00505 }
00506 }
00507 }
00508
00509
00510
00511
00512 void Node::dump( UInt32 uiIndent,
00513 const BitVector bvFlags) const
00514 {
00515 UInt32 i;
00516
00517 NodePtr thisP = getPtr();
00518
00519 indentLog(uiIndent, PLOG);
00520
00521 PLOG << "Node"
00522 << "("
00523 << thisP.getFieldContainerId()
00524 << ") : "
00525 << _mfChildren.size()
00526 << " children | "
00527 << _attachmentMap.getValue().size()
00528 << " attachments | "
00529 << "Parent : " << std::hex;
00530
00531 if(_sfParent.getValue() != NullFC)
00532 PLOG << "0x" << &(*(_sfParent.getValue())) << " | ";
00533 else
00534 PLOG << "NULL | ";
00535
00536 PLOG << "0x" << this << std::dec << std::endl;
00537
00538 indentLog(uiIndent, PLOG);
00539
00540 PLOG << "[" << std::endl;
00541
00542 if(_sfCore.getValue() != NullFC)
00543 {
00544 _sfCore.getValue()->dump(uiIndent + 4, bvFlags);
00545 }
00546 else
00547 {
00548 indentLog(uiIndent + 4, PLOG);
00549 PLOG << "Core : " << "NULL" << std::endl;
00550 }
00551
00552 Inherited::dump(uiIndent, bvFlags);
00553
00554 indentLog(uiIndent, PLOG);
00555 PLOG << "]" << std::endl;
00556
00557 indentLog(uiIndent, PLOG);
00558
00559 PLOG << "{" << std::endl;
00560
00561 for(i = 0; i < _mfChildren.size(); i++)
00562 {
00563 _mfChildren[i]->dump(uiIndent + 4, bvFlags);
00564 PLOG << std::endl;
00565 }
00566
00567
00568 indentLog(uiIndent, PLOG);
00569
00570 PLOG << "}" << std::endl;
00571
00572
00573
00574
00575
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 Node::Node(void) :
00621 Inherited (),
00622 _sfVolume (),
00623 _sfTravMask (TypeTraits<UInt32>::getMax()),
00624 _sfParent (),
00625 _mfChildren (),
00626 _sfCore ()
00627 {
00628 }
00629
00630 Node::Node(const Node &source) :
00631 Inherited (source),
00632 _sfVolume (source._sfVolume),
00633 _sfTravMask (source._sfTravMask),
00634 _sfParent (),
00635 _mfChildren (),
00636 _sfCore ()
00637 {
00638 }
00639
00640
00641
00642
00643 Node::~Node(void)
00644 {
00645 if(_sfCore.getValue() != NullFC)
00646 {
00647 NodePtr thisP = getPtr();
00648
00649 beginEditCP(_sfCore.getValue(), NodeCore::ParentsFieldMask);
00650 {
00651 _sfCore.getValue()->subParent(thisP);
00652 }
00653 endEditCP (_sfCore.getValue(), NodeCore::ParentsFieldMask);
00654
00655 subRefCP(_sfCore.getValue());
00656 }
00657
00658 MFNodePtr::iterator vChildIt = _mfChildren.begin();
00659 MFNodePtr::const_iterator endChildren = _mfChildren.end ();
00660
00661 while(vChildIt != endChildren)
00662 {
00663 beginEditCP(*vChildIt, Node::ParentFieldMask);
00664 {
00665 (*vChildIt)->setParent(NullNode);
00666 }
00667 endEditCP (*vChildIt, Node::ParentFieldMask);
00668
00669 subRefCP(*vChildIt);
00670
00671 ++vChildIt;
00672 }
00673 }
00674
00675 #if defined(OSG_FIXED_MFIELDSYNC)
00676 void Node::onDestroyAspect(UInt32 uiId, UInt32 uiAspect)
00677 {
00678 _mfChildren.terminateShare(uiAspect, this->getContainerSize());
00679 }
00680 #endif
00681
00682 NodePtr OSG::cloneTree(const NodePtr &pRootNode)
00683 {
00684 NodePtr returnValue = NullFC;
00685
00686 if(pRootNode != NullFC)
00687 {
00688 NodePtr pChildClone = NullFC;
00689
00690 returnValue = Node::create();
00691
00692 beginEditCP(returnValue);
00693 {
00694 returnValue->setTravMask(pRootNode->getTravMask());
00695 returnValue->setCore (pRootNode->getCore());
00696
00697 for(UInt32 i = 0; i < pRootNode->getNChildren(); i++)
00698 {
00699 pChildClone = cloneTree(pRootNode->getChild(i));
00700
00701 returnValue->addChild(pChildClone);
00702 }
00703 }
00704 endEditCP (returnValue);
00705 }
00706
00707 return returnValue;
00708 }
00709
00710
00711
00712 FieldContainerPtr OSG::deepClone(const FieldContainerPtr &src,
00713 const std::vector<std::string> &share)
00714 {
00715 if(src == NullFC)
00716 return NullFC;
00717
00718 const FieldContainerType &type = src->getType();
00719
00720
00721
00722 FieldContainerPtr dst = FieldContainerFactory::the()->createFieldContainer(type.getName().str());
00723
00724
00725
00726 UInt32 fcount = osgMin(type.getNumFieldDescs(), dst->getType().getNumFieldDescs());
00727
00728
00729 for(UInt32 i=1;i <= fcount;++i)
00730 {
00731 const FieldDescription* fdesc = type.getFieldDescription(i);
00732
00733 if(fdesc->isInternal())
00734 continue;
00735
00736 BitVector mask = fdesc->getFieldMask();
00737
00738 Field *src_field = src->getField(i);
00739 Field *dst_field = dst->getField(i);
00740
00741 const FieldType &ftype = src_field->getType();
00742
00743 std::string fieldType = ftype.getName().str();
00744
00745
00746 if(strcmp(fdesc->getCName(), "attachments") == 0)
00747 {
00748 SFAttachmentMap *amap = (SFAttachmentMap *) src_field;
00749
00750 AttachmentMap::const_iterator mapIt = amap->getValue().begin();
00751 AttachmentMap::const_iterator mapEnd = amap->getValue().end();
00752
00753 beginEditCP(dst, mask);
00754 for(; mapIt != mapEnd; ++mapIt)
00755 {
00756 FieldContainerPtr fc = mapIt->second;
00757
00758 bool shareit = false;
00759 for(UInt32 k=0;k<share.size();++k)
00760 {
00761 FieldContainerType *fct = FieldContainerFactory::the()
00762 ->findType(share[k].c_str());
00763 if(fc != NullFC && fct != NULL &&
00764 fc->getType().isDerivedFrom(*fct))
00765 {
00766 shareit = true;
00767 break;
00768 }
00769 }
00770
00771 if(!shareit)
00772 fc = OSG::deepClone(fc, share);
00773
00774 if(fc != NullFC)
00775 AttachmentContainerPtr::dcast(dst)->addAttachment(AttachmentPtr::dcast(fc));
00776 }
00777 endEditCP(dst, mask);
00778 continue;
00779 }
00780
00781
00782 if(strstr(ftype.getCName(), "Ptr") == NULL)
00783 {
00784
00785 beginEditCP(dst, mask);
00786 dst_field->setAbstrValue(*src_field);
00787 endEditCP(dst, mask);
00788 }
00789 else
00790 {
00791 if(src_field->getCardinality() == FieldType::SINGLE_FIELD)
00792 {
00793 FieldContainerPtr fc = ((SFFieldContainerPtr *) src_field)->getValue();
00794
00795 bool shareit = false;
00796 for(UInt32 k=0;k<share.size();++k)
00797 {
00798 FieldContainerType *fct = FieldContainerFactory::the()
00799 ->findType(share[k].c_str());
00800 if(fc != NullFC && fct != NULL &&
00801 fc->getType().isDerivedFrom(*fct))
00802 {
00803 shareit = true;
00804 break;
00805 }
00806 }
00807
00808 if(!shareit)
00809 fc = OSG::deepClone(fc, share);
00810
00811 if(fc != NullFC)
00812 {
00813
00814 addRefCP(fc);
00815 beginEditCP(dst);
00816 ((SFFieldContainerPtr *) dst_field)->setValue(fc);
00817 endEditCP(dst);
00818 }
00819 }
00820 else if(src_field->getCardinality() == FieldType::MULTI_FIELD)
00821 {
00822 beginEditCP(dst, mask);
00823 for(UInt32 j=0;j < ((MFFieldContainerPtr*)src_field)->size();++j)
00824 {
00825 FieldContainerPtr fc = (*(((MFFieldContainerPtr *)src_field)))[j];
00826
00827 bool shareit = false;
00828 for(UInt32 k=0;k<share.size();++k)
00829 {
00830 FieldContainerType *fct = FieldContainerFactory::the()
00831 ->findType(share[k].c_str());
00832 if(fc != NullFC && fct != NULL &&
00833 fc->getType().isDerivedFrom(*fct))
00834 {
00835 shareit = true;
00836 break;
00837 }
00838 }
00839
00840 if(!shareit)
00841 fc = OSG::deepClone(fc, share);
00842
00843 if(fc != NullFC)
00844 {
00845
00846 addRefCP(fc);
00847 ((MFFieldContainerPtr *) dst_field)->push_back(fc);
00848 }
00849 }
00850 endEditCP(dst, mask);
00851 }
00852 }
00853 }
00854 return dst;
00855 }
00856
00857 FieldContainerPtr OSG::deepClone(const FieldContainerPtr &src,
00858 const std::vector<UInt16> &shareGroupIds)
00859 {
00860 std::vector<std::string> share;
00861 share.reserve(shareGroupIds.size());
00862 for(UInt32 i=0;i<shareGroupIds.size();++i)
00863 {
00864 const char *name = FieldContainerFactory::the()->findGroupName(shareGroupIds[i]);
00865 if(name != NULL)
00866 share.push_back(name);
00867 }
00868 return OSG::deepClone(src, share);
00869 }
00870
00871
00872
00873 FieldContainerPtr OSG::deepClone(const FieldContainerPtr &src,
00874 const std::string &shareString)
00875 {
00876 std::vector<std::string> share;
00877
00878
00879 std::string::const_iterator nextComma;
00880 std::string::const_iterator curPos = shareString.begin();
00881 while(curPos < shareString.end())
00882 {
00883 nextComma = std::find(curPos, shareString.end(), ',');
00884
00885 curPos = std::find_if(curPos, nextComma, std::not1(std::ptr_fun(isspace)));
00886 share.push_back(std::string(curPos, nextComma));
00887 curPos = ++nextComma;
00888 }
00889
00890 return OSG::deepClone(src, share);
00891 }
00892
00893
00894 void OSG::deepCloneAttachments(const NodePtr &src, NodePtr &dst,
00895 const std::vector<std::string> &share)
00896 {
00897 SFAttachmentMap *amap = (SFAttachmentMap *) src->getSFAttachments();
00898
00899 AttachmentMap::const_iterator mapIt = amap->getValue().begin();
00900 AttachmentMap::const_iterator mapEnd = amap->getValue().end();
00901
00902 beginEditCP(dst, Node::AttachmentsFieldMask);
00903 for(; mapIt != mapEnd; ++mapIt)
00904 {
00905 FieldContainerPtr fc = mapIt->second;
00906
00907 bool shareit = false;
00908 for(UInt32 k=0;k<share.size();++k)
00909 {
00910 FieldContainerType *fct = FieldContainerFactory::the()
00911 ->findType(share[k].c_str());
00912 if(fc != NullFC && fct != NULL &&
00913 fc->getType().isDerivedFrom(*fct))
00914 {
00915 shareit = true;
00916 break;
00917 }
00918 }
00919
00920 if(!shareit)
00921 fc = OSG::deepClone(fc, share);
00922
00923 if(fc != NullFC)
00924 dst->addAttachment(AttachmentPtr::dcast(fc));
00925 }
00926 endEditCP(dst, Node::AttachmentsFieldMask);
00927 }
00928
00929 void OSG::deepCloneAttachments(const NodePtr &src, NodePtr &dst,
00930 const std::vector<UInt16> &shareGroupIds)
00931 {
00932 std::vector<std::string> share;
00933 share.reserve(shareGroupIds.size());
00934 for(UInt32 i=0;i<shareGroupIds.size();++i)
00935 {
00936 const char *name = FieldContainerFactory::the()
00937 ->findGroupName(shareGroupIds[i]);
00938 if(name != NULL)
00939 share.push_back(name);
00940 }
00941 OSG::deepCloneAttachments(src, dst, share);
00942 }
00943
00944
00945
00946 void OSG::deepCloneAttachments(const NodePtr &src, NodePtr &dst,
00947 const std::string &shareString)
00948 {
00949 std::vector<std::string> share;
00950
00951
00952 std::string::const_iterator nextComma;
00953 std::string::const_iterator curPos = shareString.begin();
00954 while(curPos < shareString.end())
00955 {
00956 nextComma = std::find(curPos, shareString.end(), ',');
00957
00958 curPos = std::find_if(curPos, nextComma, std::not1(std::ptr_fun(isspace)));
00959 share.push_back(std::string(curPos, nextComma));
00960 curPos = ++nextComma;
00961 }
00962
00963 OSG::deepCloneAttachments(src, dst, share);
00964 }
00965
00966
00967 NodePtr OSG::deepCloneTree(const NodePtr &src,
00968 const std::vector<std::string> &share)
00969 {
00970 NodePtr dst = NullFC;
00971
00972 if(src != NullFC)
00973 {
00974 dst = Node::create();
00975 deepCloneAttachments(src, dst, share);
00976
00977 beginEditCP(dst);
00978 {
00979 dst->setActive(src->getActive());
00980 dst->setTravMask(src->getTravMask());
00981 dst->setCore(NodeCorePtr::dcast(OSG::deepClone(src->getCore(), share)));
00982
00983 for(UInt32 i = 0; i < src->getNChildren(); i++)
00984 dst->addChild(deepCloneTree(src->getChild(i), share));
00985 }
00986 endEditCP (dst);
00987 }
00988
00989 return dst;
00990 }
00991
00992 NodePtr OSG::deepCloneTree(const NodePtr &src,
00993 const std::vector<UInt16> &shareGroupIds)
00994 {
00995 std::vector<std::string> share;
00996 share.reserve(shareGroupIds.size());
00997 for(UInt32 i=0;i<shareGroupIds.size();++i)
00998 {
00999 const char *name = FieldContainerFactory::the()->findGroupName(shareGroupIds[i]);
01000 if(name != NULL)
01001 share.push_back(name);
01002 }
01003 return OSG::deepCloneTree(src, share);
01004 }
01005
01006
01007
01008 NodePtr OSG::deepCloneTree(const NodePtr &src,
01009 const std::string &shareString)
01010 {
01011 std::vector<std::string> share;
01012
01013
01014 std::string::const_iterator nextComma;
01015 std::string::const_iterator curPos = shareString.begin();
01016 while(curPos < shareString.end())
01017 {
01018 nextComma = std::find(curPos, shareString.end(), ',');
01019
01020 curPos = std::find_if(curPos, nextComma, std::not1(std::ptr_fun(isspace)));
01021 share.push_back(std::string(curPos, nextComma));
01022 curPos = ++nextComma;
01023 }
01024
01025 return OSG::deepCloneTree(src, share);
01026 }
01027
01028
01029
01030
01031
01032 #ifdef __sgi
01033 #pragma set woff 1174
01034 #endif
01035
01036 #ifdef OSG_LINUX_ICC
01037 #pragma warning( disable : 177 )
01038 #endif
01039
01040 namespace
01041 {
01042 static Char8 cvsid_cpp[] = "@(#)$Id: $";
01043 static Char8 cvsid_hpp[] = OSGNODE_HEADER_CVSID;
01044 static Char8 cvsid_inl[] = OSGNODE_INLINE_CVSID;
01045 }