00001 #include "SplicingVisitor.hxx"
00002 
00003 namespace simgear
00004 {
00005 using namespace osg;
00006 
00007 SplicingVisitor::SplicingVisitor()
00008     : NodeVisitor(NodeVisitor::TRAVERSE_ALL_CHILDREN)
00009 {
00010     _childStack.push_back(NodeList());
00011 }
00012 
00013 void SplicingVisitor::reset()
00014 {
00015     _childStack.clear();
00016     NodeVisitor::reset();
00017 }
00018 
00019 NodeList SplicingVisitor::traverse(Node& node)
00020 {
00021     NodeList result;
00022     _childStack.push_back(NodeList());
00023     NodeVisitor::traverse(node);
00024     result = _childStack.back();
00025     _childStack.pop_back();
00026     return result;
00027 }
00028 void SplicingVisitor::apply(Node& node)
00029 {
00030     NodeVisitor::traverse(node);
00031     pushNode(&node);
00032 }
00033 
00034 void SplicingVisitor::apply(Group& node)
00035 {
00036     if (pushNode(getNewNode(node)))
00037         return;
00038     pushResultNode(&node, &node, traverse(node));
00039 }
00040 
00041 Group* SplicingVisitor::pushResultNode(Group* node, Group* newNode,
00042                                        const NodeList& children)
00043 {
00044     ref_ptr<Group> result;
00045     if (node == newNode) {
00046         result = copyIfNeeded(*node, children);
00047     } else {
00048         result = newNode;
00049         for (NodeList::const_iterator itr = children.begin(), end = children.end();
00050              itr != end;
00051              ++itr)
00052             result->addChild(itr->get());
00053     }
00054     _childStack.back().push_back(result);
00055     recordNewNode(node, result);
00056     return result;
00057 }
00058 
00059 Node* SplicingVisitor::pushResultNode(Node* node, Node* newNode)
00060 {
00061     _childStack.back().push_back(newNode);
00062     recordNewNode(node, newNode);
00063     return newNode;
00064 }
00065 
00066 Node* SplicingVisitor::pushNode(Node* node)
00067 {
00068     if (node)
00069         _childStack.back().push_back(node);
00070     return node;
00071 }
00072 
00073 Node* SplicingVisitor::getResult()
00074 {
00075     NodeList& top = _childStack.at(0);
00076     if (top.empty()) {
00077         return 0;
00078     } else if (top.size() == 1) {
00079         return top[0].get();
00080     } else {
00081         Group* result = new Group;
00082         for (NodeList::iterator itr = top.begin(), end = top.end();
00083              itr != end;
00084              ++itr)
00085             result->addChild(itr->get());
00086         return result;
00087     }
00088 }
00089 
00090 Node* SplicingVisitor::getNewNode(osg::Node* node)
00091 {
00092     ref_ptr<Node> tmpPtr(node);
00093     NodeMap::iterator itr;
00094     try {
00095         itr = _visited.find(tmpPtr);
00096     }
00097     catch (...) {
00098         tmpPtr.release();
00099         throw;
00100     }
00101     if (itr == _visited.end())
00102         return 0;
00103     else
00104         return itr->second.get();
00105 }
00106 
00107 bool SplicingVisitor::recordNewNode(osg::Node* oldNode, osg::Node* newNode)
00108 {
00109     ref_ptr<Node> oldTmp(oldNode);
00110     ref_ptr<Node> newTmp(newNode);
00111     return _visited.insert(std::make_pair(oldTmp, newTmp)).second;
00112 }
00113 }