33 constexpr
float kPrecision = 0.001f;
34 constexpr
int kBitsPerCoordinate = 10;
35 constexpr
int kCoordinateMask = (1 << kBitsPerCoordinate) - 1;
36 constexpr
int kMaxBitsPerDirection = 23;
42 : compressed_point_cloud_(compressed_point_cloud),
43 remaining_points_(compressed_point_cloud->num_points_),
44 remaining_points_in_current_block_(0),
45 input_(compressed_point_cloud->point_data_.begin()) {
82 for (
int i = 0; i < 3; ++i) {
87 const int point = *
input_++;
88 constexpr
int kMask = (1 << kBitsPerCoordinate) - 1;
92 ((point >> kBitsPerCoordinate) & kMask)) *
103 Eigen::Array3i point;
107 Blocks blocks(kPrecision);
109 CHECK_LE(point_cloud.size(), std::numeric_limits<int>::max());
110 for (
int point_index = 0; point_index < static_cast<int>(point_cloud.size());
112 const Eigen::Vector3f& point = point_cloud[point_index];
113 CHECK_LT(point.cwiseAbs().maxCoeff() / kPrecision,
114 1 << kMaxBitsPerDirection)
115 <<
"Point out of bounds: " << point;
116 Eigen::Array3i raster_point;
117 Eigen::Array3i block_coordinate;
118 for (
int i = 0; i < 3; ++i) {
120 block_coordinate[i] = raster_point[i] >> kBitsPerCoordinate;
121 raster_point[i] &= kCoordinateMask;
123 auto*
const block = blocks.mutable_value(block_coordinate);
124 num_blocks += block->empty();
125 block->push_back({raster_point, point_index});
129 point_data_.reserve(4 * num_blocks + point_cloud.size());
130 for (Blocks::Iterator it(blocks); !it.Done(); it.Next(), --num_blocks) {
131 const auto& raster_points = it.GetValue();
132 CHECK_LE(raster_points.size(), std::numeric_limits<int32>::max());
134 const Eigen::Array3i block_coordinate = it.GetCellIndex();
138 for (
const RasterPoint& raster_point : raster_points) {
139 point_data_.push_back((((raster_point.point.z() << kBitsPerCoordinate) +
140 raster_point.point.y())
141 << kBitsPerCoordinate) +
142 raster_point.point.x());
145 CHECK_EQ(num_blocks, 0);
166 for (
const Eigen::Vector3f& point : *
this) {
167 decompressed.push_back(point);
173 proto::CompressedPointCloud result;
176 result.add_point_data(data);
PointCloud Decompress() const
std::vector< int32 > point_data_
bool operator!=(const ConstIterator &it) const
int RoundToInt(const float x)
ConstIterator(const CompressedPointCloud *compressed_point_cloud)
ConstIterator begin() const
ConstIterator end() const
static ConstIterator EndIterator(const CompressedPointCloud *compressed_point_cloud)
ConstIterator & operator++()
proto::CompressedPointCloud ToProto() const
Eigen::Vector3f operator*() const
std::vector< Eigen::Vector3f > PointCloud
int32 remaining_points_in_current_block_
std::vector< int32 >::const_iterator input_
Eigen::Vector3f current_point_
Eigen::Vector3i current_block_coordinates_
const CompressedPointCloud * compressed_point_cloud_