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 }