Show
Ignore:
Timestamp:
02/09/07 15:54:54 (8 years ago)
Author:
robert
Message:

From Yefei He, " I wrote a class derived from CopyOp? that preserves the multi-parent
structure of scene graphs. I only considered the case of DEEP_COPY_NODES,
but it is sufficient for me. It is not the most elegant way -- I used
a map to list all the already cloned nodes with multiple parents, to be
looked up whenever such a node is revisited. The good part is, it works."

From Robert Osfield, fixed build problems under Linux 64 due to use of int's to store Node*
in internal maps used in above custom CopyOp?. Added ref_ptr<> usage to main to
prevent memory leaks

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/examples/osgcopy/osgcopy.cpp

    r5923 r6137  
    126126        mutable int _indent; 
    127127        mutable int _step; 
     128}; 
     129 
     130// this CopyOp class will preserve the multi-parent structure of the copied  
     131// object, instead of expanding it into a tree. Works with the  
     132// DEEP_COPY_NODES flag. 
     133class GraphCopyOp : public osg::CopyOp 
     134{ 
     135    public: 
     136     
     137        inline GraphCopyOp(CopyFlags flags=SHALLOW_COPY): 
     138            osg::CopyOp(flags) { _nodeCopyMap.clear();} 
     139             
     140        virtual osg::Node* operator() (const osg::Node* node) const 
     141        { 
     142            if (node && _flags&DEEP_COPY_NODES) 
     143            { 
     144                if ( node->getNumParents() > 1 ) 
     145                { 
     146                    if ( _nodeCopyMap.find(node) != _nodeCopyMap.end() ) 
     147                    { 
     148                        std::cout<<"Copy of node "<<node<<" "<<node->getName()<<", " 
     149                            << _nodeCopyMap[node]<<", will be reused"<<std::endl; 
     150                        return (osg::Node*)(_nodeCopyMap[node]); 
     151                    } 
     152                    else 
     153                    { 
     154                        osg::Node* newNode = dynamic_cast<osg::Node*>( node->clone(*this) ); 
     155                        _nodeCopyMap[node] = newNode; 
     156                        return newNode; 
     157                    } 
     158                } 
     159                else 
     160                    return dynamic_cast<osg::Node*>( node->clone(*this) ); 
     161            } 
     162            else 
     163                return const_cast<osg::Node*>(node); 
     164        } 
     165          
     166    protected: 
     167     
     168        // must be mutable since CopyOp is passed around as const to 
     169        // the various clone/copy constructors. 
     170        mutable std::map<const osg::Node*,osg::Node*> _nodeCopyMap; 
     171 
    128172}; 
    129173 
     
    152196    // do a deep copy, using MyCopyOp to reveal whats going on under the good, 
    153197    // in your own code you'd typically just use the basic osg::CopyOp something like 
    154     // osg::Node* mycopy = dynamic_cast<osg::Node*>(rootnode->clone(osg::CopyOp::DEEP_COPY_ALL)); 
     198    osg::ref_ptr<osg::Node> mycopy = dynamic_cast<osg::Node*>(rootnode->clone(osg::CopyOp::DEEP_COPY_ALL)); 
    155199    std::cout << "Doing a deep copy of scene graph"<<std::endl; 
     200 
    156201    // note, we need the dyanmic_cast because MS Visual Studio can't handle covarient 
    157202    // return types, so that clone has return just Object*.  bahh hum bug 
    158     osg::Node* deep_copy = dynamic_cast<osg::Node*>(rootnode->clone(MyCopyOp(osg::CopyOp::DEEP_COPY_ALL))); 
     203    osg::ref_ptr<osg::Node> deep_copy = dynamic_cast<osg::Node*>(rootnode->clone(MyCopyOp(osg::CopyOp::DEEP_COPY_ALL))); 
    159204     
    160205    std::cout << "----------------------------------------------------------------"<<std::endl; 
     206 
     207    // do a graph preserving deep copy. 
     208    std::cout << "Doing a graph preserving deep copy of scene graph nodes"<<std::endl; 
     209    osg::ref_ptr<osg::Node> graph_copy = dynamic_cast<osg::Node*>(rootnode->clone(GraphCopyOp(osg::CopyOp::DEEP_COPY_NODES))); 
     210 
    161211 
    162212    // do a shallow copy. 
    163213    std::cout << "Doing a shallow copy of scene graph"<<std::endl; 
    164     osg::Node* shallow_copy = dynamic_cast<osg::Node*>(rootnode->clone(MyCopyOp(osg::CopyOp::SHALLOW_COPY))); 
     214    osg::ref_ptr<osg::Node> shallow_copy = dynamic_cast<osg::Node*>(rootnode->clone(MyCopyOp(osg::CopyOp::SHALLOW_COPY))); 
    165215 
    166216 
     
    169219    std::cout << std::endl << "Writing out the original scene graph as 'original.osg'"<<std::endl; 
    170220    osgDB::writeNodeFile(*rootnode,"original.osg"); 
     221 
     222    std::cout << std::endl << "Writing out the graph preserving scene graph as 'graph_copy.osg'"<<std::endl; 
     223    osgDB::writeNodeFile(*graph_copy,"graph_copy.osg"); 
    171224 
    172225    std::cout << "Writing out the deep copied scene graph as 'deep_copy.osg'"<<std::endl; 
     
    205258    viewer.setSceneData(rootnode); 
    206259 
     260    // viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded); 
     261 
    207262    return viewer.run(); 
    208263}