ply-rs-bw

Crates.ioply-rs-bw
lib.rsply-rs-bw
version3.0.0
created_at2024-12-07 22:03:44.888379+00
updated_at2026-01-25 13:57:04.872764+00
descriptionLibrary for reading/writing ascii and binary PLY files.
homepagehttps://github.com/bourumir-wyngs/ply-rs
repositoryhttps://github.com/bourumir-wyngs/ply-rs
max_upload_size
id1475911
size159,818
Bourumir (bourumir-wyngs)

documentation

https://docs.rs/ply-rs-bw/latest/ply_rs_bw

README

Ply-rs

unsafe forbidden crates.io Fuzz & Audit Miri GitHub Workflow Status crates.io crates.io docs.rs

This is a forked version of the ply-rs project that was created to address the use of linked-hash-map to resolve CVE-2020-25573.

The crate has been renamed to ply-rs-bw, and minor issues were resolved to ensure compatibility with Rust 2024 edition. Additionally, an example has been added to demonstrate how to read PLY files with diverse field types (e.g., f32 vs f64, u32 vs i32, etc.). Semantic versioning is now adopted for consistent version management.

Version 2.0.0 eliminates unnecessary cloning, as suggested by Nguyen Thuan Hung (see pull request 'Optimise by not cloning key'). While the scope of this change is limited, it modifies the signature of the public API trait PropertyAccess. The method:

fn set_property(&mut self, _property_name: String, _property: Property)

into

fn set_property(&mut self, _property_name: &String, _property: Property)

This breaking change necessitates incrementing the major version number. According to the author, this optimization reduces the time required to read 80,000 points from 450ms to 90ms, which is a significant improvement. The pull request has been reviewed and approved by our team.

Version 2.1.0 further improves the PropertyAccess trait by changing all &String parameters to &str:

fn set_property(&mut self, _property_name: &str, _property: Property)

This change is backwards compatible — existing code using &String will continue to work without modification, as Rust's Deref trait automatically coerces &String to &str. This is the idiomatic Rust approach (recommended by Clippy's ptr_arg lint) and provides more flexibility, allowing callers to pass string literals directly without creating a String.


Ply-rs is a small library built to read and write the PLY file format (also Polygon File Format, Stanford Triangle Format). The library supports all three subformats for both reading and writing: ASCII, binary big endian, and binary little endian. See examples/write_tetrahedron.rs for a demonstration of writing binary PLY files.

It focuses on two main points:

  • An easy and fast start.
  • High performance if you're willing to do some things yourself.

Getting started

This is the easiest way to read a ply file:

use ply_rs_bw as ply;

fn main() {
    //Set up a reader, in this case, a file.
    let path = "example_plys/greg_turk_example1_ok_ascii.ply";
    let mut f = std::fs::File::open(path).unwrap();

    // create a parser
    let p = ply::parser::Parser::<ply::ply::DefaultElement>::new();

    // use the parser: read the entire file
    let ply = p.read_ply(&mut f);

    // make sure it did work
    assert!(ply.is_ok());
    let ply = ply.unwrap();

    // proof that data has been read
    println!("Ply header: {:#?}", ply.header);
    println!("Ply data: {:?}", ply.payload);
}

Write ply file

The simplest case of writing a ply file:

use ply_rs_bw::ply::{ Ply, DefaultElement };
use ply_rs_bw::writer::{ Writer };

/// Demonstrates simplest use case for reading from a file.
fn main() {
    // set up a target could also be a file
    let mut buf = Vec::<u8>::new();

    // create a ply object
    let mut ply = Ply::<DefaultElement>::new();

    // set up a writer
    let w = Writer::new();
    let written = w.write_ply(&mut buf, &mut ply).unwrap();
    println!("{} bytes written", written);
    println!("buffer size: {}", buf.len());

    // proof that data has been read

    // We can use `from_utf8` since PLY files only contain ASCII characters
    let output = String::from_utf8(buf).unwrap();
    println!("Written data:\n{}", output);
}

For more complicated examples, please see the examples.

This implementation is mainly based on these specifications with additions from here.

Commit count: 146

cargo fmt