draco_oxide/encode/connectivity/
sequential.rs1use crate::encode::connectivity::ConnectivityEncoder;
2use crate::encode::entropy::symbol_coding::encode_symbols;
3use draco_oxide_core::bit_coder::ByteWriter;
4use draco_oxide_core::codec::connectivity::sequential::index_size_from_vertex_count;
5use draco_oxide_core::codec::connectivity::sequential::Method;
6use draco_oxide_core::codec::entropy::SymbolEncodingMethod;
7use draco_oxide_core::debug_write;
8use draco_oxide_core::types::ConfigType;
9use draco_oxide_core::types::{CornerIdx, PointIdx};
10use draco_oxide_core::utils::bit_coder::leb128_write;
11
12pub(crate) struct Sequential {
13 cfg: Config,
14 num_points: usize,
15 faces: Vec<[PointIdx; 3]>,
16}
17
18impl Sequential {
19 pub fn new(faces: &[[PointIdx; 3]], config: Config, num_points: usize) -> Self {
20 Self {
21 cfg: config,
22 num_points,
23 faces: faces.to_vec(),
24 }
25 }
26
27 fn encode_direct_indices<W>(&self, writer: &mut W) -> Result<(), Err>
30 where
31 W: ByteWriter,
32 {
33 let index_size = match index_size_from_vertex_count(self.num_points) {
34 Ok(index_size) => index_size as u8,
35 Err(err) => return Err(Err::SharedError(err)),
36 };
37 debug_write!("Start of indices", writer);
38
39 if index_size == 21 {
40 for face in &self.faces {
41 leb128_write(usize::from(face[0]) as u64, writer);
42 leb128_write(usize::from(face[1]) as u64, writer);
43 leb128_write(usize::from(face[2]) as u64, writer);
44 }
45 } else {
46 match index_size {
47 8 => {
48 for face in &self.faces {
49 writer.write_u8(usize::from(face[0]) as u8);
50 writer.write_u8(usize::from(face[1]) as u8);
51 writer.write_u8(usize::from(face[2]) as u8);
52 }
53 }
54 16 => {
55 for face in &self.faces {
56 writer.write_u16(usize::from(face[0]) as u16);
57 writer.write_u16(usize::from(face[1]) as u16);
58 writer.write_u16(usize::from(face[2]) as u16);
59 }
60 }
61 32 => {
62 for face in &self.faces {
63 writer.write_u32(usize::from(face[0]) as u32);
64 writer.write_u32(usize::from(face[1]) as u32);
65 writer.write_u32(usize::from(face[2]) as u32);
66 }
67 }
68 _ => unreachable!(),
69 }
70 }
71 Ok(())
72 }
73
74 fn encode_compressed_indices<W>(&self, writer: &mut W) -> Result<(), Err>
78 where
79 W: ByteWriter,
80 {
81 debug_write!("Start of indices", writer);
82
83 let mut symbols = Vec::with_capacity(self.faces.len() * 3);
84 let mut last: i64 = 0;
85 for face in &self.faces {
86 for &p in face {
87 let index = usize::from(p) as i64;
88 let diff = index - last;
89 symbols.push((diff.unsigned_abs() << 1) | (diff < 0) as u64);
90 last = index;
91 }
92 }
93 encode_symbols(symbols, 1, SymbolEncodingMethod::DirectCoded, writer)
94 .map_err(Err::SymbolEncodingError)
95 }
96}
97
98impl ConnectivityEncoder for Sequential {
99 type Err = Err;
100 type Config = Config;
101
102 fn encode_connectivity<W>(self, writer: &mut W) -> Result<Vec<CornerIdx>, Err>
103 where
104 W: ByteWriter,
105 {
106 leb128_write(self.faces.len() as u64, writer);
107 leb128_write(self.num_points as u64, writer);
108 writer.write_u8(self.cfg.encoder_method.get_id());
109 match self.cfg.encoder_method {
110 Method::DirectIndices => self.encode_direct_indices(writer)?,
111 Method::Compressed => self.encode_compressed_indices(writer)?,
112 }
113
114 Ok(Vec::new())
116 }
117}
118
119#[derive(Clone, Debug)]
122pub struct Config {
123 pub encoder_method: Method,
125}
126
127impl ConfigType for Config {
128 fn default() -> Self {
129 Config {
130 encoder_method: Method::DirectIndices,
131 }
132 }
133}
134
135#[remain::sorted]
137#[derive(thiserror::Error, Debug)]
138pub enum Err {
139 #[error("Invalid vertex count")]
141 SharedError(draco_oxide_core::codec::connectivity::sequential::Err),
142 #[error("Entropy Symbol Encoding Error: {0}")]
144 SymbolEncodingError(crate::encode::entropy::symbol_coding::Err),
145}