Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/potocpav/rust-ply
PLY file loader written in Rust.
https://github.com/potocpav/rust-ply
Last synced: about 2 months ago
JSON representation
PLY file loader written in Rust.
- Host: GitHub
- URL: https://github.com/potocpav/rust-ply
- Owner: potocpav
- License: mit
- Created: 2015-02-03T23:29:11.000Z (almost 10 years ago)
- Default Branch: master
- Last Pushed: 2015-02-17T08:48:49.000Z (almost 10 years ago)
- Last Synced: 2023-08-27T08:59:41.856Z (over 1 year ago)
- Language: Rust
- Size: 223 KB
- Stars: 5
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# PLY file loading library in Rust
This library (written in the Rust language) can load a PLY file and store its contents in structure(s). The serialization code is generated by a compiler plugin for simple use-cases. This ensures maximum safety (the file contents must match the structures) while avoiding the boilerplate.
## About the PLY format
[**PLY**](http://en.wikipedia.org/wiki/PLY_%28file_format%29) is a computer file format known as the **Polygon File Format** or the **Stanford Triangle Format.** PLY is a simple yet powerful format designed to store three-dimensional data. It's main advantage over comparable formats (wavefront obj comes to mind) is its modularity: it can be used to store arbitrary data associated to vertices, edges or faces. This is very useful for shader attributes, skeletal animation, description of surface quality and others. PLY can be exported by blender. The full description of the format is [here](http://paulbourke.net/dataformats/ply/).
## Usage
Add this to the crate root:
```rust
#![feature(plugin)]#![plugin(ply_plugins)]
extern crate ply_plugins;
extern crate ply;
```As an example, we will parse a simple file describing a cube:
```c
ply // These comments are not a part of a valid PLY file!
format ascii 1.0 // Header section
element vertex 8 // Each PLY file consists of elements
property float x // Each element consists of properties
property float y // Each property has a type and a name
property float z
element face 6
property list uchar int vertex_index
end_header // Data section
0 0 0 // Each line corresponds to an element
0 0 1 // The first 8 lines are the vertices
0 1 1
0 1 0
1 0 0
1 0 1
1 1 1
1 1 0
4 0 1 2 3 // These 6 lines are the faces
4 7 6 5 4
4 0 4 5 1
4 1 5 6 2
4 2 6 7 3
4 3 7 4 0
```The genericity of the PLY format is now obvious: there can be any number of properties and elements of any types and names.
We create the structures that can be used to store the elements of the cube:
```rust
#[derive(Debug,Copy)]
#[ply_element]
pub struct Vertex {
x: f32, y: f32, z: f32,
}#[derive(Debug)]
#[ply_element]
pub struct Face {
vertex_index: Vec,
};
```The `#[ply_element]` lines create implementations of the `ply::Element` trait, so we can easily deserialize the data. These implementations check that the mapping from the PLY file to the structures is correct (types and names match), and provides a function `ply::Element::parse` that does the conversion from an AST to a structure.
Now, we can specify a structure that holds the whole model:
```rust
#[derive(Debug)]
#[ply_model]
struct Model {
vertex: Vec,
face: Vec,
}
```The `#[ply_model]` line creates an implementation of the `ply::Model` trait, that contains the first function that we are actually going to use in this simple example:
`ply::Model::new(&ply::PLY) -> Result`
Now that the structures are specified, we are free to do some parsing:
```rust
fn main() {
match ply::parse(PLY) { // Create an AST
Ok(ref ply) => {
// Fill in the structure from the AST
let model: Result = ply::Model::new(ply);
// Print the result
println!("\nResult: {:?}", model);
},
Err(e) => println!("Error while parsing:\n{}", e),
}
}
```The output is (line breaks and tabs added for clarity):
```rust
Result: Ok(
Model {
vertex:
[ Vertex { x: 0, y: 0, z: 0 }
, Vertex { x: 0, y: 0, z: 1 }
, Vertex { x: 0, y: 1, z: 1 }
, Vertex { x: 0, y: 1, z: 0 }
, Vertex { x: 1, y: 0, z: 0 }
, Vertex { x: 1, y: 0, z: 1 }
, Vertex { x: 1, y: 1, z: 1 }
, Vertex { x: 1, y: 1, z: 0 }
],
face:
[ Face { vertex_index: [0, 1, 2, 3] }
, Face { vertex_index: [7, 6, 5, 4] }
, Face { vertex_index: [0, 4, 5, 1] }
, Face { vertex_index: [1, 5, 6, 2] }
, Face { vertex_index: [2, 6, 7, 3] }
, Face { vertex_index: [3, 7, 4, 0] }
]
}
)
```The whole code of this example is in the example [simple.rs](examples/simple.rs). For more involved examples, see the [examples](examples).