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 }