diff --git a/examples/osgcopy/osgcopy.cpp b/examples/osgcopy/osgcopy.cpp index 1b5eaa56a..a21f44b9f 100644 --- a/examples/osgcopy/osgcopy.cpp +++ b/examples/osgcopy/osgcopy.cpp @@ -127,6 +127,50 @@ class MyCopyOp : public osg::CopyOp mutable int _step; }; +// this CopyOp class will preserve the multi-parent structure of the copied +// object, instead of expanding it into a tree. Works with the +// DEEP_COPY_NODES flag. +class GraphCopyOp : public osg::CopyOp +{ + public: + + inline GraphCopyOp(CopyFlags flags=SHALLOW_COPY): + osg::CopyOp(flags) { _nodeCopyMap.clear();} + + virtual osg::Node* operator() (const osg::Node* node) const + { + if (node && _flags&DEEP_COPY_NODES) + { + if ( node->getNumParents() > 1 ) + { + if ( _nodeCopyMap.find(node) != _nodeCopyMap.end() ) + { + std::cout<<"Copy of node "<getName()<<", " + << _nodeCopyMap[node]<<", will be reused"<( node->clone(*this) ); + _nodeCopyMap[node] = newNode; + return newNode; + } + } + else + return dynamic_cast( node->clone(*this) ); + } + else + return const_cast(node); + } + + protected: + + // must be mutable since CopyOp is passed around as const to + // the various clone/copy constructors. + mutable std::map _nodeCopyMap; + +}; + int main( int argc, char **argv ) { // use an ArgumentParser object to manage the program arguments. @@ -151,17 +195,23 @@ int main( int argc, char **argv ) // do a deep copy, using MyCopyOp to reveal whats going on under the good, // in your own code you'd typically just use the basic osg::CopyOp something like - // osg::Node* mycopy = dynamic_cast(rootnode->clone(osg::CopyOp::DEEP_COPY_ALL)); + osg::ref_ptr mycopy = dynamic_cast(rootnode->clone(osg::CopyOp::DEEP_COPY_ALL)); std::cout << "Doing a deep copy of scene graph"<(rootnode->clone(MyCopyOp(osg::CopyOp::DEEP_COPY_ALL))); + osg::ref_ptr deep_copy = dynamic_cast(rootnode->clone(MyCopyOp(osg::CopyOp::DEEP_COPY_ALL))); std::cout << "----------------------------------------------------------------"< graph_copy = dynamic_cast(rootnode->clone(GraphCopyOp(osg::CopyOp::DEEP_COPY_NODES))); + + // do a shallow copy. std::cout << "Doing a shallow copy of scene graph"<(rootnode->clone(MyCopyOp(osg::CopyOp::SHALLOW_COPY))); + osg::ref_ptr shallow_copy = dynamic_cast(rootnode->clone(MyCopyOp(osg::CopyOp::SHALLOW_COPY))); // write out the various scene graphs so that they can be browsed, either @@ -169,6 +219,9 @@ int main( int argc, char **argv ) std::cout << std::endl << "Writing out the original scene graph as 'original.osg'"<