Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef ApproxMVBB_KdTreeXml_hpp
00011 #define ApproxMVBB_KdTreeXml_hpp
00012
00013 #ifndef ApproxMVBB_SUPPORT_XML
00014 #warning "Your using the KdTreeXml header, which needs to be linked with the Xml library!"
00015 #endif
00016
00017 #include <pugixml.hpp>
00018
00019 #include "KdTree.hpp"
00020
00021
00022 namespace ApproxMVBB{
00023
00024 namespace KdTree {
00025
00026 class XML {
00027
00028 public:
00029 using XMLNodeType = pugi::xml_node;
00030
00032 template<typename TTraits>
00033 static void appendToXML(PointData<TTraits> const & obj, XMLNodeType & root){
00034 using PointGetter = typename PointData<TTraits>::PointGetter;
00035 static const auto nodePCData = pugi::node_pcdata;
00036 XMLNodeType node = root.append_child("Points");
00037 std::stringstream ss;
00038 for(auto & p : obj){
00039 ss << PointGetter::get(p).transpose().format(MyMatrixIOFormat::SpaceSep) << std::endl;
00040 }
00041 node.append_child(nodePCData).set_value( ss.str().c_str() );
00042 }
00043
00045 template<typename Traits>
00046 static void appendToXML(TreeBase<Traits> const & obj, XMLNodeType kdNode){
00047 using NodeType = typename TreeBase<Traits>::NodeType;
00048 static const auto nodePCData = pugi::node_pcdata;
00049 std::stringstream ss;
00050 XMLNodeType r = kdNode.append_child("Root");
00051 XMLNodeType aabb = r.append_child("AABB");
00052 ss.str("");
00053 ss << obj.m_root->aabb().m_minPoint.transpose().format(MyMatrixIOFormat::SpaceSep) <<" "
00054 << obj.m_root->aabb().m_maxPoint.transpose().format(MyMatrixIOFormat::SpaceSep) << "\n";
00055 aabb.append_child(nodePCData).set_value(ss.str().c_str());
00056
00057
00058 XMLNodeType leafs = kdNode.append_child("Leafs");
00059
00060 for(auto * l: obj.m_leafs) {
00061 XMLNodeType node = leafs.append_child("Leaf");
00062 node.append_attribute("level").set_value(l->getLevel());
00063 node.append_attribute("idx").set_value(std::to_string(l->getIdx()).c_str());
00064 aabb = node.append_child("AABB");
00065 ss.str("");
00066 ss << l->aabb().m_minPoint.transpose().format(MyMatrixIOFormat::SpaceSep) <<" "
00067 << l->aabb().m_maxPoint.transpose().format(MyMatrixIOFormat::SpaceSep) << "\n";
00068 aabb.append_child(nodePCData).set_value(ss.str().c_str());
00069 }
00070
00071
00072 XMLNodeType aabbTree = kdNode.append_child("AABBTree");
00073 std::deque<NodeType*> q;
00074
00075 q.push_back(obj.m_root);
00076 unsigned int currLevel = obj.m_root->getLevel();
00077 ss.str("");
00078 while(q.size()>0) {
00079
00080 auto * f = q.front();
00081
00082 if(f->getLevel() > currLevel) {
00083
00084 aabb = aabbTree.append_child("AABBSubTree");
00085 aabb.append_attribute("level").set_value(currLevel);
00086 aabb.append_child(nodePCData).set_value( ss.str().c_str() );
00087
00088 currLevel = f->getLevel();
00089 ss.str("");
00090 }
00091
00092 if(!f->isLeaf()) {
00093 ss << f->aabb().m_minPoint.transpose().format(MyMatrixIOFormat::SpaceSep) <<" "
00094 << f->aabb().m_maxPoint.transpose().format(MyMatrixIOFormat::SpaceSep) << "\n";
00095 }
00096
00097
00098 auto * n = f->leftNode();
00099 if(n) {
00100 q.push_back(n);
00101 }
00102 n = f->rightNode();
00103 if(n) {
00104 q.push_back(n);
00105 }
00106
00107 q.pop_front();
00108 }
00109
00110
00111 auto s = ss.str();
00112 if(!s.empty()) {
00113 aabb = aabbTree.append_child("AABBSubTree");
00114 aabb.append_attribute("level").set_value(currLevel);
00115 aabb.append_child(nodePCData).set_value( s.c_str() );
00116 }
00117 }
00119 static void appendToXML(const TreeStatistics & obj, XMLNodeType & kdNode){
00120
00121 auto stat = kdNode.append_child("Statistics");
00122
00123 stat.append_attribute("m_computedTreeStats").set_value( obj.m_computedTreeStats );
00124 stat.append_attribute("m_treeDepth").set_value( obj.m_treeDepth );
00125 stat.append_attribute("m_avgSplitPercentage").set_value( obj.m_avgSplitPercentage );
00126 stat.append_attribute("m_minLeafExtent").set_value( obj.m_minLeafExtent );
00127 stat.append_attribute("m_maxLeafExtent").set_value( obj.m_maxLeafExtent );
00128 stat.append_attribute("m_avgLeafSize").set_value( obj.m_avgLeafSize );
00129 stat.append_attribute("m_minLeafDataSize").set_value( (long long unsigned int)obj.m_minLeafDataSize );
00130 stat.append_attribute("m_maxLeafDataSize").set_value( (long long unsigned int)obj.m_maxLeafDataSize );
00131 stat.append_attribute("m_computedNeighbourStats").set_value( (long long unsigned int)obj.m_computedNeighbourStats );
00132 stat.append_attribute("m_minNeighbours").set_value( (long long unsigned int)obj.m_minNeighbours );
00133 stat.append_attribute("m_maxNeighbours").set_value( (long long unsigned int)obj.m_maxNeighbours );
00134 stat.append_attribute("m_avgNeighbours").set_value( obj.m_avgNeighbours );
00135 }
00136
00138 template<typename TTraits>
00139 static void appendToXML(const Tree<TTraits> & obj, XMLNodeType & root, bool aligned = true,
00140 const Matrix33 & A_IK = Matrix33::Identity()
00141 ) {
00142 using Base = typename Tree<TTraits>::Base;
00143
00144 static const auto nodePCData = pugi::node_pcdata;
00145
00146 std::stringstream ss;
00147 XMLNodeType node;
00148 XMLNodeType kdNode = root.append_child("KdTree");
00149
00150 kdNode.append_attribute("aligned").set_value( aligned );
00151
00152 XMLNodeType a = kdNode.append_child("A_IK");
00153 ss << A_IK.format(MyMatrixIOFormat::SpaceSep);
00154 a.append_child(nodePCData).set_value(ss.str().c_str());
00155
00156 appendToXML(static_cast<const Base &>(obj), kdNode);
00157
00158 appendToXML(obj.m_statistics, kdNode);
00159
00160 }
00161
00163 template<typename TTraits>
00164 static void appendToXML(const TreeSimple<TTraits> & obj,
00165 XMLNodeType root,
00166 bool aligned = true,
00167 const Matrix33 & A_IK = Matrix33::Identity()) {
00168 using Base = typename TreeSimple<TTraits>::Base;
00169 static const auto nodePCData = pugi::node_pcdata;
00170
00171 std::stringstream ss;
00172 XMLNodeType node;
00173 XMLNodeType kdNode = root.append_child("KdTree");
00174
00175 kdNode.append_attribute("aligned").set_value( aligned );
00176
00177 XMLNodeType a = kdNode.append_child("A_IK");
00178 ss << A_IK.format(MyMatrixIOFormat::SpaceSep);
00179 a.append_child(nodePCData).set_value(ss.str().c_str());
00180
00181 appendToXML(static_cast<const Base &>(obj), kdNode);
00182 appendToXML(obj.m_statistics, kdNode);
00183
00184 }
00185
00186 };
00187
00188 }
00189 }
00190 #endif