8 #include <draco/compression/decode.h> 12 #include <sensor_msgs/PointCloud2.h> 14 #include <draco_point_cloud_transport/CompressedPointCloud2.h> 23 const draco::PointCloud& pc,
24 const draco_point_cloud_transport::CompressedPointCloud2& compressed_PC2,
25 sensor_msgs::PointCloud2& PC2)
28 int32_t number_of_attributes = pc.num_attributes();
31 draco::PointIndex::ValueType number_of_points = pc.num_points();
33 PC2.data.resize(number_of_points * compressed_PC2.point_step);
36 for (int32_t att_id = 0; att_id < number_of_attributes; att_id++)
39 const draco::PointAttribute* attribute = pc.attribute(att_id);
42 if (!attribute->IsValid())
43 return cras::make_unexpected(
"In point_cloud_transport::DracoToPC2, attribute of Draco pointcloud is not valid!");
46 uint32_t attribute_offset = compressed_PC2.fields[att_id].offset;
49 for (draco::PointIndex::ValueType point_index = 0; point_index < number_of_points; point_index++)
52 uint8_t* out_data = &PC2.data[
static_cast<int>(compressed_PC2.point_step * point_index + attribute_offset)];
55 attribute->GetValue(draco::AttributeValueIndex(point_index), out_data);
71 const CompressedPointCloud2& compressed,
const DracoSubscriberConfig& config)
const 74 uint32_t compressed_data_size = compressed.compressed_data.size();
77 if (compressed_data_size == 0)
78 return cras::make_unexpected(
"Received compressed Draco message with zero length.");
80 draco::DecoderBuffer decode_buffer;
81 std::vector<unsigned char> vec_data = compressed.compressed_data;
86 decode_buffer.Init(reinterpret_cast<const char*>(&vec_data[0]), compressed_data_size);
89 draco::Decoder decoder;
91 if (
config_.SkipDequantizationPOSITION)
93 decoder.SetSkipAttributeTransform(draco::GeometryAttribute::POSITION);
95 if (
config_.SkipDequantizationNORMAL)
97 decoder.SetSkipAttributeTransform(draco::GeometryAttribute::NORMAL);
99 if (
config_.SkipDequantizationCOLOR)
101 decoder.SetSkipAttributeTransform(draco::GeometryAttribute::COLOR);
103 if (
config_.SkipDequantizationTEX_COORD)
105 decoder.SetSkipAttributeTransform(draco::GeometryAttribute::TEX_COORD);
107 if (
config_.SkipDequantizationGENERIC)
109 decoder.SetSkipAttributeTransform(draco::GeometryAttribute::GENERIC);
113 const auto res = decoder.DecodePointCloudFromBuffer(&decode_buffer);
115 return cras::make_unexpected(
116 cras::format(
"Draco decoder returned code %i: %s.", res.status().code(), res.status().error_msg()));
118 const std::unique_ptr<draco::PointCloud>& decoded_pc = res.value();
120 sensor_msgs::PointCloud2Ptr message(
new sensor_msgs::PointCloud2);
123 return cras::make_unexpected(convertRes.error());
std::string getTransportName() const override
cras::expected< cras::optional< sensor_msgs::PointCloud2ConstPtr >, std::string > DecodeResult
void copyCloudMetadata(PC1 &target, const PC2 &source)
copies header, width, ... between clouds
DecodeResult decodeTyped(const CompressedPointCloud2 &compressed, const DracoSubscriberConfig &config) const override
inline ::std::string format(const char *format, ::va_list args)
DracoSubscriberConfig config_
cras::expected< bool, std::string > convertDracoToPC2(const draco::PointCloud &pc, const draco_point_cloud_transport::CompressedPointCloud2 &compressed_PC2, sensor_msgs::PointCloud2 &PC2)
Method for converting into sensor_msgs::PointCloud2.