ddiakopoulos / tinyply Goto Github PK
View Code? Open in Web Editor NEW:earth_africa: C++11 ply 3d mesh format importer & exporter
:earth_africa: C++11 ply 3d mesh format importer & exporter
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
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 :)
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.
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));
^~~~~~
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
.
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!
Hello,
The example is given for a cube.
How to make the same for a polygon with more than 4 points by plane ?
Thank you,
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?
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;
}
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
}
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.
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.
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!
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.
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.
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; }
};
Useful for providing a progress bar when loading huge point ply files. Also to allow the user to abort the import process
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.
Every 10000 vertices or so, a user provided callback function could be called.
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
if you don't close cube_file && vertex>10000
the ply out is error can't open in MeshLab
How to I get the first number for each face with tinyply?
3 0 2 3 triangle
4 7 6 5 4 quad
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.?
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)?
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);
}
The "file.read(memory_stream);" function causes a segfault, when loading the included elephant.ply file, from the assets folder.
The other .ply files all load ok.
(Ubuntu 18.04)
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.
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?
I have a big ply file and I just want to add some points to it with out read the whole file.
Can I achieve this?
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?
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 !
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.
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:
Do others get an all-zero error when reading a large file? (Does the capacity of MemoryStream automatically expand?)
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));
}
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).
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
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!
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;
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.
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?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.