Skip to main content

draco_oxide/encode/connectivity/
sequential.rs

1use crate::encode::connectivity::ConnectivityEncoder;
2use draco_oxide_core::bit_coder::ByteWriter;
3use draco_oxide_core::codec::connectivity::sequential::index_size_from_vertex_count;
4use draco_oxide_core::codec::connectivity::sequential::Method;
5use draco_oxide_core::debug_write;
6use draco_oxide_core::types::ConfigType;
7use draco_oxide_core::types::{CornerIdx, PointIdx};
8use draco_oxide_core::utils::bit_coder::leb128_write;
9
10pub(crate) struct Sequential {
11    cfg: Config,
12    num_points: usize,
13    faces: Vec<[PointIdx; 3]>,
14}
15
16impl Sequential {
17    pub fn new(faces: &[[PointIdx; 3]], config: Config, num_points: usize) -> Self {
18        Self {
19            cfg: config,
20            num_points,
21            faces: faces.to_vec(),
22        }
23    }
24
25    fn encode_direct_indices<W>(&self, writer: &mut W) -> Result<(), Err>
26    where
27        W: ByteWriter,
28    {
29        let index_size = match index_size_from_vertex_count(self.num_points) {
30            Ok(index_size) => index_size as u8,
31            Err(err) => return Err(Err::SharedError(err)),
32        };
33        debug_write!("Start of indices", writer);
34
35        if index_size == 21 {
36            // varint encoding
37            for face in &self.faces {
38                leb128_write(usize::from(face[0]) as u64, writer);
39                leb128_write(usize::from(face[1]) as u64, writer);
40                leb128_write(usize::from(face[2]) as u64, writer);
41            }
42        } else {
43            // non-varint encoding
44            match index_size {
45                8 => {
46                    for face in &self.faces {
47                        writer.write_u8(usize::from(face[0]) as u8);
48                        writer.write_u8(usize::from(face[1]) as u8);
49                        writer.write_u8(usize::from(face[2]) as u8);
50                    }
51                }
52                16 => {
53                    for face in &self.faces {
54                        writer.write_u16(usize::from(face[0]) as u16);
55                        writer.write_u16(usize::from(face[1]) as u16);
56                        writer.write_u16(usize::from(face[2]) as u16);
57                    }
58                }
59                32 => {
60                    for face in &self.faces {
61                        writer.write_u32(usize::from(face[0]) as u32);
62                        writer.write_u32(usize::from(face[1]) as u32);
63                        writer.write_u32(usize::from(face[2]) as u32);
64                    }
65                }
66                _ => unreachable!(),
67            }
68        }
69        Ok(())
70    }
71}
72
73impl ConnectivityEncoder for Sequential {
74    type Err = Err;
75    type Config = Config;
76
77    fn encode_connectivity<W>(self, writer: &mut W) -> Result<Vec<CornerIdx>, Err>
78    where
79        W: ByteWriter,
80    {
81        writer.write_u64(self.faces.len() as u64);
82        let encoder_method_id = self.cfg.encoder_method.get_id();
83        writer.write_u8(encoder_method_id);
84        self.encode_direct_indices(writer)?;
85
86        // Sequential connectivity has no edgebreaker traversal to surface.
87        Ok(Vec::new())
88    }
89}
90
91#[derive(Clone, Debug)]
92pub struct Config {
93    pub encoder_method: Method,
94}
95
96impl ConfigType for Config {
97    fn default() -> Self {
98        Config {
99            encoder_method: Method::DirectIndices,
100        }
101    }
102}
103
104#[remain::sorted]
105#[derive(thiserror::Error, Debug)]
106pub enum Err {
107    #[error("Invalid vertex count")]
108    SharedError(draco_oxide_core::codec::connectivity::sequential::Err),
109}