Draco-encode POSITION (x,y,z) + one GENERIC (intensity) attribute, sequential (lossless float) so positions round-trip closely. When generic_meta_name is given, the GENERIC attribute is tagged with that name in Draco attribute metadata (the Foxglove / draco_point_cloud_transport convention).
| 71 | // the GENERIC attribute is tagged with that name in Draco attribute metadata (the |
| 72 | // Foxglove / draco_point_cloud_transport convention). |
| 73 | std::vector<uint8_t> encodeDraco(const std::vector<Pt>& pts, const char* generic_meta_name = nullptr) { |
| 74 | draco::PointCloudBuilder builder; |
| 75 | builder.Start(static_cast<draco::PointIndex::ValueType>(pts.size())); |
| 76 | const int pos_att = builder.AddAttribute(draco::GeometryAttribute::POSITION, 3, draco::DT_FLOAT32); |
| 77 | const int gen_att = builder.AddAttribute(draco::GeometryAttribute::GENERIC, 1, draco::DT_FLOAT32); |
| 78 | for (size_t i = 0; i < pts.size(); ++i) { |
| 79 | const float xyz[3] = {pts[i].x, pts[i].y, pts[i].z}; |
| 80 | builder.SetAttributeValueForPoint(pos_att, draco::PointIndex(static_cast<uint32_t>(i)), xyz); |
| 81 | builder.SetAttributeValueForPoint(gen_att, draco::PointIndex(static_cast<uint32_t>(i)), &pts[i].intensity); |
| 82 | } |
| 83 | if (generic_meta_name != nullptr) { |
| 84 | auto meta = std::make_unique<draco::AttributeMetadata>(); |
| 85 | meta->AddEntryString("name", generic_meta_name); |
| 86 | builder.AddAttributeMetadata(gen_att, std::move(meta)); |
| 87 | } |
| 88 | std::unique_ptr<draco::PointCloud> pc = builder.Finalize(/*deduplicate_points=*/false); |
| 89 | draco::Encoder encoder; |
| 90 | encoder.SetEncodingMethod(draco::POINT_CLOUD_SEQUENTIAL_ENCODING); |
| 91 | draco::EncoderBuffer buffer; |
| 92 | const draco::Status status = encoder.EncodePointCloudToBuffer(*pc, &buffer); |
| 93 | EXPECT_TRUE(status.ok()) << status.error_msg(); |
| 94 | return std::vector<uint8_t>(buffer.data(), buffer.data() + buffer.size()); |
| 95 | } |
| 96 | |
| 97 | CompressedPointCloud wrap(std::vector<uint8_t> blob, std::string format, std::string frame_id, int64_t ts_ns) { |
| 98 | auto owned = std::make_shared<std::vector<uint8_t>>(std::move(blob)); |