|
10 | 10 | #include <memory>
|
11 | 11 | #include <ostream>
|
12 | 12 | #include <stdexcept>
|
| 13 | +#include <streambuf> |
13 | 14 | #include <vector>
|
14 | 15 |
|
15 | 16 | #include <yarp/os/LogStream.h>
|
|
18 | 19 |
|
19 | 20 | namespace
|
20 | 21 | {
|
| 22 | + // https://github.com/ddiakopoulos/tinyply/blob/master/source/example-utils.hpp |
| 23 | + |
| 24 | + struct memory_buffer : public std::streambuf |
| 25 | + { |
| 26 | + char * p_start {nullptr}; |
| 27 | + char * p_end {nullptr}; |
| 28 | + std::size_t size; |
| 29 | + |
| 30 | + memory_buffer(char const * first_elem, std::size_t size) |
| 31 | + : p_start(const_cast<char *>(first_elem)), p_end(p_start + size), size(size) |
| 32 | + { |
| 33 | + setg(p_start, p_start, p_end); |
| 34 | + } |
| 35 | + |
| 36 | + pos_type seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which) override |
| 37 | + { |
| 38 | + if (dir == std::ios_base::cur) gbump(static_cast<int>(off)); |
| 39 | + else setg(p_start, (dir == std::ios_base::beg ? p_start : p_end) + off, p_end); |
| 40 | + return gptr() - p_start; |
| 41 | + } |
| 42 | + |
| 43 | + pos_type seekpos(pos_type pos, std::ios_base::openmode which) override |
| 44 | + { |
| 45 | + return seekoff(pos, std::ios_base::beg, which); |
| 46 | + } |
| 47 | + }; |
| 48 | + |
| 49 | + struct memory_stream : virtual memory_buffer, public std::istream |
| 50 | + { |
| 51 | + memory_stream(char const * first_elem, size_t size) |
| 52 | + : memory_buffer(first_elem, size), std::istream(static_cast<std::streambuf *>(this)) {} |
| 53 | + }; |
| 54 | + |
21 | 55 | void write(std::ostream & os, const yarp::sig::PointCloudXY & cloud, const yarp::sig::VectorOf<int> & vertices, bool isBinary)
|
22 | 56 | {
|
23 | 57 | tinyply::PlyFile ply;
|
@@ -373,7 +407,7 @@ namespace
|
373 | 407 | return it->size;
|
374 | 408 | }
|
375 | 409 |
|
376 |
| - bool read(std::ifstream & ifs, yarp::sig::PointCloudXY & cloud, yarp::sig::VectorOf<int> & vertices) |
| 410 | + bool read(std::istream & ifs, yarp::sig::PointCloudXY & cloud, yarp::sig::VectorOf<int> & vertices) |
377 | 411 | {
|
378 | 412 | tinyply::PlyFile file;
|
379 | 413 |
|
@@ -411,7 +445,7 @@ namespace
|
411 | 445 | return false;
|
412 | 446 | }
|
413 | 447 |
|
414 |
| - bool read(std::ifstream & ifs, yarp::sig::PointCloudXYZ & cloud, yarp::sig::VectorOf<int> & vertices) |
| 448 | + bool read(std::istream & ifs, yarp::sig::PointCloudXYZ & cloud, yarp::sig::VectorOf<int> & vertices) |
415 | 449 | {
|
416 | 450 | tinyply::PlyFile file;
|
417 | 451 |
|
@@ -452,7 +486,7 @@ namespace
|
452 | 486 | return false;
|
453 | 487 | }
|
454 | 488 |
|
455 |
| - bool read(std::ifstream & ifs, yarp::sig::PointCloudNormal & cloud, yarp::sig::VectorOf<int> & vertices) |
| 489 | + bool read(std::istream & ifs, yarp::sig::PointCloudNormal & cloud, yarp::sig::VectorOf<int> & vertices) |
456 | 490 | {
|
457 | 491 | tinyply::PlyFile file;
|
458 | 492 |
|
@@ -507,7 +541,7 @@ namespace
|
507 | 541 | return false;
|
508 | 542 | }
|
509 | 543 |
|
510 |
| - bool read(std::ifstream & ifs, yarp::sig::PointCloudXYZRGBA & cloud, yarp::sig::VectorOf<int> & vertices) |
| 544 | + bool read(std::istream & ifs, yarp::sig::PointCloudXYZRGBA & cloud, yarp::sig::VectorOf<int> & vertices) |
511 | 545 | {
|
512 | 546 | tinyply::PlyFile file;
|
513 | 547 |
|
@@ -574,7 +608,7 @@ namespace
|
574 | 608 | return false;
|
575 | 609 | }
|
576 | 610 |
|
577 |
| - bool read(std::ifstream & ifs, yarp::sig::PointCloudXYZI & cloud, yarp::sig::VectorOf<int> & vertices) |
| 611 | + bool read(std::istream & ifs, yarp::sig::PointCloudXYZI & cloud, yarp::sig::VectorOf<int> & vertices) |
578 | 612 | {
|
579 | 613 | tinyply::PlyFile file;
|
580 | 614 |
|
@@ -629,7 +663,7 @@ namespace
|
629 | 663 | return false;
|
630 | 664 | }
|
631 | 665 |
|
632 |
| - bool read(std::ifstream & ifs, yarp::sig::PointCloudInterestPointXYZ & cloud, yarp::sig::VectorOf<int> & vertices) |
| 666 | + bool read(std::istream & ifs, yarp::sig::PointCloudInterestPointXYZ & cloud, yarp::sig::VectorOf<int> & vertices) |
633 | 667 | {
|
634 | 668 | tinyply::PlyFile file;
|
635 | 669 |
|
@@ -684,7 +718,7 @@ namespace
|
684 | 718 | return false;
|
685 | 719 | }
|
686 | 720 |
|
687 |
| - bool read(std::ifstream & ifs, yarp::sig::PointCloudXYZNormal & cloud, yarp::sig::VectorOf<int> & vertices) |
| 721 | + bool read(std::istream & ifs, yarp::sig::PointCloudXYZNormal & cloud, yarp::sig::VectorOf<int> & vertices) |
688 | 722 | {
|
689 | 723 | tinyply::PlyFile file;
|
690 | 724 |
|
@@ -751,7 +785,7 @@ namespace
|
751 | 785 | return false;
|
752 | 786 | }
|
753 | 787 |
|
754 |
| - bool read(std::ifstream & ifs, yarp::sig::PointCloudXYZNormalRGBA & cloud, yarp::sig::VectorOf<int> & vertices) |
| 788 | + bool read(std::istream & ifs, yarp::sig::PointCloudXYZNormalRGBA & cloud, yarp::sig::VectorOf<int> & vertices) |
755 | 789 | {
|
756 | 790 | tinyply::PlyFile file;
|
757 | 791 |
|
@@ -899,17 +933,31 @@ bool loadPLY(const std::string & filename, yarp::sig::PointCloud<T> & cloud)
|
899 | 933 | template <typename T>
|
900 | 934 | bool loadPLY(const std::string & filename, yarp::sig::PointCloud<T> & cloud, yarp::sig::VectorOf<int> & vertices)
|
901 | 935 | {
|
902 |
| - std::ifstream ifs(filename); |
| 936 | + std::ifstream ifs(filename, std::ios::binary); |
903 | 937 |
|
904 | 938 | if (ifs.fail())
|
905 | 939 | {
|
906 | 940 | yError() << "unable to open" << filename << "for read";
|
907 | 941 | return false;
|
908 | 942 | }
|
909 | 943 |
|
| 944 | + std::vector<std::uint8_t> fileBufferBytes; |
| 945 | + ifs.seekg(0, std::ios::end); |
| 946 | + std::size_t sizeBytes = ifs.tellg(); |
| 947 | + ifs.seekg(0, std::ios::beg); |
| 948 | + fileBufferBytes.resize(sizeBytes); |
| 949 | + |
| 950 | + if (!ifs.read((char *)fileBufferBytes.data(), sizeBytes)) |
| 951 | + { |
| 952 | + yError() << "unable to read from" << filename; |
| 953 | + return false; |
| 954 | + } |
| 955 | + |
| 956 | + memory_stream ms((char *)fileBufferBytes.data(), fileBufferBytes.size()); |
| 957 | + |
910 | 958 | try
|
911 | 959 | {
|
912 |
| - return read(ifs, cloud, vertices); |
| 960 | + return read(ms, cloud, vertices); |
913 | 961 | }
|
914 | 962 | catch (const std::exception & e)
|
915 | 963 | {
|
|
0 commit comments