Monthly Archives: September 2009

A flexible PLY loader for Evolution War r71

I’ve cited Evolution War for the first time on this blog in my previous post, today I want to celebrate my return to SVN committing after a very long time. 😀

PLY Export

Revision 71 adds the support for a real Stanford PLY parser and loader, while the one I coded for my graphic class library is very primitive, expecting a hard-coded order for data, this one shouldn’t have any kind of problem with every well-formed PLY file.

For example, while the hard-coded loader can only accept a file like this:

ply
format ascii 1.0
comment Created by Blender3D 249 - www.blender.org
element vertex 4
property float x
property float y
property float z
property float nx
property float ny
property float nz
element face 3
property list uchar uint vertex_indices
end_header
1.000000 2.000000 3.000000 -4.000000 -5.000000 6.000000 
-1.000000 -2.000000 -3.000000 4.000000 5.000000 6.000000 
1.000000 2.000000 3.000000 -4.000000 -5.000000 6.000000 
-1.000000 -2.000000 -3.000000 4.000000 5.000000 6.000000  
3 0 1 2 
3 1 3 2 
3 4 2 1 

the parser loader can load even something like this:

ply
format ascii 1.0
comment Created and shuffled by hand
element face 3
property list uchar uint vertex_indices
element skipme 3
property float skipfirst
property float skipsecond
element vertex 4
property float z
property float nz
property float y
property float ny
property float nx
property float x
end_header
3 0 1 2 
3 1 3 2 
3 4 2 1 
0.0 0.0 
0.0 0.0
0.0 0.0 
3.000000 -6.000000 2.000000 -5.000000 -4.000000 1.000000 
-3.000000 6.000000 -2.000000 5.000000 4.000000 -1.000000 
3.000000 -6.000000 2.000000 -5.000000 -4.000000 1.000000 
-3.000000 6.000000 -2.000000 5.000000 4.000000 -1.000000 

But one of its most important feature resides in the ability to correctly load binary PLY files! 🙂

Related to it there’s a bug I would like to share with you together with the fix:

istream& istream::read (char* s, streamsize n);
[...]
ifstream ifs;
unsigned int *uIndices;
[...]
ifs.read((char *) uIndices+(j*3), sizeof(unsigned int) * 3);

The read() method only accepts char pointers, so uIndices is casted, but the precedence goes to casting and not to native unsigned int pointer arithmetics, leading to catastrophic effects! 😮

The fix was as simple as the bug was subtle:

-ifs.read((char *) uIndices+(j*3), sizeof(unsigned int) * 3);
+ifs.read((char *) (uIndices+(j*3)), sizeof(unsigned int) * 3)