octomap 1.5.0
|
00001 // $Id: OcTreeDataNode.hxx 397 2012-08-02 13:34:36Z ahornung $ 00002 00011 /* 00012 * Copyright (c) 2009, K. M. Wurm, A. Hornung, University of Freiburg 00013 * All rights reserved. 00014 * 00015 * Redistribution and use in source and binary forms, with or without 00016 * modification, are permitted provided that the following conditions are met: 00017 * 00018 * * Redistributions of source code must retain the above copyright 00019 * notice, this list of conditions and the following disclaimer. 00020 * * Redistributions in binary form must reproduce the above copyright 00021 * notice, this list of conditions and the following disclaimer in the 00022 * documentation and/or other materials provided with the distribution. 00023 * * Neither the name of the University of Freiburg nor the names of its 00024 * contributors may be used to endorse or promote products derived from 00025 * this software without specific prior written permission. 00026 * 00027 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00028 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00029 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00030 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00031 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00032 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00033 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00034 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00035 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00036 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00037 * POSSIBILITY OF SUCH DAMAGE. 00038 */ 00039 00040 namespace octomap { 00041 00042 template <typename T> 00043 OcTreeDataNode<T>::OcTreeDataNode() 00044 : children(NULL) 00045 { 00046 00047 } 00048 00049 template <typename T> 00050 OcTreeDataNode<T>::OcTreeDataNode(T initVal) 00051 : children(NULL), value(initVal) 00052 { 00053 00054 } 00055 00056 template <typename T> 00057 OcTreeDataNode<T>::OcTreeDataNode(const OcTreeDataNode<T>& rhs) 00058 : children(NULL), value(rhs.value) 00059 { 00060 if (rhs.hasChildren()){ 00061 allocChildren(); 00062 for (unsigned i = 0; i<8; ++i){ 00063 if (rhs.children[i]) 00064 children[i] = new OcTreeDataNode<T>(*(rhs.children[i])); 00065 00066 } 00067 } 00068 } 00069 00070 00071 00072 template <typename T> 00073 OcTreeDataNode<T>::~OcTreeDataNode() 00074 { 00075 if (children != NULL) { 00076 for (unsigned int i=0; i<8; i++) { 00077 if (children[i] != NULL) delete children[i]; 00078 } 00079 delete[] children; 00080 } 00081 00082 } 00083 00084 template <typename T> 00085 bool OcTreeDataNode<T>::operator== (const OcTreeDataNode<T>& rhs) const{ 00086 return rhs.value == value; 00087 } 00088 00089 // ============================================================ 00090 // = children ======================================= 00091 // ============================================================ 00092 00093 template <typename T> 00094 bool OcTreeDataNode<T>::createChild(unsigned int i) { 00095 if (children == NULL) { 00096 allocChildren(); 00097 } 00098 assert (children[i] == NULL); 00099 children[i] = new OcTreeDataNode<T>(); 00100 return true; 00101 } 00102 00103 template <typename T> 00104 bool OcTreeDataNode<T>::childExists(unsigned int i) const { 00105 assert(i < 8); 00106 if ((children != NULL) && (children[i] != NULL)) 00107 return true; 00108 else 00109 return false; 00110 } 00111 00112 template <typename T> 00113 void OcTreeDataNode<T>::deleteChild(unsigned int i) { 00114 assert((i < 8) && (children != NULL)); 00115 assert(children[i] != NULL); 00116 delete children[i]; 00117 children[i] = NULL; 00118 } 00119 00120 template <typename T> 00121 OcTreeDataNode<T>* OcTreeDataNode<T>::getChild(unsigned int i) { 00122 assert((i < 8) && (children != NULL)); 00123 assert(children[i] != NULL); 00124 return children[i]; 00125 } 00126 00127 template <typename T> 00128 const OcTreeDataNode<T>* OcTreeDataNode<T>::getChild(unsigned int i) const { 00129 assert((i < 8) && (children != NULL)); 00130 assert(children[i] != NULL); 00131 return children[i]; 00132 } 00133 00134 template <typename T> 00135 bool OcTreeDataNode<T>::hasChildren() const { 00136 if (children == NULL) return false; 00137 for (unsigned int i = 0; i<8; i++) 00138 if (childExists(i)) return true; 00139 return false; 00140 } 00141 00142 // ============================================================ 00143 // = pruning ======================================= 00144 // ============================================================ 00145 00146 00147 template <typename T> 00148 bool OcTreeDataNode<T>::collapsible() const { 00149 // all children must exist, must not have children of 00150 // their own and have the same occupancy probability 00151 if (!childExists(0) || getChild(0)->hasChildren()) 00152 return false; 00153 00154 T childValue = getChild(0)->getValue(); 00155 00156 for (unsigned int i = 1; i<8; i++) { 00157 if (!childExists(i)) return false; 00158 else if (getChild(i)->hasChildren()) return false; 00159 else if (! (getChild(i)->getValue() == childValue)) return false; 00160 } 00161 return true; 00162 } 00163 00164 template <typename T> 00165 bool OcTreeDataNode<T>::pruneNode() { 00166 00167 if (!this->collapsible()) 00168 return false; 00169 00170 // set value to children's values (all assumed equal) 00171 setValue(getChild(0)->getValue()); 00172 00173 // delete children 00174 for (unsigned int i=0;i<8;i++) { 00175 delete children[i]; 00176 } 00177 delete[] children; 00178 children = NULL; 00179 00180 return true; 00181 } 00182 00183 template <typename T> 00184 void OcTreeDataNode<T>::expandNode() { 00185 assert(!hasChildren()); 00186 00187 for (unsigned int k=0; k<8; k++) { 00188 createChild(k); 00189 children[k]->setValue(value); 00190 } 00191 } 00192 00193 // ============================================================ 00194 // = File IO ======================================= 00195 // ============================================================ 00196 00197 template <typename T> 00198 std::istream& OcTreeDataNode<T>::readValue(std::istream &s) { 00199 00200 char children_char; 00201 00202 // read data: 00203 s.read((char*) &value, sizeof(value)); 00204 s.read((char*)&children_char, sizeof(char)); 00205 std::bitset<8> children ((unsigned long long) children_char); 00206 00207 // std::cout << "read: " << value << " " 00208 // << children.to_string<char,std::char_traits<char>,std::allocator<char> >() 00209 // << std::endl; 00210 00211 for (unsigned int i=0; i<8; i++) { 00212 if (children[i] == 1){ 00213 createChild(i); 00214 getChild(i)->readValue(s); 00215 } 00216 } 00217 return s; 00218 } 00219 00220 00221 template <typename T> 00222 std::ostream& OcTreeDataNode<T>::writeValue(std::ostream &s) const{ 00223 00224 // 1 bit for each children; 0: empty, 1: allocated 00225 std::bitset<8> children; 00226 00227 for (unsigned int i=0; i<8; i++) { 00228 if (childExists(i)) 00229 children[i] = 1; 00230 else 00231 children[i] = 0; 00232 } 00233 00234 char children_char = (char) children.to_ulong(); 00235 s.write((const char*) &value, sizeof(value)); 00236 s.write((char*)&children_char, sizeof(char)); 00237 00238 // std::cout << "wrote: " << value << " " 00239 // << children.to_string<char,std::char_traits<char>,std::allocator<char> >() 00240 // << std::endl; 00241 00242 // write children's children 00243 for (unsigned int i=0; i<8; i++) { 00244 if (children[i] == 1) { 00245 this->getChild(i)->writeValue(s); 00246 } 00247 } 00248 return s; 00249 } 00250 00251 00252 // ============================================================ 00253 // = private methodes ======================================= 00254 // ============================================================ 00255 template <typename T> 00256 void OcTreeDataNode<T>::allocChildren() { 00257 children = new OcTreeDataNode<T>*[8]; 00258 for (unsigned int i=0; i<8; i++) { 00259 children[i] = NULL; 00260 } 00261 } 00262 00263 00264 } // end namespace 00265