12 #include <liblzf/lzf.h>
60 std::unordered_map<std::string, bool>
has_attr;
66 const int row_idx = 0,
67 const int row_length = 0,
92 char type_uppercase = std::toupper(
type, std::locale());
93 if (type_uppercase ==
'I') {
102 }
else if (type_uppercase ==
'U') {
111 }
else if (type_uppercase ==
'F') {
132 header.
has_attr[
"positions"] =
false;
136 std::unordered_set<std::string> known_field;
137 std::unordered_map<std::string, core::Dtype> field_dtype;
139 for (
const auto &field : header.
fields) {
140 if (field.name ==
"x" || field.name ==
"y" || field.name ==
"z" ||
141 field.name ==
"normal_x" || field.name ==
"normal_y" ||
142 field.name ==
"normal_z" || field.name ==
"rgb" ||
143 field.name ==
"rgba") {
144 known_field.insert(field.name);
145 field_dtype[field.name] =
154 if (known_field.count(
"x") && known_field.count(
"y") &&
155 known_field.count(
"z")) {
156 if ((field_dtype[
"x"] == field_dtype[
"y"]) &&
157 (field_dtype[
"x"] == field_dtype[
"z"])) {
158 header.
has_attr[
"positions"] =
true;
159 header.
attr_dtype[
"positions"] = field_dtype[
"x"];
162 "[Write PCD] Dtype for positions data are not "
168 "[Write PCD] Fields for positions data are not "
173 if (known_field.count(
"normal_x") && known_field.count(
"normal_y") &&
174 known_field.count(
"normal_z")) {
175 if ((field_dtype[
"normal_x"] == field_dtype[
"normal_y"]) &&
176 (field_dtype[
"normal_x"] == field_dtype[
"normal_z"])) {
178 header.
attr_dtype[
"normals"] = field_dtype[
"x"];
181 "[InitializeHeader] Dtype for normals data are not same.");
186 if (known_field.count(
"rgb")) {
188 header.
attr_dtype[
"colors"] = field_dtype[
"rgb"];
189 }
else if (known_field.count(
"rgba")) {
191 header.
attr_dtype[
"colors"] = field_dtype[
"rgba"];
199 size_t specified_channel_count = 0;
202 std::string line(line_buffer);
207 std::stringstream sstream(line);
208 sstream.imbue(std::locale::classic());
209 std::string line_type;
210 sstream >> line_type;
211 if (line_type.substr(0, 1) ==
"#") {
212 }
else if (line_type.substr(0, 7) ==
"VERSION") {
213 if (st.size() >= 2) {
216 }
else if (line_type.substr(0, 6) ==
"FIELDS" ||
217 line_type.substr(0, 7) ==
"COLUMNS") {
218 specified_channel_count = st.size() - 1;
219 if (specified_channel_count == 0) {
223 header.
fields.resize(specified_channel_count);
225 for (
size_t i = 0; i < specified_channel_count;
227 header.
fields[i].name = st[i + 1];
228 header.
fields[i].size = 4;
229 header.
fields[i].type =
'F';
230 header.
fields[i].count = 1;
236 }
else if (line_type.substr(0, 4) ==
"SIZE") {
237 if (specified_channel_count != st.size() - 1) {
241 int offset = 0, col_type = 0;
242 for (
size_t i = 0; i < specified_channel_count;
243 ++i,
offset += col_type) {
245 header.
fields[i].size = col_type;
249 }
else if (line_type.substr(0, 4) ==
"TYPE") {
250 if (specified_channel_count != st.size() - 1) {
254 for (
size_t i = 0; i < specified_channel_count; ++i) {
255 header.
fields[i].type = st[i + 1].c_str()[0];
257 }
else if (line_type.substr(0, 5) ==
"COUNT") {
258 if (specified_channel_count != st.size() - 1) {
263 for (
size_t i = 0; i < specified_channel_count; ++i) {
264 sstream >> col_count;
265 header.
fields[i].count = col_count;
273 }
else if (line_type.substr(0, 5) ==
"WIDTH") {
274 sstream >> header.
width;
275 }
else if (line_type.substr(0, 6) ==
"HEIGHT") {
278 }
else if (line_type.substr(0, 9) ==
"VIEWPOINT") {
279 if (st.size() >= 2) {
282 }
else if (line_type.substr(0, 6) ==
"POINTS") {
284 }
else if (line_type.substr(0, 4) ==
"DATA") {
286 if (st.size() >= 2) {
287 if (st[1].substr(0, 17) ==
"binary_compressed") {
289 }
else if (st[1].substr(0, 6) ==
"binary") {
304 const char *data_ptr,
306 std::uint8_t *attr_data_ptr =
static_cast<std::uint8_t *
>(attr.
data_ptr_) +
309 if (field.
size == 4) {
310 std::uint8_t data[4] = {0};
312 char type_uppercase = std::toupper(field.
type, std::locale());
313 if (type_uppercase ==
'I') {
314 std::int32_t value = std::strtol(data_ptr, &end, 0);
315 std::memcpy(data, &value,
sizeof(std::int32_t));
316 }
else if (type_uppercase ==
'U') {
317 std::uint32_t value = std::strtoul(data_ptr, &end, 0);
318 std::memcpy(data, &value,
sizeof(std::uint32_t));
319 }
else if (type_uppercase ==
'F') {
320 float value = std::strtof(data_ptr, &end);
321 std::memcpy(data, &value,
sizeof(
float));
325 attr_data_ptr[0] = data[2];
326 attr_data_ptr[1] = data[1];
327 attr_data_ptr[2] = data[0];
329 attr_data_ptr[0] = 0;
330 attr_data_ptr[1] = 0;
331 attr_data_ptr[2] = 0;
335 template <
typename scalar_t>
337 const char *data_ptr) =
delete;
342 data = std::strtof(data_ptr, &end);
348 data = std::strtod(data_ptr, &end);
352 void UnpackASCIIPCDElement<std::int8_t>(std::int8_t &data,
353 const char *data_ptr) {
355 data =
static_cast<std::int8_t
>(std::strtol(data_ptr, &end, 0));
359 void UnpackASCIIPCDElement<std::int16_t>(std::int16_t &data,
360 const char *data_ptr) {
362 data =
static_cast<std::int16_t
>(std::strtol(data_ptr, &end, 0));
366 void UnpackASCIIPCDElement<std::int32_t>(std::int32_t &data,
367 const char *data_ptr) {
369 data =
static_cast<std::int32_t
>(std::strtol(data_ptr, &end, 0));
373 void UnpackASCIIPCDElement<std::int64_t>(std::int64_t &data,
374 const char *data_ptr) {
376 data = std::strtol(data_ptr, &end, 0);
380 void UnpackASCIIPCDElement<std::uint8_t>(std::uint8_t &data,
381 const char *data_ptr) {
383 data =
static_cast<std::uint8_t
>(std::strtoul(data_ptr, &end, 0));
387 void UnpackASCIIPCDElement<std::uint16_t>(std::uint16_t &data,
388 const char *data_ptr) {
390 data =
static_cast<std::uint16_t
>(std::strtoul(data_ptr, &end, 0));
394 void UnpackASCIIPCDElement<std::uint32_t>(std::uint32_t &data,
395 const char *data_ptr) {
397 data =
static_cast<std::uint32_t
>(std::strtoul(data_ptr, &end, 0));
401 void UnpackASCIIPCDElement<std::uint64_t>(std::uint64_t &data,
402 const char *data_ptr) {
404 data = std::strtoul(data_ptr, &end, 0);
409 const char *data_ptr,
413 scalar_t *attr_data_ptr =
414 static_cast<scalar_t *>(attr.data_ptr_) +
415 index * attr.row_length_ + attr.row_idx_;
417 UnpackASCIIPCDElement<scalar_t>(attr_data_ptr[0], data_ptr);
423 const void *data_ptr,
425 std::uint8_t *attr_data_ptr =
static_cast<std::uint8_t *
>(attr.
data_ptr_) +
428 if (field.
size == 4) {
429 std::uint8_t data[4] = {0};
430 std::memcpy(data, data_ptr, 4 *
sizeof(std::uint8_t));
433 attr_data_ptr[0] = data[2];
434 attr_data_ptr[1] = data[1];
435 attr_data_ptr[2] = data[0];
437 attr_data_ptr[0] = 0;
438 attr_data_ptr[1] = 0;
439 attr_data_ptr[2] = 0;
445 const void *data_ptr,
449 scalar_t *attr_data_ptr =
450 static_cast<scalar_t *>(attr.data_ptr_) +
451 index * attr.row_length_ + attr.row_idx_;
453 std::memcpy(attr_data_ptr, data_ptr, sizeof(scalar_t));
464 std::unordered_map<std::string, ReadAttributePtr> map_field_to_attr_ptr;
475 map_field_to_attr_ptr.emplace(std::string(
"x"), position_x);
476 map_field_to_attr_ptr.emplace(std::string(
"y"), position_y);
477 map_field_to_attr_ptr.emplace(std::string(
"z"), position_z);
480 "[ReadPCDData] Fields for point data are not complete.");
492 map_field_to_attr_ptr.emplace(std::string(
"normal_x"), normal_x);
493 map_field_to_attr_ptr.emplace(std::string(
"normal_y"), normal_y);
494 map_field_to_attr_ptr.emplace(std::string(
"normal_z"), normal_z);
505 map_field_to_attr_ptr.emplace(std::string(
"colors"),
colors);
509 for (
const auto &field : header.
fields) {
510 if (header.
has_attr[field.name] && field.name !=
"x" &&
511 field.name !=
"y" && field.name !=
"z" &&
512 field.name !=
"normal_x" && field.name !=
"normal_y" &&
513 field.name !=
"normal_z" && field.name !=
"rgb" &&
514 field.name !=
"rgba") {
520 void *data_ptr = pointcloud.
GetPointAttr(field.name).GetDataPtr();
523 map_field_to_attr_ptr.emplace(field.name, attr);
535 std::string line(line_buffer);
536 std::vector<std::string> strs =
541 for (
size_t i = 0; i < header.
fields.size(); ++i) {
542 const auto &field = header.
fields[i];
543 if (field.name ==
"rgb" || field.name ==
"rgba") {
545 map_field_to_attr_ptr[
"colors"], field,
546 strs[field.count_offset].c_str(), idx);
549 map_field_to_attr_ptr[field.name], field,
550 strs[field.count_offset].c_str(), idx);
554 if (idx % 1000 == 0) {
559 std::unique_ptr<char[]> buffer(
new char[header.
pointsize]);
560 for (
int i = 0; i < header.
points; ++i) {
561 if (fread(buffer.get(), header.
pointsize, 1, file) != 1) {
563 "[ReadPCDData] Failed to read data record.");
567 for (
const auto &field : header.
fields) {
568 if (field.name ==
"rgb" || field.name ==
"rgba") {
570 map_field_to_attr_ptr[
"colors"], field,
571 buffer.get() + field.offset, i);
574 map_field_to_attr_ptr[field.name], field,
575 buffer.get() + field.offset, i);
583 double reporter_total = 100.0;
584 reporter.
SetTotal(
int(reporter_total));
585 reporter.
Update(
int(reporter_total * 0.01));
586 std::uint32_t compressed_size;
587 std::uint32_t uncompressed_size;
588 if (fread(&compressed_size,
sizeof(compressed_size), 1, file) != 1) {
593 if (fread(&uncompressed_size,
sizeof(uncompressed_size), 1, file) !=
600 "PCD data with {:d} compressed size, and {:d} uncompressed "
602 compressed_size, uncompressed_size);
603 std::unique_ptr<char[]> buffer_compressed(
new char[compressed_size]);
604 reporter.
Update(
int(reporter_total * .1));
605 if (fread(buffer_compressed.get(), 1, compressed_size, file) !=
611 std::unique_ptr<char[]> buffer(
new char[uncompressed_size]);
612 reporter.
Update(
int(reporter_total * .2));
613 if (lzf_decompress(buffer_compressed.get(),
614 (
unsigned int)compressed_size, buffer.get(),
615 (
unsigned int)uncompressed_size) !=
621 for (
const auto &field : header.
fields) {
622 const char *base_ptr = buffer.get() + field.offset * header.
points;
624 double(base_ptr - buffer.get()) / uncompressed_size;
625 reporter.
Update(
int(reporter_total * (progress + .2)));
626 if (field.name ==
"rgb" || field.name ==
"rgba") {
627 for (
int i = 0; i < header.
points; ++i) {
629 map_field_to_attr_ptr[
"colors"], field,
630 base_ptr + i * field.size * field.count, i);
633 for (
int i = 0; i < header.
points; ++i) {
635 map_field_to_attr_ptr[field.name], field,
636 base_ptr + i * field.size * field.count, i);
703 header.
fields.push_back(field_x);
707 header.
fields.push_back(field_y);
711 header.
fields.push_back(field_z);
717 PCLPointField field_normal_x, field_normal_y, field_normal_z;
719 field_normal_x.
name =
"normal_x";
720 field_normal_x.
count = 1;
723 header.
fields.push_back(field_normal_x);
725 field_normal_y = field_normal_x;
726 field_normal_y.
name =
"normal_y";
727 header.
fields.push_back(field_normal_y);
729 field_normal_z = field_normal_x;
730 field_normal_z.
name =
"normal_z";
731 header.
fields.push_back(field_normal_z);
738 field_colors.
name =
"rgb";
739 field_colors.
count = 1;
740 field_colors.
type =
'F';
741 field_colors.
size = 4;
742 header.
fields.push_back(field_colors);
750 if (kv.first !=
"positions" && kv.first !=
"normals" &&
751 kv.first !=
"colors") {
752 if (kv.second.GetShape() ==
754 {pointcloud.GetPointPositions().GetLength(), 1})) {
756 field_custom_attr.
name = kv.first;
757 field_custom_attr.
count = 1;
760 header.
fields.push_back(field_custom_attr);
766 "Write PCD : Skipping {} attribute. PointCloud "
767 "contains {} attribute which is not supported by PCD "
768 "IO. Only points, normals, colors and attributes with "
769 "shape (num_points, 1) are supported. Expected shape: "
773 {pointcloud.GetPointPositions().GetLength(), 1})
775 kv.second.GetShape().ToString());
793 fprintf(file,
"# .PCD v%s - Point Cloud Data file format\n",
795 fprintf(file,
"VERSION %s\n", header.
version.c_str());
796 fprintf(file,
"FIELDS");
797 for (
const auto &field : header.
fields) {
798 fprintf(file,
" %s", field.name.c_str());
801 fprintf(file,
"SIZE");
802 for (
const auto &field : header.
fields) {
803 fprintf(file,
" %d", field.size);
806 fprintf(file,
"TYPE");
807 for (
const auto &field : header.
fields) {
808 fprintf(file,
" %c", field.type);
811 fprintf(file,
"COUNT");
812 for (
const auto &field : header.
fields) {
813 fprintf(file,
" %d", field.count);
816 fprintf(file,
"WIDTH %d\n", header.
width);
817 fprintf(file,
"HEIGHT %d\n", header.
height);
818 fprintf(file,
"VIEWPOINT 0 0 0 1 0 0 0\n");
819 fprintf(file,
"POINTS %d\n", header.
points);
823 fprintf(file,
"DATA binary\n");
826 fprintf(file,
"DATA binary_compressed\n");
830 fprintf(file,
"DATA ascii\n");
836 template <
typename scalar_t>
838 std::uint8_t *output_color) {
840 "Color format not supported. Supported color format includes "
841 "Float32, Float64, UInt8, UInt16, UInt32.");
846 const float normalisation_factor =
848 for (
int i = 0; i < 3; ++i) {
849 output_color[i] =
static_cast<std::uint8_t
>(
851 normalisation_factor));
858 std::uint8_t *output_color) {
859 const double normalisation_factor =
861 for (
int i = 0; i < 3; ++i) {
862 output_color[i] =
static_cast<std::uint8_t
>(
864 normalisation_factor));
870 void ColorToUint8<std::uint8_t>(
const std::uint8_t *input_color,
871 std::uint8_t *output_color) {
872 for (
int i = 0; i < 3; ++i) {
873 output_color[i] = input_color[2 - i];
879 void ColorToUint8<std::uint16_t>(
const std::uint16_t *input_color,
880 std::uint8_t *output_color) {
881 const float normalisation_factor =
884 for (
int i = 0; i < 3; ++i) {
885 output_color[i] =
static_cast<std::uint16_t
>(input_color[2 - i] *
886 normalisation_factor);
892 void ColorToUint8<std::uint32_t>(
const std::uint32_t *input_color,
893 std::uint8_t *output_color) {
894 const float normalisation_factor =
897 for (
int i = 0; i < 3; ++i) {
898 output_color[i] =
static_cast<std::uint32_t
>(input_color[2 - i] *
899 normalisation_factor);
908 auto packed_color_ptr = packed_color.
GetDataPtr<
float>();
911 auto colors_ptr = colors_contiguous.GetDataPtr<scalar_t>();
912 core::ParallelFor(core::Device(
"CPU:0"), colors_contiguous.GetLength(),
913 [&](std::int64_t workload_idx) {
914 std::uint8_t rgba[4] = {0};
915 ColorToUint8<scalar_t>(
916 colors_ptr + 3 * workload_idx, rgba);
918 std::memcpy(&val, rgba, 4 * sizeof(std::uint8_t));
919 packed_color_ptr[workload_idx] = val;
926 template <
typename scalar_t>
928 FILE *file) =
delete;
932 return fprintf(file,
"%.10g ", data);
937 return fprintf(file,
"%.10g ", data);
941 int WriteElementDataToFileASCII<std::int8_t>(
const std::int8_t &data,
943 return fprintf(file,
"%" PRId8
" ", data);
947 int WriteElementDataToFileASCII<std::int16_t>(
const std::int16_t &data,
949 return fprintf(file,
"%" PRId16
" ", data);
953 int WriteElementDataToFileASCII<std::int32_t>(
const std::int32_t &data,
955 return fprintf(file,
"%" PRId32
" ", data);
959 int WriteElementDataToFileASCII<std::int64_t>(
const std::int64_t &data,
961 return fprintf(file,
"%" PRId64
" ", data);
965 int WriteElementDataToFileASCII<std::uint8_t>(
const std::uint8_t &data,
967 return fprintf(file,
"%" PRIu8
" ", data);
971 int WriteElementDataToFileASCII<std::uint16_t>(
const std::uint16_t &data,
973 return fprintf(file,
"%" PRIu16
" ", data);
977 int WriteElementDataToFileASCII<std::uint32_t>(
const std::uint32_t &data,
979 return fprintf(file,
"%" PRIu32
" ", data);
983 int WriteElementDataToFileASCII<std::uint64_t>(
const std::uint64_t &data,
985 return fprintf(file,
"%" PRIu64
" ", data);
999 const std::int64_t num_points =
static_cast<std::int64_t
>(
1002 std::vector<WriteAttributePtr> attribute_ptrs;
1004 attribute_ptrs.emplace_back(t_map[
"positions"].GetDtype(),
1005 t_map[
"positions"].GetDataPtr(), 3);
1008 attribute_ptrs.emplace_back(t_map[
"normals"].GetDtype(),
1009 t_map[
"normals"].GetDataPtr(), 3);
1014 attribute_ptrs.emplace_back(
core::Float32, t_map[
"colors"].GetDataPtr(),
1020 for (
auto &field : header.
fields) {
1021 if (field.name !=
"x" && field.name !=
"y" && field.name !=
"z" &&
1022 field.name !=
"normal_x" && field.name !=
"normal_y" &&
1023 field.name !=
"normal_z" && field.name !=
"rgb" &&
1024 field.name !=
"rgba" && field.count == 1) {
1025 attribute_ptrs.emplace_back(t_map[field.name].GetDtype(),
1026 t_map[field.name].GetDataPtr(), 1);
1032 if (header.
datatype == PCDDataType::ASCII) {
1033 for (std::int64_t i = 0; i < num_points; ++i) {
1034 for (
auto &it : attribute_ptrs) {
1036 const scalar_t *data_ptr =
1037 static_cast<const scalar_t *>(it.data_ptr_);
1039 for (int idx_offset = it.group_size_ * i;
1040 idx_offset < it.group_size_ * (i + 1); ++idx_offset) {
1041 WriteElementDataToFileASCII<scalar_t>(
1042 data_ptr[idx_offset], file);
1047 fprintf(file,
"\n");
1048 if (i % 1000 == 0) {
1052 }
else if (header.datatype == PCDDataType::BINARY) {
1053 std::vector<char> buffer((header.pointsize * header.points));
1054 std::uint32_t buffer_index = 0;
1055 for (std::int64_t i = 0; i < num_points; ++i) {
1056 for (
auto &it : attribute_ptrs) {
1058 const scalar_t *data_ptr =
1059 static_cast<const scalar_t *>(it.data_ptr_);
1061 for (int idx_offset = it.group_size_ * i;
1062 idx_offset < it.group_size_ * (i + 1); ++idx_offset) {
1063 std::memcpy(buffer.data() + buffer_index,
1064 reinterpret_cast<const char *>(
1065 &data_ptr[idx_offset]),
1067 buffer_index += sizeof(scalar_t);
1072 if (i % 1000 == 0) {
1077 fwrite(buffer.data(),
sizeof(
char), buffer.size(), file);
1078 }
else if (header.datatype == PCDDataType::BINARY_COMPRESSED) {
1084 const std::int64_t report_total = attribute_ptrs.size() * 2;
1088 reporter.SetTotal(report_total);
1090 const std::uint32_t buffer_size_in_bytes =
1091 header.pointsize * header.points;
1092 std::vector<char> buffer(buffer_size_in_bytes);
1093 std::vector<char> buffer_compressed(2 * buffer_size_in_bytes);
1095 std::uint32_t buffer_index = 0;
1096 std::int64_t
count = 0;
1097 for (
auto &it : attribute_ptrs) {
1099 const scalar_t *data_ptr =
1100 static_cast<const scalar_t *>(it.data_ptr_);
1102 for (int idx_offset = 0; idx_offset < it.group_size_;
1104 for (std::int64_t i = 0; i < num_points; ++i) {
1105 std::memcpy(buffer.data() + buffer_index,
1106 reinterpret_cast<const char *>(
1107 &data_ptr[i * it.group_size_ +
1110 buffer_index += sizeof(scalar_t);
1115 reporter.Update(
count++);
1118 std::uint32_t size_compressed = lzf_compress(
1119 buffer.data(), buffer_size_in_bytes, buffer_compressed.data(),
1120 buffer_size_in_bytes * 2);
1121 if (size_compressed == 0) {
1127 "[WritePCDData] {:d} bytes data compressed into {:d} bytes.",
1128 buffer_size_in_bytes, size_compressed);
1130 reporter.Update(
static_cast<std::int64_t
>(report_total * 0.75));
1132 fwrite(&size_compressed,
sizeof(size_compressed), 1, file);
1133 fwrite(&buffer_size_in_bytes,
sizeof(buffer_size_in_bytes), 1, file);
1134 fwrite(buffer_compressed.data(), 1, size_compressed, file);
1157 "PCD header indicates {:d} fields, {:d} bytes per point, and {:d} "
1160 for (
const auto &field : header.
fields) {
1162 field.type, field.size, field.count, field.offset);
1166 header.
has_attr[
"positions"] ?
"yes" :
"no",
1167 header.
has_attr[
"normals"] ?
"yes" :
"no",
1168 header.
has_attr[
"colors"] ?
"yes" :
"no");
1186 bool(
params.compressed), header)) {
#define DISPATCH_DTYPE_TO_TEMPLATE(DTYPE,...)
cmdLineReadable * params[]
#define AssertTensorDevice(tensor,...)
static const Dtype Float32
static const Dtype UInt16
static const Dtype UInt64
static const Dtype UInt32
static const Dtype Float64
std::string ToString() const
int64_t GetLength() const
static Tensor Empty(const SizeVector &shape, Dtype dtype, const Device &device=Device("CPU:0"))
Create a tensor with uninitialized values.
A point cloud contains a list of 3D points.
void SetPointNormals(const core::Tensor &value)
Set the value of the "normals" attribute. Convenience function.
core::Tensor & GetPointNormals()
Get the value of the "normals" attribute. Convenience function.
bool HasPointPositions() const
void SetPointColors(const core::Tensor &value)
Set the value of the "colors" attribute. Convenience function.
void SetPointPositions(const core::Tensor &value)
Set the value of the "positions" attribute. Convenience function.
core::Tensor & GetPointPositions()
Get the value of the "positions" attribute. Convenience function.
bool IsEmpty() const override
Returns !HasPointPositions().
bool HasPointNormals() const
const TensorMap & GetPointAttr() const
Getter for point_attr_ TensorMap. Used in Pybind.
PointCloud & Clear() override
Clear all data in the point cloud.
void SetPointAttr(const std::string &key, const core::Tensor &value)
core::Tensor & GetPointColors()
Get the value of the "colors" attribute. Convenience function.
bool HasPointColors() const
TensorMap Contiguous() const
void SetTotal(int64_t total)
bool Update(int64_t count)
#define DEFAULT_IO_BUFFER_SIZE
Helper functions for the ml ops.
static void ReadBinaryPCDColorsFromField(ReadAttributePtr &attr, const PCLPointField &field, const void *data_ptr, const int index)
int WriteElementDataToFileASCII< double >(const double &data, FILE *file)
static core::Tensor PackColorsToFloat(const core::Tensor &colors_contiguous)
static void ReadASCIIPCDColorsFromField(ReadAttributePtr &attr, const PCLPointField &field, const char *data_ptr, const int index)
void ColorToUint8< double >(const double *input_color, std::uint8_t *output_color)
static bool ReadPCDData(FILE *file, PCDHeader &header, t::geometry::PointCloud &pointcloud, const ReadPointCloudOption ¶ms)
static bool GenerateHeader(const t::geometry::PointCloud &pointcloud, const bool write_ascii, const bool compressed, PCDHeader &header)
void UnpackASCIIPCDElement< float >(float &data, const char *data_ptr)
bool WritePointCloudToPCD(const std::string &filename, const geometry::PointCloud &pointcloud, const WritePointCloudOption ¶ms)
void UnpackASCIIPCDElement< double >(double &data, const char *data_ptr)
bool ReadPointCloudFromPCD(const std::string &filename, t::geometry::PointCloud &pointcloud, const ReadPointCloudOption ¶ms)
static void ReadBinaryPCDElementsFromField(ReadAttributePtr &attr, const PCLPointField &field, const void *data_ptr, const int index)
static bool WritePCDHeader(FILE *file, const PCDHeader &header)
static core::Dtype GetDtypeFromPCDHeaderField(char type, int size)
static int WriteElementDataToFileASCII(const scalar_t &data, FILE *file)=delete
static bool ReadPCDHeader(FILE *file, PCDHeader &header)
static bool WritePCDData(FILE *file, const PCDHeader &header, const geometry::PointCloud &pointcloud, const WritePointCloudOption ¶ms)
static bool InitializeHeader(PCDHeader &header)
static void SetPCDHeaderFieldTypeAndSizeFromDtype(const core::Dtype &dtype, PCLPointField &field)
static void UnpackASCIIPCDElement(scalar_t &data, const char *data_ptr)=delete
int WriteElementDataToFileASCII< float >(const float &data, FILE *file)
static void ReadASCIIPCDElementsFromField(ReadAttributePtr &attr, const PCLPointField &field, const char *data_ptr, const int index)
void ColorToUint8< float >(const float *input_color, std::uint8_t *output_color)
static void ColorToUint8(const scalar_t *input_color, std::uint8_t *output_color)
FILE * FOpen(const std::string &filename, const std::string &mode)
void SplitString(std::vector< std::string > &tokens, const std::string &str, const std::string &delimiters=" ", bool trim_empty_str=true)
Generic file read and write utility for python interface.
Optional parameters to ReadPointCloud.
Optional parameters to WritePointCloud.
ReadAttributePtr(void *data_ptr=nullptr, const int row_idx=0, const int row_length=0, const int size=0)
WriteAttributePtr(const core::Dtype &dtype, const void *data_ptr, const int group_size)