draco_oxide/encode/
mod.rs

1pub(crate) mod attribute;
2pub(crate) mod connectivity;
3pub(crate) mod entropy;
4pub(crate) mod header;
5pub(crate) mod metadata;
6
7use crate::core::bit_coder::ByteWriter;
8use crate::core::mesh::Mesh;
9use crate::core::shared::ConfigType;
10use crate::{debug_write, shared};
11use thiserror::Error;
12
13#[cfg(feature = "evaluation")]
14use crate::eval;
15
16pub trait EncoderConfig {
17    type Encoder;
18    fn get_encoder(&self) -> Self::Encoder;
19}
20
21#[derive(Debug, Clone)]
22pub struct Config {
23    #[allow(unused)]
24    // This field is unused in the current implementation, as we only support edgebreaker.
25    connectivity_encoder_cfg: connectivity::Config,
26    #[allow(unused)]
27    // This field is unused in the current implementation, as we only suport the default attribute encoder configuration.
28    attribute_encoder_cfg: attribute::Config,
29    geometry_type: header::EncodedGeometryType,
30    encoder_method: shared::header::EncoderMethod,
31    metdata: bool,
32}
33
34impl ConfigType for Config {
35    fn default() -> Self {
36        Self {
37            connectivity_encoder_cfg: connectivity::Config::default(),
38            attribute_encoder_cfg: attribute::Config::default(),
39            geometry_type: header::EncodedGeometryType::TrianglarMesh,
40            encoder_method: shared::header::EncoderMethod::Edgebreaker,
41            metdata: false,
42        }
43    }
44}
45
46#[remain::sorted]
47#[derive(Error, Debug)]
48pub enum Err {
49    #[error("Attribute encoding error: {0}")]
50    AttributeError(#[from] attribute::Err),
51    #[error("Connectivity encoding error: {0}")]
52    ConnectivityError(#[from] connectivity::Err),
53    #[error("Header encoding error: {0}")]
54    HeaderError(#[from] header::Err),
55    #[error("Metadata encoding error: {0}")]
56    MetadataError(#[from] metadata::Err),
57}
58
59/// Encodes the input mesh into a provided byte stream using the provided configuration.
60pub fn encode<W>(mesh: Mesh, writer: &mut W, cfg: Config) -> Result<(), Err>
61where
62    W: ByteWriter,
63{
64    #[cfg(feature = "evaluation")]
65    eval::scope_begin("compression info", writer);
66
67    // Encode header
68    header::encode_header(writer, &cfg)?;
69
70    debug_write!("Header done, now starting metadata.", writer);
71
72    // Encode metadata
73    if cfg.metdata {
74        #[cfg(feature = "evaluation")]
75        eval::scope_begin("metadata", writer);
76        metadata::encode_metadata(&mesh, writer)?;
77        #[cfg(feature = "evaluation")]
78        eval::scope_end(writer);
79    }
80
81    debug_write!("Metadata done, now starting connectivity.", writer);
82
83    // Destruct the mesh so that attributes and faces have the different lifetime.
84    let Mesh {
85        mut attributes,
86        faces,
87        ..
88    } = mesh;
89
90    // Encode connectivity
91    let conn_out = connectivity::encode_connectivity(&faces, &mut attributes, writer, &cfg)?;
92    debug_write!("Connectivity done, now starting attributes.", writer);
93
94    // Encode attributes
95    attribute::encode_attributes(attributes, writer, conn_out, &cfg)?;
96
97    debug_write!("All done", writer);
98
99    #[cfg(feature = "evaluation")]
100    eval::scope_end(writer);
101    Ok(())
102}