Giter Site home page Giter Site logo

tinyply's People

Contributors

3descape avatar adrian-bodenmann avatar ataber avatar atablash avatar bchretien avatar bradleymarie avatar ddiakopoulos avatar eren121 avatar holynski avatar jiri avatar maruncz avatar mfpgs avatar myd7349 avatar nigels-com avatar ohadmen avatar ramonarguelles avatar svenevs avatar vertexwahn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tinyply's Issues

tinyply 2.0 crashes on malformed file

Hi

i created this corrupted ply file
ply
format ascii 1.0
element vertex 16
property float x
property float y
property float z
.13043 0 255 0 0
10 7 0 255 0 0
10.9091 10 0 255 0 0
9.88235 9.05882 0 255 0 0
12 8 0 255 0 0
12 10 0 255 0 0
3 12 13 14
3 12 14 15
3 8 9 10
3 8 10 11
3 4 5 6
3 4 6 7
3 0 1 2
3 0 2 3

each vertex has aditional properties

but tinyply 2.0 will silently load this file and i get this ((1,1,1,1) color, (0,0,0) normal and 0 scalar are default if not fund)
vertices:
pos: vec3(10.000000, 7.000000, 0.000000) color: vec4(1.000000, 1.000000, 1.000000, 1.000000) normal: vec3(0.000000, 0.000000, 0.000000) scalar: 0
pos: vec3(255.000000, 0.000000, 0.000000) color: vec4(1.000000, 1.000000, 1.000000, 1.000000) normal: vec3(0.000000, 0.000000, 0.000000) scalar: 0
pos: vec3(10.909100, 10.000000, 0.000000) color: vec4(1.000000, 1.000000, 1.000000, 1.000000) normal: vec3(0.000000, 0.000000, 0.000000) scalar: 0
pos: vec3(255.000000, 0.000000, 0.000000) color: vec4(1.000000, 1.000000, 1.000000, 1.000000) normal: vec3(0.000000, 0.000000, 0.000000) scalar: 0
pos: vec3(9.882350, 9.058820, 0.000000) color: vec4(1.000000, 1.000000, 1.000000, 1.000000) normal: vec3(0.000000, 0.000000, 0.000000) scalar: 0
pos: vec3(255.000000, 0.000000, 0.000000) color: vec4(1.000000, 1.000000, 1.000000, 1.000000) normal: vec3(0.000000, 0.000000, 0.000000) scalar: 0
pos: vec3(12.000000, 8.000000, 0.000000) color: vec4(1.000000, 1.000000, 1.000000, 1.000000) normal: vec3(0.000000, 0.000000, 0.000000) scalar: 0
pos: vec3(255.000000, 0.000000, 0.000000) color: vec4(1.000000, 1.000000, 1.000000, 1.000000) normal: vec3(0.000000, 0.000000, 0.000000) scalar: 0
pos: vec3(12.000000, 10.000000, 0.000000) color: vec4(1.000000, 1.000000, 1.000000, 1.000000) normal: vec3(0.000000, 0.000000, 0.000000) scalar: 0
pos: vec3(255.000000, 0.000000, 0.000000) color: vec4(1.000000, 1.000000, 1.000000, 1.000000) normal: vec3(0.000000, 0.000000, 0.000000) scalar: 0
pos: vec3(3.000000, 12.000000, 13.000000) color: vec4(1.000000, 1.000000, 1.000000, 1.000000) normal: vec3(0.000000, 0.000000, 0.000000) scalar: 0
pos: vec3(14.000000, 3.000000, 12.000000) color: vec4(1.000000, 1.000000, 1.000000, 1.000000) normal: vec3(0.000000, 0.000000, 0.000000) scalar: 0
pos: vec3(14.000000, 15.000000, 3.000000) color: vec4(1.000000, 1.000000, 1.000000, 1.000000) normal: vec3(0.000000, 0.000000, 0.000000) scalar: 0
pos: vec3(8.000000, 9.000000, 10.000000) color: vec4(1.000000, 1.000000, 1.000000, 1.000000) normal: vec3(0.000000, 0.000000, 0.000000) scalar: 0
pos: vec3(3.000000, 8.000000, 10.000000) color: vec4(1.000000, 1.000000, 1.000000, 1.000000) normal: vec3(0.000000, 0.000000, 0.000000) scalar: 0
pos: vec3(11.000000, 3.000000, 4.000000) color: vec4(1.000000, 1.000000, 1.000000, 1.000000) normal: vec3(0.000000, 0.000000, 0.000000) scalar: 0
faces:

as you can see those aditional properties gets loaded into position vector

avoid deleting old releases?

Since this github seems to serve as the primary archive of releases it would be good if you could avoid removing releases from the repo. When you do this is breaks any links present in, for example, rpm spec files, or other package metadata files.

Thanks :)

Does not handle large files

Parsing files larger than 4GiB fails. It could be due to the data cursor contains an uint32_t offset. Replacing all internal sizes of 32-bit type with 64-bit equivalents fixes this.

error: no member named 'memcpy' in namespace 'std'

Including #include<cstring> solves this for me.

tinyply.cpp:378:26: error: no member named 'memcpy' in namespace 'std' [clang-diagnostic-error]
                    std::memcpy(listSize, &p.listCount, sizeof(uint32_t));
                         ^
tinyply.cpp: In member function ‘void tinyply::PlyFile::PlyFileImpl::write_binary_internal(std::ostream&)’:
tinyply.cpp:378:26: error: ‘memcpy’ is not a member of ‘std’
                     std::memcpy(listSize, &p.listCount, sizeof(uint32_t));
                          ^~~~~~
tinyply.cpp:378:26: note: suggested alternative: ‘mem_fn’
                     std::memcpy(listSize, &p.listCount, sizeof(uint32_t));
                          ^~~~~~

non-const uint8_t*

In PlyFile::add_properties_to_element I notice that argument uint8_t* data is a pointer to non-const data. Is this buffer modified by the function? If so, some comment to that effect would be helpful. If not, please change to const uint8_t* data.

Buffer overrun: PLY with a header that specifies more vertices than what the file really has

Aka, if the header says there are 20 vertices, but the contents only have 19, you'll hit the problem.

Looking a little bit into the code, tinyply already uses the information from the header to allocate a buffer that should fit the file contents. The size of the buffer is thus known, but it is not passed all the way down. We coded a simple fix that mainly passes the buffer size a couple of frames down into the stack, when we are about to read from the file and copy into the buffer. If we pass the buffer size down, we can check if the copy is going to fit, and if not, throw an exception instead of attempting to reference beyond the buffer.

We tested our local fix with both master and variable-length branches, and it does seem to work. So, we are unblocked. But wanted to post the issue in case we can either directly contribute it back, or just share what we did for a potential future fix.

Thanks!

Silencing compilation warnings

Hey, thanks for the the great library.

Compiling the with -Wall -Wextra -Wpedantic -Wshadow shows the following warnings

tinyply/source/tinyply.h:77:29: warning: declaration shadows a field of 'tinyply::Buffer' [-Wshadow]
        Buffer(const size_t size) : data(new uint8_t[size], delete_array()), size(size) { alias = data.get(); } // allocating
                            ^
tinyply/source/tinyply.h:74:16: note: previous declaration is here
        size_t size;
               ^
tinyply/source/tinyply.h:393:78: warning: unused parameter 'is' [-Wunused-parameter]
void PlyFile::PlyFileImpl::read_header_text(std::string line, std::istream & is, std::vector<std::string>& place, int erase)
                                                                             ^
tinyply/source/tinyply.h:417:64: warning: unused parameter 't' [-Wunused-parameter]
size_t PlyFile::PlyFileImpl::read_property_binary(const Type & t, const size_t & stride, void * dest, size_t & destOffset, std::istream & is)
                                                               ^
tinyply/source/tinyply.h:460:55: warning: unused parameter 't' [-Wunused-parameter]
void PlyFile::PlyFileImpl::write_property_binary(Type t, std::ostream & os, uint8_t * src, size_t & srcOffset, const size_t & stride)
                                                      ^
tinyply/source/tinyply.h:473:17: warning: unused variable 'b' [-Wunused-variable]
    for (auto & b : buffers) for (auto & entry : userData) list_hints += entry.second.list_size_hint;
                ^
tinyply/source/tinyply.h:600:39: warning: comparison of integers of different signs: 'int' and 'size_t' (aka 'unsigned long') [-Wsign-compare]
                    for (int j = 0; j < p.listCount; ++j)
                                    ~ ^ ~~~~~~~~~~~
tinyply/source/tinyply.h:691:101: warning: adding 'uint32_t' (aka 'unsigned int') to a string does not append to the string [-Wstring-plus-int]
                    throw std::invalid_argument("element-property key has already been requested: " + hash_fnv1a(element.name + property.name));
                                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tinyply/source/tinyply.h:691:101: note: use array indexing to silence this warning
                    throw std::invalid_argument("element-property key has already been requested: " + hash_fnv1a(element.name + property.name));
                                                                                                    ^
                                                &                                                   [                                         ]
tinyply/source/tinyply.h:767:21: warning: 5 enumeration values not handled in switch: 'INVALID', 'INT8', 'UINT8'... [-Wswitch]
            switch (t)
                    ^

Would it be possible to remedy these?

return unique_ptr's instead of shared_ptr's

Right now methods like request_properties_from_element return shared pointers to PlyData objects. However, shared pointers have their own overheads and often they have a singular owner which makes their "sharedness" redundant.

However, it's possible to assume that all requests return PlyData with a single owner by default using a unique_ptr and it's always possible to automatically convert it to a shared_ptr where shared ownership is actually needed. Due to obvious reasons, it's impossible to do the opposite and convert a pointer with shared ownership to an object with unique ownership. For example this compiles perfectly fine:

std::unique_ptr<SomeData> get_data();
int main()
{
  std::shared_ptr<SomeData> shared_data = get_data();
  std::unique_ptr<SomeData> unique_data = get_data();
  return 0;
}

Including the header brings in std and tinyply namespace

When including the library with #define TINYPLY_IMPLEMENTATION, the std and tinyply namespaces are automatically included via using declarations. This introduces in a lot of very common names (like Type and Buffer from tinyply:: or vector from std::) into the declarative region that is using tinyply and can lead to unexpected and hard to debug errors.

As a fix, I suggest to write the implementation like this

namespace tinyply
{
  using namespace std;
  // implementation here
}

Catch Exception on Ascii Ply

Hello,Is there anythong wrong in the new commit?
I just clone the repository and run the example but got exception when reading example_cube-ascii.ply:

........................................................................
Now Reading: example_cube-ascii.ply
        [ply_header] Type: ascii
        [ply_header] Comment: generated by tinyply 2.3
        [ply_header] element: vertex (24)
        [ply_header]    property: x (type=float)
        [ply_header]    property: y (type=float)
        [ply_header]    property: z (type=float)
        [ply_header]    property: nx (type=float)
        [ply_header]    property: ny (type=float)
        [ply_header]    property: nz (type=float)
        [ply_header]    property: u (type=float)
        [ply_header]    property: v (type=float)
        [ply_header] element: face (12)
        [ply_header]    property: vertex_indices (type=uint) (list_type=uchar)
tinyply exception: the following property keys were not found in the header: red, green, blue, alpha,
tinyply exception: the following property keys were not found in the header: r, g, b, a,
tinyply exception: the element key was not found in the header: tristrips
Caught tinyply exception: unexpected EOF. malformed file?
........................................................................
Now Reading: example_cube-binary.ply
        [ply_header] Type: binary
        [ply_header] Comment: generated by tinyply 2.3
        [ply_header] element: vertex (24)
        [ply_header]    property: x (type=float)
        [ply_header]    property: y (type=float)
        [ply_header]    property: z (type=float)
        [ply_header]    property: nx (type=float)
        [ply_header]    property: ny (type=float)
        [ply_header]    property: nz (type=float)
        [ply_header]    property: u (type=float)
        [ply_header]    property: v (type=float)
        [ply_header] element: face (12)
        [ply_header]    property: vertex_indices (type=uint) (list_type=uchar)
tinyply exception: the following property keys were not found in the header: red, green, blue, alpha,
tinyply exception: the following property keys were not found in the header: r, g, b, a,
tinyply exception: the element key was not found in the header: tristrips
        parsing 0.001217mb in 4.04e-05 seconds [30.1238 MBps]
        Read 24 total vertices
        Read 24 total vertex normals
        Read 24 total vertex texcoords
        Read 12 total faces (triangles)

Same exception occured when I try another ascii ply.
I compiled the code on windows msvc/wsl2 and no one was spared.

warning: C4267: 'return': conversion from 'size_t' to 'int', possible loss of data

Congratulating for the 2.0 version!
I would like to address some warnings that keep appearing which annoyed me a lot:

...\tinyply\source\tinyply.cpp(206): warning C4100: 'is': unreferenced formal parameter
...\tinyply\source\tinyply.cpp(472): warning C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data
...\tinyply\source\tinyply.cpp(472): warning C4267: 'initializing': conversion from 'size_t' to 'const int', possible loss of data
...\tinyply\source\tinyply.cpp(485): warning C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data
...\tinyply\source\tinyply.cpp(485): warning C4267: 'initializing': conversion from 'size_t' to 'const int', possible loss of data
...\tinyply\source\tinyply.cpp(520): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data
...\tinyply\source\tinyply.cpp(526): warning C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data
``

Thanks.

Writing large files is slow

I'm not sure what kinds of transformations on the data you're doing as it's being written, it doesn't look like much, but for whatever reason it is significantly slowing down the writing of files. I've got files that are ~0.5-1 GB that I'm exporting using your library (which - other than this hiccup - works beautifully btw) and it is suuuuuuuuuuuuper slow. Here is a super-accurate benchmark for you:

Writing to disk... Buffer size is: 1048576 bytes
Closing file... Took 142169 ms
fstream mode
170 ms

That's like 830x slower!!! I understand like 2x... or 4x, but 800!?!?!? The relevant code snippet is as follows:

const size_t bufsize = 1024 * 1024;
  { // just to help deny file-handle leak
    // std::filebuf fb;
    // fb.open(filename, std::ios::out | std::ios::binary);
    // std::ostream outputStream(&fb);
    std::fstream outputStream(filename, std::fstream::out | std::fstream::binary | std::fstream::trunc);
    // set up buffering
    // const size_t bufsize = 1024 * 1024;
    char* buf = (char*)malloc(bufsize);
    outputStream.rdbuf()->pubsetbuf(buf, bufsize);
    std::cout << "Writing to disk... Buffer size is: " << bufsize << " bytes\n";
    auto start = std::chrono::high_resolution_clock::now();
    ply.write(outputStream, true);
    auto duration = (std::chrono::duration_cast<std::chrono::milliseconds>(
        std::chrono::high_resolution_clock::now() - start).count());
    std::cout << "Closing file... Took " << duration << " ms\n";
    free(buf);
    outputStream.close();
  }

  // test for speedz
  {
    const size_t sz = 512 * 1024 * 1024;
    const int numiter = 1;
    std::unique_ptr<char[]> data(new char[sz]);
    std::unique_ptr<char[]> buf(new char[bufsize]);
    for (size_t p = 0; p < sz; p += 16) {
      memcpy(&data[p], "BINARY.DATA.....", 16);
    }
    unlink("file.binary");
    int64_t total = 0;
    std::cout << "fstream mode\n";
    std::ofstream myfile("file.binary", std::ios::out | std::ios::binary);
    if (!myfile) {
      std::cerr << "open failed\n"; return 1;
    }
    myfile.rdbuf()->pubsetbuf(buf.get(), bufsize); // IMPORTANT
    for (int i = 0; i < numiter; ++i) {
      auto tm1 = std::chrono::high_resolution_clock::now();
      myfile.write(data.get(), sz);
      if (!myfile)
        std::cerr << "write failed\n";
      auto tm = (std::chrono::duration_cast<std::chrono::milliseconds>(
        std::chrono::high_resolution_clock::now() - tm1).count());
      std::cout << tm << " ms\n";
      total += tm;
    }
    myfile.close();
  }

and the file I'm writing using TinyPLY ends up being ~312MB while the test for speedz section outputs a 512MB file. How can we speed this up?? Let me know if there is anything in particular you want me to try.

Thanks in advance!

VS2019 Compiler Warnings?

First of all, thank you very much for this excellent library.

Nonetheless VS2019 tells me that there is an unused variable (warning C4189). And I think there is an issue:

file: tinyply.h
line: 473
method: PlyFile::PlyFileImpl::read(std::istream & is)

` // Discover if we can allocate up front without parsing the file twice

uint32_t list_hints = 0;

for (auto & b : buffers) for (auto & entry : userData) list_hints += entry.second.list_size_hint;

`

The lool for (auto & b : buffers) seems wrong to me. VS2019 warns that b is unused which is true. My guess is that the loop should be removed, and even better, the variable list_hints might be computed in the loop on line 469 what would perform better.

Tags instead of continuous branch

Can I request tags instead of a continuously changing branch for 2.0? That would help me in the workflow I have, where I am using a build system that downloads a tarball from github and verifies the checksum before installing it. If the branch is changing, this will break often; if immutable tags are used instead, it's robust.

Write methods should respect const input

The add_properties_to_element() should have "const uint_t* data" because the write routine should principally never modify the input mesh. The more generic WriteMesh() upstream enforces a const assumption on all wrtiers, so tinyply has to be modified for things to work.

Changing the data type has consequences to other pieces of tinyply because the data is wrapped in Buffer(). One solution is to add another constant pointer and use getConstant() when writing parameters. There needs to be some sanity checking that we're using the right pointer at the right time.

class Buffer
{
    uint8_t * alias{ nullptr };
    const uint8_t * calias{ nullptr };
    struct delete_array { void operator()(uint8_t * p) { delete[] p; } };
    std::unique_ptr<uint8_t, decltype(Buffer::delete_array())> data;
    size_t size {0};
public:
    Buffer() {};
    Buffer(const size_t size) : data(new uint8_t[size], delete_array()), size(size) { alias = data.get(); } // allocating
    Buffer(uint8_t * ptr): alias(ptr) { } // non-allocating, todo: set size?
    Buffer(const uint8_t * ptr): calias(ptr) { }
    uint8_t * get() { return alias; }
    const uint8_t* getConstant() const { return calias; }
    size_t size_bytes() const { return size; }
};

Progress Indicator / Callback?

Useful for providing a progress bar when loading huge point ply files. Also to allow the user to abort the import process

Suggestion 1

Allow loading the ply file chunk-wise. For example, allow the user to call read with a range of vertices/faces to be loaded.

The user could call read(size_t begin, size_t end) with range like saying, load the vertices from 100000 to 100100. This would also make implementing a progress bar (and aborting the loading process) possible without having to integrate a callback function.

Suggestion 2

Every 10000 vertices or so, a user provided callback function could be called.

request_properties_from_element crash

Hey!

I just stumble upon crash that happens when I try to load all properties to one buffer as:
file.request_properties_from_element("vertex", { "x", "y", "z", "nx", "ny", "nz", "s", "t", "red", "green", "blue" });

I checked and it crashes only when non uniform types are present on the list (colors are uint8, while the others float32). Is it on purpose? If that is the case, could you consider making a feature that copes with that? (maybe bytes stride inferred from listed properties types could give a hint for further processing and interpreting the data).

Best,
Bartek

write variable length lists (tinyply 2.0)

Hi,
the readme of tinyply 2.0 states:

Version 2.0 is mostly an API re-write, although various bits of the implementation have been changed. In fact, the changes reduce the overall speed of the library around 5%, although at much greater flexibility for further improvements to support variable length lists. One notable change is that tinyply now produces and consumes untyped byte buffers, with type information held as metadata.

Unfortunately there is no example how to write (and read) a variable length list in the example. I wonder how this works. I would basically like to write/read this

ply
format ascii 1.0
comment author: Greg Turk
comment object: another cube
element vertex 8
property float x
property float y
property float z
property uchar red                   { start of vertex color }
property uchar green
property uchar blue
element face 7
property list uchar int vertex_index  { number of vertices for each face }
element edge 5                        { five edges in object }
property int vertex1                  { index to first vertex of edge }
property int vertex2                  { index to second vertex }
property uchar red                    { start of edge color }
property uchar green
property uchar blue
end_header
0 0 0 255 0 0                         { start of vertex list }
0 0 1 255 0 0
0 1 1 255 0 0
0 1 0 255 0 0
1 0 0 0 0 255
1 0 1 0 0 255
1 1 1 0 0 255
1 1 0 0 0 255
3 0 1 2                           { start of face list, begin with a triangle }
3 0 2 3                           { another triangle }
4 7 6 5 4                         { now some quadrilaterals }
4 0 4 5 1
4 1 5 6 2
4 2 6 7 3
4 3 7 4 0
0 1 255 255 255                   { start of edge list, begin with white edge }
1 2 255 255 255
2 3 255 255 255
3 0 255 255 255
2 0 0 0 0                         { end with a single black line }

where lists should be represented by a std::vector<std::vector<T>>. Is this supported by tinyply 2.0?

I also saw this was discussed here and here but this is quite old and it is not clear to me what ended up in upstream (branch 2.0) and what is only available in some forks etc.?

What exactly does list_size_hint in request_properties_from_element refer to?

Does it refer to the number of elements in a list or the size in number of bytes? Or something else?

For example, if I have a file with header like this:

ply
format ascii 1.0
element vertex 10
property float x
property float y
property float z
property uchar red
property uchar green
property uchar blue
property float nx
property float ny
property float nz
end_header

and rows like this:

52.4691 1.49131 82.4518 108 81 62 -0.175547 0.335647 0.925486

Would the list_size_hint be 9 or 27 (6 x 4 + 3 x 1)?

error while reading ascii PLY files

hi there,
i am exporting from 3dsmax in the ply format, for each ply export in cant read the ascii file, tinyply generates an error
teapot_ascii.zip

you will find joind an example file
the error is generated at:

template<typename T> void ply_cast_ascii(void * dest, std::istream & is)
{
    *(static_cast<T *>(dest)) = ply_read_ascii<T>(is);
}

PlyFile::read ignores order of requested properties

Let's assume I have the following dummy .ply file:

ply
format ascii 1.0
element vertex 3
property float x
property float y
property float z
property uchar blue
property uchar green
property uchar red
end_header
1 2 3 200 201 202
4 5 6 203 204 205
7 8 9 206 207 208

Please note the order of blue, green and red properties.

Then, I want to load this information into a pre-made structure an external library imposes on me, the peculiarity being that it represents color values encoded in memory in a specific order. You can read this issue in a twofold manner: either order is BGR in the .ply file and RGB in my custom structure, or order is RGB in the .ply and BGR in said structure.

In other words, the order of properties in the .ply file differs from the order of properties as represented in memory by the structure, let's name it float3 in the example below. My attempt to circumvent this scenario is to request said properties in the order expected by float3:

struct float3 { float red, green, blue; }; // RGB

tinyply::PlyFile file;
// boilerplate omitted, we open a .ply file with color properties encoded as BGR

auto rgb = file.request_properties_from_element("vertex", {"red", "green", "blue"});
// now load `rgb` into an instance of `float3`

I'd expect tinyply to parse the .ply in the order specified in request_properties_from_element, which is what I ultimately want to memcpy into my float3 structure. However, tinyply reads actual blue values as red and viceversa, simply following the order of properties in the .ply file.

Any way to polymorphically accept `float` and `double` attributes?

In my application I have to deal with meshes that can have positions of either float or double length. I've kinda sorta hacked something together by try-catching the error tinyply throws if the attribute isn't the right type, but I'm wondering if there's a better way to do it? Possibly by reading the header and exposing the property types to the client?

Built library is large

The built tinyply library target (libtinyply.a in my Cmake project) is 1.6 M. This seems pretty large for a library advertised as "tiny". For comparison, rply builds to about 88 K. Is there a way to trim down the final size of the library?

Using std::vector for propertyKeys ?

I do not want the propertyKeys hardcoded eg for request_properties_from_element(), I want to use std::vector instead of std::initializer_list to allow specifying the property names dynamically.

Maybe there's an obvious solution I cannot see (instead of patching tinyply.h)

My native language is C, I am not as fluent in C++ ... type casting tricks I tried based on what I read on stackoverflow failed, maybe they were dependent on the compiler (options?) or the standard library implementation, anyway I could not manage to make it work with g++

Thanks in advance !

Reading file causes heap corruption

Hey there!
Lately I am fighting with heap corruptions, that are caused by the custom deleter used by the class Buffer.
This bug probably related to #3 and #46.

The file I tried to parse, uses tri- and quadfaces; while latter were unwanted it causes your parser to exhibit following behavior:

Reading the lists with a size hint

const auto index_buffer = ply.request_properties_from_element("face", {"vertex_indices"}, 3);

causes a Heap corruption, when cleaning up the buffer.

Omitting the list_size_hint yields the exception, that "Variable length lists are not supported." as probably expected.

Reading Error: All zeros when reading huge ply file (>2GB on Windows, >2.48GB on Ubuntu)

All the points are (0, 0, 0) when I read a huge .ply file, both on Windows and Linux.
I seem to have figured out why:
I pre-load the entire file upfront (preload_into_memory = true), just like in example.cpp and example-utils.hpp. (It seems to be prepared for files smaller than 1GB. It's already stated in the notes.)
In my experiment, this occurs when the .ply file > 2.01GB (2160000275 bytes) on Windows, and > 2.48GB (2685605907 bytes) on Ubuntu.

But the memoryStream capacity is automatically expanded according to the reference

[@ SaiKishor-MSFT]
The maximum size of a MemoryStream object that can be handled by the System.IO.MemoryStream class is determined by the amount of available memory on the system. The maximum size of a MemoryStream object is 2 gigabytes (GB) by default.

My questions are:

  1. Do others get an all-zero error when reading a large file? (Does the capacity of MemoryStream automatically expand?)

  2. If all-zero errors are common, do you need to add a judgment: If the file size is too large, preload is not allowed? like this (in example.cpp, line 64):

// For most files < 1gb, pre-loading the entire file upfront and wrapping it into a 
// stream is a net win for parsing speed, about 40% faster. 
std::ifstream file_helper(filepath, std::ios::binary);
file_helper.seekg(0, std::ios::end);
std::streamsize byte_size = file_helper.tellg(); // get the byte_size of the file to be read
file_helper.close();
if (preload_into_memory && byte_size < 1.9e9)
{
    byte_buffer = read_file_binary(filepath);
    file_stream.reset(new memory_stream((char*)byte_buffer.data(), byte_buffer.size()));
}
else
{
    file_stream.reset(new std::ifstream(filepath, std::ios::binary));
}

Variable-length lists are not supported

Hi,

First of all thanks for the library. While testing it, I encountered the following issue.

The common use cases involve fixed-length lists for properties (e.g. faces made of 3 vertices), but the PLY format also supports variable lengths for the lists of each element, for example:

ply
format ascii 1.0
comment author: Greg Turk
comment object: another cube
element vertex 8
property float x
property float y
property float z
property uchar red                    { start of vertex color }
property uchar green
property uchar blue
element face 7
property list uchar int vertex_index  { number of vertices for each face }
element edge 5                        { five edges in object }
property int vertex1                  { index to first vertex of edge }
property int vertex2                  { index to second vertex }
property uchar red                    { start of edge color }
property uchar green
property uchar blue
end_header
0 0 0 255 0 0                         { start of vertex list }
0 0 1 255 0 0
0 1 1 255 0 0
0 1 0 255 0 0
1 0 0 0 0 255
1 0 1 0 0 255
1 1 1 0 0 255
1 1 0 0 0 255
3 0 1 2                               { start of face list, begin with a triangle }
3 0 2 3                               { another triangle }
4 7 6 5 4                             { now some quadrilaterals }
4 0 4 5 1
4 1 5 6 2
4 2 6 7 3
4 3 7 4 0
0 1 255 255 255                       { start of edge list, begin with white edge }
1 2 255 255 255
2 3 255 255 255
3 0 255 255 255
2 0 0 0 0                             { end with a single black line }

(example taken from Paul Bourke's personal page)

Here faces are described as both triangles and quadrilaterals, thus taking either 3 or 4 values. Apparently, this use case is not supported by tinyply yet, since these properties are serialized into a single vector, without keeping track of how many values are assigned to each element. We could also imagine cases where these lists can take any value (0 included).

Thus, for such cases, we might need to store the data in vector<vector<T>> (or vector<T> with an additional vector of offsets).

fail to build on Windows VS2013 x64

Error 1 error C2280: 'std::unique_ptr<uint8_t,tinyply::Buffer::delete_array> &std::unique_ptr<uint8_t,tinyply::Buffer::delete_array>::operator =(const std::unique_ptr<uint8_t,tinyply::Buffer::delete_array> &)' : attempting to reference a deleted function tinyply\source\tinyply.cpp 390 1 tinyply

Cannot read a ply file correctly

Hey, ddiakopoulos, the library is really cool. However, during my use of it, something wrong happend. I use tinyply to generate the file I needed, which contains other 4 properties for vertex. The writing part works well. When i tried to read it, it just crashed, or read some nosense content. I think the file itself has no errors, because meshlab can parse it properly. Here is the file: download_link .
It's written through ascii, when i use binary format to write it, tinyply works well. However i want to figure out what happened. I will be very thankful if you will take some time to check this out!

Use std::vector<uint8_t> instead of Buffer class

Currently I don't see any reasons why tinyply is using a Buffer class, which looks equal to a normal std::vector. So Buffer buffer; in struct PlyData could be replaced by std::vector<uint8_t> buffer; or std::unique_ptr<std::vector<uint8_t>> buffer;

Failed to open a .ply file

Hello,

I am trying to read a .ply file, however, i always get back the following message:

Caught tinyply exception: failed to open ...
tinyply exception: header had no elements defined. malformed file? ...

I have read in the description, that you need only to add the header file, so i just add to my project the tinyply header and based on the example.cpp (read_ply_file method) file i wrote a method to my application which reads the .ply file.

Here you can find also the header of the ply file i am trying to read (i would like to point out that i tried to read different ply files but i always got back the previous errors).

ply
format binary_little_endian 1.0
comment MergePly generated
element vertex 2694360
property float x
property float y
property float z
property float nx
property float ny
property float nz
property uchar red
property uchar green
property uchar blue
element face 0
property list uchar int vertex_indices
end_header

Do you have any idea, what i am doing wrong?
Thank you in advance,
Elena.

Provide custom memory for vertices

Hey there!

Given a class mesh, which (pre-)allocates it's own memory for storing up to n vertices. I cannot modify this class.
Can I instruct TinyPly to use the preallocate memory instead of it allocating its own memory and having to copy the vertices?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.