octree.cpp
Go to the documentation of this file.
1 
27 #include <boost/serialization/access.hpp>
28 #include <boost/serialization/base_object.hpp>
29 #include <boost/serialization/nvp.hpp>
30 #include <boost/serialization/binary_object.hpp>
31 #include <boost/serialization/split_member.hpp>
32 #include <octomap/octomap.h>
34 
35 #include <tesseract_common/utils.h>
37 
38 namespace tesseract_geometry
39 {
40 Octree::Octree(std::shared_ptr<const octomap::OcTree> octree, OctreeSubType sub_type, bool pruned, bool binary_octree)
42  , octree_(std::move(octree))
43  , sub_type_(sub_type)
44  , pruned_(pruned)
45  , binary_octree_(binary_octree)
46 {
47 }
48 
49 const std::shared_ptr<const octomap::OcTree>& Octree::getOctree() const { return octree_; }
50 
52 
53 bool Octree::getPruned() const { return pruned_; }
54 
55 Geometry::Ptr Octree::clone() const { return std::make_shared<Octree>(octree_, sub_type_); }
56 
58 {
59  long cnt = 0;
60  double occupancy_threshold = octree_->getOccupancyThres();
61  for (auto it = octree_->begin(static_cast<unsigned char>(octree_->getTreeDepth())), end = octree_->end(); it != end;
62  ++it)
63  if (it->getOccupancy() >= occupancy_threshold)
64  ++cnt;
65 
66  return cnt;
67 }
68 
69 bool Octree::isNodeCollapsible(octomap::OcTree& octree, octomap::OcTreeNode* node)
70 {
71  if (!octree.nodeChildExists(node, 0))
72  return false;
73 
74  double occupancy_threshold = octree.getOccupancyThres();
75 
76  const octomap::OcTreeNode* firstChild = octree.getNodeChild(node, 0);
77  if (octree.nodeHasChildren(firstChild) || firstChild->getOccupancy() < occupancy_threshold)
78  return false;
79 
80  for (unsigned int i = 1; i < 8; i++)
81  {
82  // comparison via getChild so that casts of derived classes ensure
83  // that the right == operator gets called
84  if (!octree.nodeChildExists(node, i))
85  return false;
86 
87  if (octree.nodeHasChildren(octree.getNodeChild(node, i)))
88  return false;
89 
90  if (octree.getNodeChild(node, i)->getOccupancy() < occupancy_threshold)
91  return false;
92  }
93 
94  return true;
95 }
96 
97 bool Octree::pruneNode(octomap::OcTree& octree, octomap::OcTreeNode* node)
98 {
99  if (!isNodeCollapsible(octree, node))
100  return false;
101 
102  // set value to children's values (all assumed equal)
103  node->copyData(*(octree.getNodeChild(node, 0)));
104 
105  // delete children (known to be leafs at this point!)
106  for (unsigned int i = 0; i < 8; i++)
107  {
108  octree.deleteNodeChild(node, i);
109  }
110 
111  return true;
112 }
113 
114 // NOLINTNEXTLINE(misc-no-recursion)
115 void Octree::pruneRecurs(octomap::OcTree& octree,
116  octomap::OcTreeNode* node,
117  unsigned int depth,
118  unsigned int max_depth,
119  unsigned int& num_pruned)
120 {
121  assert(node);
122 
123  if (depth < max_depth)
124  {
125  for (unsigned int i = 0; i < 8; i++)
126  {
127  if (octree.nodeChildExists(node, i))
128  {
129  pruneRecurs(octree, octree.getNodeChild(node, i), depth + 1, max_depth, num_pruned);
130  }
131  }
132  } // end if depth
133 
134  else
135  {
136  // max level reached
137  if (pruneNode(octree, node))
138  {
139  num_pruned++;
140  }
141  }
142 }
143 
144 void Octree::prune(octomap::OcTree& octree)
145 {
146  if (octree.getRoot() == nullptr)
147  return;
148 
149  for (unsigned int depth = octree.getTreeDepth() - 1; depth > 0; --depth)
150  {
151  unsigned int num_pruned = 0;
152  pruneRecurs(octree, octree.getRoot(), 0, depth, num_pruned);
153  if (num_pruned == 0)
154  break;
155  }
156 }
157 
158 bool Octree::operator==(const Octree& rhs) const
159 {
160  using namespace tesseract_common;
161 
162  bool equal = true;
163  equal &= Geometry::operator==(rhs);
164  equal &= sub_type_ == rhs.sub_type_;
165  equal &= pruned_ == rhs.pruned_;
166  equal &= resolution_ == rhs.resolution_;
167 
168  // octree_ == rhs.octree_ looks for exact double equality
169  equal &= octree_->getTreeDepth() == rhs.octree_->getTreeDepth(); // tree_depth
170  equal &= almostEqualRelativeAndAbs(octree_->getResolution(), rhs.octree_->getResolution()); // resolution
171  equal &= octree_->size() == rhs.octree_->size(); // tree_size
172  equal &= octree_->getNumLeafNodes() == rhs.octree_->getNumLeafNodes();
173  equal &= calcNumSubShapes() == rhs.calcNumSubShapes();
174 
175  for (auto it = octree_->begin(static_cast<unsigned char>(octree_->getTreeDepth())), end = octree_->end(); it != end;
176  ++it)
177  {
178  const auto coord = it.getCoordinate();
179  const auto* node = rhs.octree_->search(coord);
180 
181  if (node != nullptr)
182  {
183  equal &= almostEqualRelativeAndAbs(it->getValue(), node->getValue());
184  equal &= almostEqualRelativeAndAbs(it->getOccupancy(), node->getOccupancy());
185  }
186  else
187  return false;
188  }
189 
190  return equal;
191 }
192 bool Octree::operator!=(const Octree& rhs) const { return !operator==(rhs); }
193 
194 template <class Archive>
195 void Octree::save(Archive& ar, const unsigned int /*version*/) const
196 {
197  using namespace boost::serialization;
198  ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(Geometry);
199  ar& BOOST_SERIALIZATION_NVP(sub_type_);
200  ar& BOOST_SERIALIZATION_NVP(resolution_);
201  ar& BOOST_SERIALIZATION_NVP(pruned_);
202  ar& BOOST_SERIALIZATION_NVP(binary_octree_);
203 
204  // Read the data to a stream which does not guarantee contiguous memory
205  std::ostringstream s;
206  if (binary_octree_)
207  octree_->writeBinaryConst(s);
208  else
209  octree_->write(s);
210 
211  // Write it to a string, wich does guarantee contiguous memory
212  std::string data_string = s.str();
213  std::size_t octree_data_size = data_string.size();
214  ar& make_nvp("octree_data_size", octree_data_size);
215  ar& make_nvp("octree_data", make_binary_object(data_string.data(), octree_data_size));
216 }
217 
218 template <class Archive>
219 void Octree::load(Archive& ar, const unsigned int /*version*/)
220 {
221  using namespace boost::serialization;
222  ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(Geometry);
223  ar& BOOST_SERIALIZATION_NVP(sub_type_);
224  ar& BOOST_SERIALIZATION_NVP(resolution_);
225  ar& BOOST_SERIALIZATION_NVP(pruned_);
226  ar& BOOST_SERIALIZATION_NVP(binary_octree_);
227 
228  // Initialize the octree to the right size
229  auto local_octree = std::make_shared<octomap::OcTree>(resolution_);
230 
231  // Read the data into a string
232  std::size_t octree_data_size = 0;
233  ar& make_nvp("octree_data_size", octree_data_size);
234  std::string data_string;
235  data_string.resize(octree_data_size);
236  ar& make_nvp("octree_data", make_binary_object(data_string.data(), octree_data_size));
237 
238  // Write that data into the stringstream required by octree and load data
239  std::stringstream s;
240  s.write(data_string.data(), static_cast<std::streamsize>(octree_data_size));
241 
242  if (binary_octree_)
243  local_octree->readBinary(s);
244  else
245  local_octree = std::shared_ptr<octomap::OcTree>(dynamic_cast<octomap::OcTree*>(octomap::OcTree::read(s)));
246 
247  octree_ = local_octree;
248 }
249 
250 template <class Archive>
251 void Octree::serialize(Archive& ar, const unsigned int version)
252 {
253  boost::serialization::split_member(ar, *this, version);
254 }
255 } // namespace tesseract_geometry
256 
258 BOOST_CLASS_EXPORT_IMPLEMENT(tesseract_geometry::Octree)
tesseract_geometry::Geometry::Ptr
std::shared_ptr< Geometry > Ptr
Definition: geometry.h:72
tesseract_common
tesseract_geometry::Octree::pruneNode
static bool pruneNode(octomap::OcTree &octree, octomap::OcTreeNode *node)
Definition: octree.cpp:97
tesseract_geometry::Octree::binary_octree_
bool binary_octree_
Definition: octree.h:102
tesseract_geometry::Octree
Definition: octree.h:58
tesseract_geometry::Geometry
Definition: geometry.h:69
tesseract_geometry::Octree::octree_
std::shared_ptr< const octomap::OcTree > octree_
Definition: octree.h:98
utils.h
tesseract_geometry::Octree::Octree
Octree()=default
tesseract_geometry::GeometryType
GeometryType
Definition: geometry.h:48
almostEqualRelativeAndAbs
bool almostEqualRelativeAndAbs(const Eigen::Ref< const Eigen::VectorXd > &v1, const Eigen::Ref< const Eigen::VectorXd > &v2, const Eigen::Ref< const Eigen::VectorXd > &max_diff, const Eigen::Ref< const Eigen::VectorXd > &max_rel_diff)
tesseract_geometry::Octree::save
void save(Archive &ar, const unsigned int version) const
Definition: octree.cpp:195
TESSERACT_COMMON_IGNORE_WARNINGS_PUSH
#define TESSERACT_COMMON_IGNORE_WARNINGS_PUSH
tesseract_geometry::Octree::pruneRecurs
static void pruneRecurs(octomap::OcTree &octree, octomap::OcTreeNode *node, unsigned int depth, unsigned int max_depth, unsigned int &num_pruned)
Definition: octree.cpp:115
tesseract_geometry::Octree::getOctree
const std::shared_ptr< const octomap::OcTree > & getOctree() const
Definition: octree.cpp:49
tesseract_geometry::Geometry::operator==
bool operator==(const Geometry &rhs) const
Definition: geometry.cpp:48
tesseract_geometry::Octree::load
void load(Archive &ar, const unsigned int version)
Definition: octree.cpp:219
serialization.h
tesseract_geometry::Octree::operator==
bool operator==(const Octree &rhs) const
Definition: octree.cpp:158
tesseract_geometry::Octree::getSubType
OctreeSubType getSubType() const
Definition: octree.cpp:51
TESSERACT_SERIALIZE_SAVE_LOAD_ARCHIVES_INSTANTIATE
#define TESSERACT_SERIALIZE_SAVE_LOAD_ARCHIVES_INSTANTIATE(Type)
boost::serialization
tesseract_geometry::Octree::clone
Geometry::Ptr clone() const override final
Create a copy of this shape.
Definition: octree.cpp:55
tesseract_geometry::Octree::pruned_
bool pruned_
Definition: octree.h:101
TESSERACT_COMMON_IGNORE_WARNINGS_POP
#define TESSERACT_COMMON_IGNORE_WARNINGS_POP
tesseract_geometry::Octree::isNodeCollapsible
static bool isNodeCollapsible(octomap::OcTree &octree, octomap::OcTreeNode *node)
Definition: octree.cpp:69
tesseract_geometry::Octree::operator!=
bool operator!=(const Octree &rhs) const
Definition: octree.cpp:192
tesseract_geometry
Definition: fwd.h:31
tesseract_geometry::Octree::getPruned
bool getPruned() const
Definition: octree.cpp:53
tesseract_geometry::GeometryType::OCTREE
@ OCTREE
tesseract_geometry::Octree::prune
static void prune(octomap::OcTree &octree)
A custom octree prune which will prune if all children are above the occupancy threshold.
Definition: octree.cpp:144
macros.h
octree.h
Tesseract Octree Geometry.
tesseract_geometry::Octree::calcNumSubShapes
long calcNumSubShapes() const
Calculate the number of sub shapes that would get generated for this octree.
Definition: octree.cpp:57
tesseract_geometry::OctreeSubType
OctreeSubType
Definition: octree.h:51
tesseract_geometry::Octree::sub_type_
OctreeSubType sub_type_
Definition: octree.h:99
tesseract_geometry::Octree::resolution_
double resolution_
Definition: octree.h:100
tesseract_geometry::Octree::serialize
void serialize(Archive &ar, const unsigned int version)
Definition: octree.cpp:251


tesseract_geometry
Author(s): Levi Armstrong
autogenerated on Sun May 18 2025 03:01:46