10 #include <liblzf/lzf.h>
13 #include <ui_PCDOutputFormatDlg.h>
14 #include <ui_savePCDFileDlg.h>
36 #include <QPushButton>
43 #include <pcl/filters/passthrough.h>
44 #include <pcl/io/pcd_io.h>
52 PCD_DATA_BINARY_COMPRESSED = 2
55 struct PCLPointField {
69 std::vector<PCLPointField>
fields;
86 bool CheckHeader(PCDHeader& header) {
87 if (header.points <= 0 || header.pointsize <= 0) {
91 if (header.fields.size() == 0 || header.pointsize <= 0) {
95 header.has_points =
false;
96 header.has_normals =
false;
97 header.has_colors =
false;
98 header.has_ring =
false;
99 header.has_intensity =
false;
100 header.has_timestamp =
false;
104 bool has_normal_x =
false;
105 bool has_normal_y =
false;
106 bool has_normal_z =
false;
107 bool has_rgb =
false;
108 bool has_rgba =
false;
111 bool has_timestamp =
false;
112 for (
const auto& field : header.fields) {
113 if (field.name ==
"x") {
115 }
else if (field.name ==
"y") {
117 }
else if (field.name ==
"z") {
119 }
else if (field.name ==
"normal_x") {
121 }
else if (field.name ==
"normal_y") {
123 }
else if (field.name ==
"normal_z") {
125 }
else if (field.name ==
"rgb") {
127 }
else if (field.name ==
"rgba") {
129 }
else if (field.name ==
"intensity") {
131 }
else if (field.name ==
"timestamp") {
132 has_timestamp =
true;
133 }
else if (field.name ==
"ring") {
137 header.has_points = (has_x && has_y && has_z);
138 header.has_normals = (has_normal_x && has_normal_y && has_normal_z);
139 header.has_colors = (has_rgb || has_rgba);
141 header.has_timestamp = has_timestamp;
143 if (header.has_points ==
false) {
145 "[CheckHeader] Fields for point data are not complete."));
153 size_t specified_channel_count = 0;
156 std::string line(line_buffer);
160 std::vector<std::string> st;
162 std::stringstream sstream(line);
163 sstream.imbue(std::locale::classic());
164 std::string line_type;
165 sstream >> line_type;
166 if (line_type.substr(0, 1) ==
"#") {
167 }
else if (line_type.substr(0, 7) ==
"VERSION") {
168 if (st.size() >= 2) {
169 header.version = st[1];
171 }
else if (line_type.substr(0, 6) ==
"FIELDS" ||
172 line_type.substr(0, 7) ==
"COLUMNS") {
173 specified_channel_count = st.size() - 1;
174 if (specified_channel_count == 0) {
178 header.fields.resize(specified_channel_count);
180 for (
size_t i = 0; i < specified_channel_count;
182 header.fields[i].name = st[i + 1];
183 header.fields[i].size = 4;
184 header.fields[i].type =
'F';
185 header.fields[i].count = 1;
187 header.fields[i].offset =
offset;
190 header.pointsize =
offset;
191 }
else if (line_type.substr(0, 4) ==
"SIZE") {
192 if (specified_channel_count != st.size() - 1) {
196 int offset = 0, col_type = 0;
197 for (
size_t i = 0; i < specified_channel_count;
198 i++,
offset += col_type) {
200 header.fields[i].size = col_type;
201 header.fields[i].offset =
offset;
203 header.pointsize =
offset;
204 }
else if (line_type.substr(0, 4) ==
"TYPE") {
205 if (specified_channel_count != st.size() - 1) {
209 for (
size_t i = 0; i < specified_channel_count; i++) {
210 header.fields[i].type = st[i + 1].c_str()[0];
212 }
else if (line_type.substr(0, 5) ==
"COUNT") {
213 if (specified_channel_count != st.size() - 1) {
218 for (
size_t i = 0; i < specified_channel_count; i++) {
219 sstream >> col_count;
220 header.fields[i].count = col_count;
222 header.fields[i].offset =
offset;
224 offset += col_count * header.fields[i].size;
227 header.pointsize =
offset;
228 }
else if (line_type.substr(0, 5) ==
"WIDTH") {
229 sstream >> header.width;
230 }
else if (line_type.substr(0, 6) ==
"HEIGHT") {
231 sstream >> header.height;
232 header.points = header.width * header.height;
233 }
else if (line_type.substr(0, 9) ==
"VIEWPOINT") {
234 if (st.size() >= 2) {
235 header.viewpoint = st[1];
237 }
else if (line_type.substr(0, 6) ==
"POINTS") {
238 sstream >> header.points;
239 }
else if (line_type.substr(0, 4) ==
"DATA") {
240 header.datatype = PCD_DATA_ASCII;
241 if (st.size() >= 2) {
242 if (st[1].substr(0, 17) ==
"binary_compressed") {
243 header.datatype = PCD_DATA_BINARY_COMPRESSED;
244 }
else if (st[1].substr(0, 6) ==
"binary") {
245 header.datatype = PCD_DATA_BINARY;
251 if (CheckHeader(header) ==
false) {
263 memcpy(&data, data_ptr,
sizeof(data));
265 }
else if (
size == 2) {
267 memcpy(&data, data_ptr,
sizeof(data));
269 }
else if (
size == 4) {
271 memcpy(&data, data_ptr,
sizeof(data));
276 }
else if (
type ==
'U') {
279 memcpy(&data, data_ptr,
sizeof(data));
281 }
else if (
size == 2) {
283 memcpy(&data, data_ptr,
sizeof(data));
285 }
else if (
size == 4) {
287 memcpy(&data, data_ptr,
sizeof(data));
292 }
else if (
type ==
'F') {
295 memcpy(&data, data_ptr,
sizeof(data));
308 std::uint8_t data[4];
309 memcpy(data, data_ptr, 4);
317 ScalarType UnpackBinaryPCDScalar(
const char* data_ptr,
322 memcpy(&data, data_ptr, 1);
323 ScalarType scalar =
static_cast<ScalarType
>(data);
326 return static_cast<ScalarType
>(0);
336 }
else if (
type ==
'U') {
338 std::strtoul(data_ptr, &end, 0));
339 }
else if (
type ==
'F') {
349 std::uint8_t data[4] = {0, 0, 0, 0};
352 std::int32_t value = std::strtol(data_ptr, &end, 0);
353 memcpy(data, &value, 4);
354 }
else if (
type ==
'U') {
355 std::uint32_t value = std::strtoul(data_ptr, &end, 0);
356 memcpy(data, &value, 4);
357 }
else if (
type ==
'F') {
358 float value = std::strtof(data_ptr, &end);
359 memcpy(data, &value, 4);
367 ScalarType UnpackASCIIPCDScalar(
const char* data_ptr,
374 std::int32_t value = std::strtol(data_ptr, &end, 0);
375 memcpy(&data, &value, 1);
376 }
else if (
type ==
'U') {
377 std::uint32_t value = std::strtoul(data_ptr, &end, 0);
378 memcpy(&data, &value, 1);
379 }
else if (
type ==
'F') {
380 float value = std::strtof(data_ptr, &end);
381 memcpy(&data, &value, 1);
383 ScalarType scalar =
static_cast<ScalarType
>(data);
386 return static_cast<ScalarType
>(0);
391 const PCDHeader& header,
395 if (header.has_points) {
396 pointcloud.
resize(
static_cast<unsigned int>(header.points));
399 "[ReadPCDData] Fields for point data are not complete."));
402 if (header.has_normals) {
405 if (header.has_colors) {
410 size_t pointCount =
static_cast<size_t>(header.points);
414 if (header.has_intensity) {
422 static_cast<unsigned>(pointCount))) {
428 if (header.has_timestamp) {
436 static_cast<unsigned>(pointCount))) {
442 if (header.has_ring) {
448 if (!cc_ring_field->
reserveSafe(
static_cast<unsigned>(pointCount))) {
454 std::function<bool(
double)> update_progress;
456 reporter.SetTotal(header.points);
462 ScalarType intensity;
463 ScalarType timestamp;
465 if (header.datatype == PCD_DATA_ASCII) {
467 unsigned int idx = 0;
469 idx < (
unsigned int)header.points) {
470 std::string line(line_buffer);
471 std::vector<std::string> strs;
473 if ((
int)strs.size() < header.elementnum) {
477 bool find_point =
false;
478 bool find_normal =
false;
479 bool find_color =
false;
480 bool find_ring =
false;
481 bool find_intensity =
false;
482 bool find_timestamp =
false;
483 for (
size_t i = 0; i < header.fields.size(); i++) {
484 const auto& field = header.fields[i];
485 if (field.name ==
"x") {
488 strs[field.count_offset].c_str(), field.type,
490 }
else if (field.name ==
"y") {
493 strs[field.count_offset].c_str(), field.type,
495 }
else if (field.name ==
"z") {
498 strs[field.count_offset].c_str(), field.type,
500 }
else if (field.name ==
"normal_x") {
503 strs[field.count_offset].c_str(), field.type,
505 }
else if (field.name ==
"normal_y") {
508 strs[field.count_offset].c_str(), field.type,
510 }
else if (field.name ==
"normal_z") {
513 strs[field.count_offset].c_str(), field.type,
515 }
else if (field.name ==
"rgb" || field.name ==
"rgba") {
517 col = UnpackASCIIPCDColor(strs[field.count_offset].c_str(),
518 field.type, field.size);
519 }
else if (field.name ==
"intensity") {
520 find_intensity =
true;
521 intensity = UnpackASCIIPCDScalar(
522 strs[field.count_offset].c_str(), field.type,
524 }
else if (field.name ==
"timestamp") {
525 find_timestamp =
true;
526 timestamp = UnpackASCIIPCDScalar(
527 strs[field.count_offset].c_str(), field.type,
529 }
else if (field.name ==
"ring") {
531 ring = UnpackASCIIPCDScalar(
532 strs[field.count_offset].c_str(), field.type,
540 if (header.has_normals && find_normal) {
543 if (header.has_colors && find_color) {
546 if (header.has_intensity && find_intensity) {
549 if (header.has_timestamp && find_timestamp) {
552 if (header.has_ring && find_ring) {
557 if (idx % 1000 == 0) {
558 reporter.Update(idx);
561 }
else if (header.datatype == PCD_DATA_BINARY) {
562 std::unique_ptr<char[]> buffer(
new char[header.pointsize]);
563 for (
unsigned int i = 0; i < (
unsigned int)header.points; i++) {
564 if (fread(buffer.get(), header.pointsize, 1, file) != 1) {
566 QString(
"[ReadPCDData] Failed to read data record."));
571 bool find_point =
false;
572 bool find_normal =
false;
573 bool find_color =
false;
574 bool find_ring =
false;
575 bool find_intensity =
false;
576 bool find_timestamp =
false;
577 for (
const auto& field : header.fields) {
578 if (field.name ==
"x") {
580 P.x = UnpackBinaryPCDElement(buffer.get() + field.offset,
581 field.type, field.size);
582 }
else if (field.name ==
"y") {
584 P.y = UnpackBinaryPCDElement(buffer.get() + field.offset,
585 field.type, field.size);
586 }
else if (field.name ==
"z") {
588 P.z = UnpackBinaryPCDElement(buffer.get() + field.offset,
589 field.type, field.size);
590 }
else if (field.name ==
"normal_x") {
592 N.x = UnpackBinaryPCDElement(buffer.get() + field.offset,
593 field.type, field.size);
594 }
else if (field.name ==
"normal_y") {
596 N.y = UnpackBinaryPCDElement(buffer.get() + field.offset,
597 field.type, field.size);
598 }
else if (field.name ==
"normal_z") {
600 N.z = UnpackBinaryPCDElement(buffer.get() + field.offset,
601 field.type, field.size);
602 }
else if (field.name ==
"rgb" || field.name ==
"rgba") {
604 col = UnpackBinaryPCDColor(buffer.get() + field.offset,
605 field.type, field.size);
606 }
else if (field.name ==
"intensity") {
607 find_intensity =
true;
609 UnpackBinaryPCDScalar(buffer.get() + field.offset,
610 field.type, field.size);
611 }
else if (field.name ==
"timestamp") {
612 find_timestamp =
true;
614 UnpackBinaryPCDScalar(buffer.get() + field.offset,
615 field.type, field.size);
616 }
else if (field.name ==
"ring") {
618 ring = UnpackBinaryPCDScalar(buffer.get() + field.offset,
619 field.type, field.size);
626 if (header.has_normals && find_normal) {
629 if (header.has_colors && find_color) {
632 if (header.has_intensity && find_intensity) {
635 if (header.has_timestamp && find_timestamp) {
638 if (header.has_ring && find_ring) {
646 }
else if (header.datatype == PCD_DATA_BINARY_COMPRESSED) {
647 double reporter_total = 100.0;
648 reporter.SetTotal(
int(reporter_total));
649 reporter.Update(
int(reporter_total * 0.01));
651 std::uint32_t compressed_size;
652 std::uint32_t uncompressed_size;
653 if (fread(&compressed_size,
sizeof(compressed_size), 1, file) != 1) {
655 QString(
"[ReadPCDData] Failed to read data record."));
659 if (fread(&uncompressed_size,
sizeof(uncompressed_size), 1, file) !=
662 QString(
"[ReadPCDData] Failed to read data record."));
668 QString(
"PCD data with %1 compressed size, and %2 uncompressed "
670 .arg(compressed_size)
671 .arg(uncompressed_size));
672 std::unique_ptr<char[]> buffer_compressed(
new char[compressed_size]);
673 reporter.Update(
int(reporter_total * .1));
674 if (fread(buffer_compressed.get(), 1, compressed_size, file) !=
677 QString(
"[ReadPCDData] Failed to read data record."));
681 std::unique_ptr<char[]> buffer(
new char[uncompressed_size]);
682 reporter.Update(
int(reporter_total * .2));
683 if (lzf_decompress(buffer_compressed.get(),
684 (
unsigned int)compressed_size, buffer.get(),
685 (
unsigned int)uncompressed_size) !=
692 std::vector<CCVector3>
normals;
693 if (header.has_normals) {
694 normals.resize(
static_cast<unsigned int>(header.points));
697 for (
const auto& field : header.fields) {
698 const char* base_ptr = buffer.get() + field.offset * header.points;
700 double(base_ptr - buffer.get()) / uncompressed_size;
701 reporter.Update(
int(reporter_total * (progress + .2)));
703 if (field.name ==
"x") {
704 for (
size_t i = 0; i < (size_t)header.points; i++) {
706 base_ptr + i * field.size * field.count, field.type,
709 }
else if (field.name ==
"y") {
710 for (
size_t i = 0; i < (size_t)header.points; i++) {
712 base_ptr + i * field.size * field.count, field.type,
715 }
else if (field.name ==
"z") {
716 for (
size_t i = 0; i < (size_t)header.points; i++) {
718 base_ptr + i * field.size * field.count, field.type,
721 }
else if (field.name ==
"normal_x") {
722 for (
size_t i = 0; i < (size_t)header.points; i++) {
723 normals[i].x = UnpackBinaryPCDElement(
724 base_ptr + i * field.size * field.count, field.type,
727 }
else if (field.name ==
"normal_y") {
728 for (
size_t i = 0; i < (size_t)header.points; i++) {
729 normals[i].y = UnpackBinaryPCDElement(
730 base_ptr + i * field.size * field.count, field.type,
733 }
else if (field.name ==
"normal_z") {
734 for (
size_t i = 0; i < (size_t)header.points; i++) {
735 normals[i].z = UnpackBinaryPCDElement(
736 base_ptr + i * field.size * field.count, field.type,
739 }
else if (field.name ==
"rgb" || field.name ==
"rgba") {
740 for (
unsigned int i = 0; i < (
unsigned int)header.points; i++) {
742 base_ptr + i * field.size * field.count, field.type,
746 }
else if (field.name ==
"intensity") {
747 for (
unsigned int i = 0; i < (
unsigned int)header.points; i++) {
748 ScalarType intensity = UnpackBinaryPCDScalar(
749 base_ptr + i * field.size * field.count, field.type,
753 }
else if (field.name ==
"timestamp") {
754 for (
unsigned int i = 0; i < (
unsigned int)header.points; i++) {
755 ScalarType timestamp = UnpackBinaryPCDScalar(
756 base_ptr + i * field.size * field.count, field.type,
760 }
else if (field.name ==
"ring") {
761 for (
unsigned int i = 0; i < (
unsigned int)header.points; i++) {
762 ScalarType ring = UnpackBinaryPCDScalar(
763 base_ptr + i * field.size * field.count, field.type,
770 if (header.has_normals) {
775 if (header.has_ring && cc_ring_field) {
782 if (header.has_intensity && cc_intensity_field) {
789 if (header.has_timestamp && cc_timestamp_field) {
805 CVLog::Warning(QString(
"Read PCD failed: unable to open file: %1")
806 .arg(qPrintable(
filename.c_str())));
810 CVLog::Warning(QString(
"Read PCD failed: unable to parse header."));
816 "per point, and %3 points in total.")
817 .arg(header.fields.size())
818 .arg(header.pointsize)
819 .arg(header.points));
820 for (
const auto& field : header.fields) {
822 .arg(field.name.c_str())
829 QString(
"Compression method is %1.").arg(header.datatype));
831 .arg(header.has_points ?
"yes" :
"no")
832 .arg(header.has_normals ?
"yes" :
"no")
833 .arg(header.has_colors ?
"yes" :
"no"));
848 QStringList{
"pcd"},
"pcd",
849 QStringList{
"Point Cloud Library cloud (*.pcd)"},
850 QStringList{
"Point Cloud Library cloud (*.pcd)"},
855 bool& exclusive)
const {
873 public Ui::PCDOutputFormatDialog {
876 : QDialog(parent, Qt::Tool),
Ui::PCDOutputFormatDialog() {
886 : QDialog(parent),
Ui::SavePCDFileDlg() {
894 if (!entity ||
filename.isEmpty()) {
901 CVLog::Warning(
"[PCL] This filter can only save one cloud at a time!");
905 QSettings settings(
"save pcd");
906 settings.beginGroup(
"SavePcd");
907 bool saveOriginOrientation =
908 settings.value(
"saveOriginOrientation",
true).toBool();
909 bool saveBinary = settings.value(
"SavePCDBinary",
true).toBool();
910 bool compressedMode = settings.value(
"Compressed",
true).toBool();
913 if (outputFileFormat ==
AUTO) {
923 switch (s_previousOutputFileFormat) {
925 dialog.compressedBinaryRadioButton->setChecked(
true);
928 dialog.binaryRadioButton->setChecked(
true);
931 dialog.asciiRadioButton->setChecked(
true);
935 QAbstractButton* clickedButton =
nullptr;
938 dialog.buttonBox, &QDialogButtonBox::clicked,
939 [&](QAbstractButton* button) { clickedButton = button; });
942 if (dialog.compressedBinaryRadioButton->isChecked()) {
944 }
else if (dialog.binaryRadioButton->isChecked()) {
945 outputFileFormat =
BINARY;
946 }
else if (dialog.asciiRadioButton->isChecked()) {
947 outputFileFormat =
ASCII;
952 s_previousOutputFileFormat = outputFileFormat;
955 dialog.buttonBox->button(
956 QDialogButtonBox::StandardButton::YesToAll)) {
965 saveOriginOrientation =
true;
966 switch (outputFileFormat) {
969 compressedMode =
true;
974 compressedMode =
false;
979 compressedMode =
false;
988 saveOriginOrientation = saveOriginOrientation;
989 saveBinary = saveBinary;
990 compressedMode = compressedMode;
993 compressedMode = saveBinary && compressedMode ? true :
false;
995 spfDlg.saveOriginOrientationCheckBox->setChecked(
996 saveOriginOrientation);
997 spfDlg.saveBinaryCheckBox->setChecked(saveBinary);
998 spfDlg.saveCompressedCheckBox->setChecked(compressedMode);
1002 saveOriginOrientation =
1003 spfDlg.saveOriginOrientationCheckBox->isChecked();
1004 saveBinary = spfDlg.saveBinaryCheckBox->isChecked();
1005 compressedMode = spfDlg.saveCompressedCheckBox->isChecked();
1010 settings.setValue(
"saveOriginOrientation", saveOriginOrientation);
1011 settings.setValue(
"SavePCDBinary", saveBinary);
1012 settings.setValue(
"Compressed",
1013 saveBinary && compressedMode ?
true :
false);
1014 settings.endGroup();
1016 PCLCloud::Ptr pclCloud = cc2smReader(ccCloud).getAsSM();
1021 if (saveOriginOrientation) {
1035 Eigen::Vector4f pos;
1036 Eigen::Quaternionf ori;
1039 pos = Eigen::Vector4f::Zero();
1040 ori = Eigen::Quaternionf::Identity();
1050 Eigen::Matrix3f eigrot;
1051 for (
int i = 0; i < 3; ++i)
1052 for (
int j = 0; j < 3; ++j) eigrot(i, j) = mat.
getColumn(j)[i];
1055 ori = Eigen::Quaternionf(eigrot);
1058 if (ccCloud->
size() == 0) {
1061 if (!file.open(QFile::WriteOnly | QFile::Truncate))
1063 QTextStream stream(&file);
1065 if (compressedMode) {
1066 stream << QString(w.generateHeaderBinaryCompressed(*pclCloud,
1071 stream << QString(w.generateHeaderBinary(*pclCloud, pos, ori)
1078 if (compressedMode) {
1080 if (w.writeBinaryCompressed(
1082 *pclCloud, pos, ori) < 0) {
1086 if (pcl::io::savePCDFile(
1088 *pclCloud, pos, ori,
1096 if (ccCloud->
size() == 0) {
1099 if (!file.open(QFile::WriteOnly | QFile::Truncate))
1101 QTextStream stream(&file);
1103 Eigen::Vector4f pos;
1104 Eigen::Quaternionf ori;
1106 if (compressedMode) {
1107 stream << QString(w.generateHeaderBinaryCompressed(*pclCloud,
1112 stream << QString(w.generateHeaderBinary(*pclCloud, pos, ori)
1121 if (hasColor && !hasNormals) {
1122 PointCloudRGB::Ptr rgbCloud(
new PointCloudRGB);
1123 FROM_PCL_CLOUD(*pclCloud, *rgbCloud);
1127 if (compressedMode) {
1128 if (pcl::io::savePCDFileBinaryCompressed(
1137 *rgbCloud, saveBinary) <
1144 }
else if (!hasColor && hasNormals) {
1145 PointCloudNormal::Ptr normalCloud(
new PointCloudNormal);
1146 FROM_PCL_CLOUD(*pclCloud, *normalCloud);
1150 if (compressedMode) {
1151 if (pcl::io::savePCDFileBinaryCompressed(
1160 *normalCloud, saveBinary) <
1167 }
else if (hasColor && hasNormals) {
1168 PointCloudRGBNormal::Ptr rgbNormalCloud(
new PointCloudRGBNormal);
1169 FROM_PCL_CLOUD(*pclCloud, *rgbNormalCloud);
1170 if (!rgbNormalCloud) {
1173 if (compressedMode) {
1174 if (pcl::io::savePCDFileBinaryCompressed(
1184 *rgbNormalCloud, saveBinary) <
1193 PointCloudT::Ptr xyzCloud(
new PointCloudT);
1194 FROM_PCL_CLOUD(*pclCloud, *xyzCloud);
1198 if (compressedMode) {
1199 if (pcl::io::savePCDFileBinaryCompressed(
1208 *xyzCloud, saveBinary) <
1224 Eigen::Vector4f origin;
1225 Eigen::Quaternionf orientation;
1228 unsigned int data_idx;
1229 size_t pointCount = -1;
1230 PCLCloud::Ptr inputCloud(
new PCLCloud);
1236 if (p.readHeader(fileName, *inputCloud, origin, orientation, pcd_version,
1237 data_type, data_idx) < 0) {
1238 CVLog::Warning(QString(
"[PCL] An error occurred while reading PCD "
1239 "header and try to "
1240 "mannually read %1")
1248 "mannually read %1")
1254 pointCount = inputCloud->width * inputCloud->height;
1259 if (pointCount == 0) {
1264 if (pcl::io::loadPCDFile(fileName, *inputCloud, origin, orientation) < 0) {
1266 "pcl::io::loadPCDFile and try to "
1267 "mannually read %1")
1275 "mannually read %1")
1282 if (!inputCloud->is_dense) {
1284 pcl::PassThrough<PCLCloud> passFilter;
1285 passFilter.setInputCloud(inputCloud);
1286 passFilter.filter(*inputCloud);
1293 "[PCL] An error occurred while converting PCD cloud to "
1294 "CloudViewer cloud!");
1297 ccCloud->
setName(QStringLiteral(
"unnamed"));
1304 Eigen::Matrix3f eigrot = orientation.toRotationMatrix();
1309 X[0] = eigrot(0, 0);
1310 X[1] = eigrot(1, 0);
1311 X[2] = eigrot(2, 0);
1312 Y[0] = eigrot(0, 1);
1313 Y[1] = eigrot(1, 1);
1314 Y[2] = eigrot(2, 1);
1315 Z[0] = eigrot(0, 2);
1316 Z[1] = eigrot(1, 2);
1317 Z[2] = eigrot(2, 2);
float PointCoordinateType
Type of the coordinates of a (N-D) point.
int64_t CV_CLASS_ENUM
Type of object type flags (64 bits)
filament::Texture::InternalFormat format
std::vector< PCLPointField > fields
CC_FILE_ERROR
Typical I/O filter errors.
@ CC_FERR_CANCELED_BY_USER
@ CC_FERR_THIRD_PARTY_LIB_FAILURE
@ CC_FERR_BAD_ENTITY_TYPE
static PcdFilter::PCDOutputFileFormat s_outputFileFormat
virtual void release()
Decrease counter and deletes object when 0.
static bool PrintDebug(const char *format,...)
Same as Print, but works only in Debug mode.
static bool Warning(const char *format,...)
Prints out a formatted warning message in console.
static bool Print(const char *format,...)
Prints out a formatted message in console.
PCDOutputFileFormat
Output file format.
virtual CC_FILE_ERROR saveToFile(ccHObject *entity, const QString &filename, const SaveParameters ¶meters)
Saves an entity (or a group of) to a file.
virtual CC_FILE_ERROR loadFile(const QString &filename, ccHObject &container, LoadParameters ¶meters)
Loads one or more entities from a file.
virtual bool canSave(CV_CLASS_ENUM type, bool &multiple, bool &exclusive) const
Returns whether this I/O filter can save the specified type of entity.
static void SetOutputFileFormat(PCDOutputFileFormat format)
Set the output file format.
SavePCDFileDialog(QWidget *parent=nullptr)
Default constructor.
virtual void setVisible(bool state)
Sets entity visibility.
virtual void showSF(bool state)
Sets active scalarfield visibility.
Ground-based Laser sensor.
void setUncertainty(PointCoordinateType u)
Sets the Z-buffer uncertainty on depth values.
bool computeAutoParameters(cloudViewer::GenericCloud *theCloud)
Computes angular parameters automatically (all but the angular steps!)
void setYawStep(PointCoordinateType dTheta)
Sets the yaw step.
void setPitchStep(PointCoordinateType dPhi)
Sets the pitch step.
Vector3Tpl< T > getTranslationAsVec3D() const
Returns a copy of the translation as a CCVector3.
void setTranslation(const Vector3Tpl< float > &Tr)
Sets translation (float version)
T * getColumn(unsigned index)
Returns a pointer to a given column.
Float version of ccGLMatrixTpl.
A 3D cloud interface with associated features (color, normals, octree, etc.)
ccBBox getOwnBB(bool withGLFeatures=false) override
Returns the entity's own bounding-box.
static ccPointCloud * ToPointCloud(ccHObject *obj, bool *isLockedVertices=nullptr)
Converts current object to 'equivalent' ccPointCloud.
static ccGenericPointCloud * ToGenericPointCloud(ccHObject *obj, bool *isLockedVertices=nullptr)
Converts current object to 'equivalent' ccGenericPointCloud.
static ccSensor * ToSensor(ccHObject *obj)
Converts current object to ccSensor (if possible)
Hierarchical CLOUDVIEWER Object.
unsigned getChildrenNumber() const
Returns the number of children.
virtual bool addChild(ccHObject *child, int dependencyFlags=DP_PARENT_OF_OTHER, int insertIndex=-1)
Adds a child.
ccHObject * getChild(unsigned childPos) const
Returns the ith child.
virtual void setName(const QString &name)
Sets object name.
virtual void setEnabled(bool state)
Sets the "enabled" property.
Dialog for the PCV plugin.
ccPCDFileOutputForamtDialog(QWidget *parent=nullptr)
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
void setCurrentDisplayedScalarField(int index)
Sets the currently displayed scalar field.
void addNorms(const std::vector< CCVector3 > &Ns)
void addNorm(const CCVector3 &N)
Pushes a normal vector on stack (shortcut)
int addScalarField(const char *uniqueName) override
Creates a new scalar field and registers it.
bool hasNormals() const override
Returns whether normals are enabled or not.
bool resizeTheRGBTable(bool fillWithWhite=false)
Resizes the RGB colors array.
bool reserveTheNormsTable()
Reserves memory to store the compressed normals.
void clear() override
Clears the entity from all its points and features.
bool hasColors() const override
Returns whether colors are enabled or not.
bool resize(unsigned numberOfPoints) override
Resizes all the active features arrays.
void deleteScalarField(int index) override
Deletes a specific scalar field.
void setPointColor(size_t pointIndex, const ecvColor::Rgb &col)
Sets a particular point color.
A scalar field associated to display-related parameters.
void computeMinAndMax() override
Determines the min and max values.
Generic sensor interface.
virtual ccGLMatrix & getRigidTransformation()
virtual void setRigidTransformation(const ccGLMatrix &mat)
void setGraphicScale(PointCoordinateType scale)
Sets the sensor graphic representation scale.
T getDiagNorm() const
Returns diagonal length.
int getScalarFieldIndexByName(const char *name) const
Returns the index of a scalar field represented by its name.
CCVector3 * getPointPtr(size_t index)
unsigned size() const override
void setPoint(size_t index, const CCVector3 &P)
void addElement(ScalarType value)
bool reserveSafe(std::size_t count)
Reserves memory (no exception thrown)
#define DEFAULT_IO_BUFFER_SIZE
Helper functions for the ml ops.
bool ReadPointCloudFromPCD(const std::string &filename, ccPointCloud &pointcloud, const ReadPointCloudOption ¶ms)
static bool ReadPCDData(FILE *file, PCDHeader &header, t::geometry::PointCloud &pointcloud, const ReadPointCloudOption ¶ms)
static bool ReadPCDHeader(FILE *file, PCDHeader &header)
static void UnpackASCIIPCDElement(scalar_t &data, const char *data_ptr)=delete
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.
RgbTpl< ColorCompType > Rgb
3 components, default type
Generic loading parameters.
Generic saving parameters.
QWidget * parentWidget
Parent widget (if any)