ply_rs/ply/
ply_data_structure.rs

1use std::fmt::{ Display, Formatter };
2use std::fmt;
3use super::PropertyType;
4use super::KeyMap;
5use super::PropertyAccess;
6
7/// Models all necessary information to interact with a PLY file.
8///
9/// The generic parameter `E` is the element type used to store the payload data.
10#[derive(Debug, Clone, PartialEq)]
11pub struct Ply<E: PropertyAccess> {
12    /// All header information found in a PLY file.
13    pub header: Header,
14    /// The payloud found after the `end_header` line in a PLY file.
15    ///
16    /// One line in an ascii PLY file corresponds to a single element.
17    /// The payload groups elments with the same type together in a vector.
18    ///
19    /// # Examples
20    ///
21    /// Assume you have a `Ply` object called `ply` and want to access the third `point` element:
22    ///
23    /// ```rust,no_run
24    /// # use ply_rs::ply::{Ply, DefaultElement};
25    /// # let ply = Ply::<DefaultElement>::new();
26    /// // get ply from somewhere ...
27    /// let ref a_point = ply.payload["point"][2];
28    /// let ref a_point_x = ply.payload["point"][2]["x"];
29    /// ```
30    pub payload: Payload<E>,
31}
32impl<E: PropertyAccess> Ply<E> {
33    /// Creates a new `Ply<E>`.
34    pub fn new() -> Self {
35        Ply::<E> {
36            header: Header::new(),
37            payload: Payload::new(),
38        }
39    }
40}
41
42// Header Types
43
44/// Models the header of a PLY file.
45#[derive(Debug, PartialEq, Eq, Clone)]
46pub struct Header {
47    /// In which format is the payload encoded?
48    ///
49    /// Ascii produces human readable files,
50    /// while binary encoding lets you choose between big and little endian.
51    pub encoding: Encoding,
52    /// Which file format standard is used?
53    ///
54    /// The only existing standard is 1.0.
55    pub version: Version,
56    pub obj_infos: Vec<ObjInfo>,
57    /// Ordered map of elements as they appear in the payload.
58    pub elements: KeyMap<ElementDef>,
59    /// File comments.
60    pub comments: Vec<Comment>,
61}
62
63impl Header {
64    /// Constructs an empty `Header` using Ascii encoding and version 1.0.
65    /// No object informations, elements or comments are set.
66    pub fn new() -> Self {
67        Header {
68            encoding: Encoding::Ascii,
69            version: Version{major: 1, minor: 0},
70            obj_infos: Vec::new(),
71            elements: KeyMap::new(),
72            comments: Vec::new(),
73        }
74    }
75}
76
77/// Alias to give object informations an explicit type.
78pub type ObjInfo = String;
79
80/// Alias to give comments an explicit type.
81pub type Comment = String;
82
83/// Models a version number.
84///
85/// At time of writing, the only existin version for a PLY file is "1.0".
86#[derive(Debug, PartialEq, Eq, Clone, Copy)]
87pub struct Version {
88    pub major: u16,
89    pub minor: u8,
90}
91
92impl Display for Version {
93    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
94        f.write_str(&format!("{}.{}", self.major, self.minor))
95    }
96}
97
98/// Models possible encoding standards for the payload.
99#[derive(Debug, PartialEq, Eq, Clone, Copy)]
100pub enum Encoding {
101    /// Write numbers in their ascii representation (e.g. -13, 6.28, etc.).
102    /// Properties are separated by spaces and elements are separated by line breaks.
103    Ascii,
104    /// Encode payload using big endian.
105    BinaryBigEndian,
106    /// Encode payload using little endian.
107    BinaryLittleEndian,
108}
109
110impl Display for Encoding {
111    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
112        f.write_str(
113            match *self {
114                Encoding::Ascii => "ascii",
115                Encoding::BinaryBigEndian => "binary_big_endian",
116                Encoding::BinaryLittleEndian => "binary_little_endian",
117            }
118        )
119    }
120}
121
122/// Models the definition of an element.
123///
124/// Elements describe single entities consisting of different properties.
125/// A single point is an element.
126/// We might model it as consisting of three coordinates: x, y, and z.
127/// Usually, one finds a list of elements in a ply file.
128#[derive(Debug, PartialEq, Eq, Clone)]
129pub struct ElementDef {
130    /// Name of the element.
131    ///
132    /// Each element within a PLY file needs a unique name.
133    /// There are common conventions like using "vertex" and "face" to assure interoperability between applications.
134    /// For further information, please consult your target applications or the [original specification](http://paulbourke.net/dataformats/ply/).
135    pub name: String,
136    /// Describes, how many elements appear in a PLY file.
137    ///
138    /// The `count` is used when reading since we need to know how many elements we should interprete as having this type.
139    /// The `count` is also needed for writing, since it will be written to the header.
140    pub count: usize,
141    /// An element is modeled by multiple properties, those are named values or lists.
142    ///
143    /// # Examples
144    ///
145    /// - Point: We can define a point by its three coordinates. Hence we have three properties: x, y, and z. Reasonable types would be float or double.
146    /// - Polygon: A polygon can be defined as a list of points. Since the points are stored in a list, we can define a list of indices. Good types would be some of the unsigned integer lists.
147    pub properties: KeyMap<PropertyDef>,
148}
149impl ElementDef {
150    /// Creates a new element definition.
151    ///
152    /// The name should be unique for each element in a PLY file.
153    ///
154    /// You should never need to set `count` manuall, since it is set by the consistency check (see `make_consistent()` of `Ply`).
155    ///
156    /// No properties are set.
157    pub fn new(name: String) -> Self {
158        ElementDef {
159            name: name,
160            count: 0,
161            properties: KeyMap::new(),
162        }
163    }
164}
165
166/// Defines a property of an element.
167#[derive(Debug, PartialEq, Eq, Clone)]
168pub struct PropertyDef {
169    /// Unique name of property.
170    ///
171    /// The name should be unique for each property of the same element.
172    pub name: String,
173    /// Data type of the property:
174    /// You can have simple scalars (ints, floats, etc.) or lists of scalars.
175    /// In the case of lists you need to decide in which type you want to store the list length and what type to use for the list elemetns.
176    pub data_type: PropertyType,
177}
178
179impl PropertyDef {
180    /// Creates a new property definition.
181    pub fn new(name: String, data_type: PropertyType) -> Self {
182        PropertyDef {
183            name: name,
184            data_type: data_type,
185        }
186    }
187}
188
189/// The part after `end_header`, contains the main data.
190pub type Payload<E> = KeyMap<Vec<E>>;