use crate::core::shared::ConfigType;
use crate::core::shared::PointIdx;
use crate::debug_write;
use crate::encode::connectivity::ConnectivityEncoder;
use crate::prelude::ByteWriter;
use crate::shared::connectivity::sequential::index_size_from_vertex_count;
use crate::shared::connectivity::sequential::Method;
use crate::utils::bit_coder::leb128_write;
pub(crate) struct Sequential {
cfg: Config,
num_points: usize,
}
impl Sequential {
pub fn new(config: Config, num_points: usize) -> Self {
Self {
cfg: config,
num_points,
}
}
fn encode_direct_indices<W>(&self, faces: &[[PointIdx; 3]], writer: &mut W) -> Result<(), Err>
where
W: ByteWriter,
{
let index_size = match index_size_from_vertex_count(self.num_points) {
Ok(index_size) => index_size as u8,
Err(err) => return Err(Err::SharedError(err)),
};
debug_write!("Start of indices", writer);
if index_size == 21 {
for face in faces {
leb128_write(usize::from(face[0]) as u64, writer);
leb128_write(usize::from(face[1]) as u64, writer);
leb128_write(usize::from(face[2]) as u64, writer);
}
} else {
match index_size {
8 => {
for face in faces {
writer.write_u8(usize::from(face[0]) as u8);
writer.write_u8(usize::from(face[1]) as u8);
writer.write_u8(usize::from(face[2]) as u8);
}
}
16 => {
for face in faces {
writer.write_u16(usize::from(face[0]) as u16);
writer.write_u16(usize::from(face[1]) as u16);
writer.write_u16(usize::from(face[2]) as u16);
}
}
32 => {
for face in faces {
writer.write_u32(usize::from(face[0]) as u32);
writer.write_u32(usize::from(face[1]) as u32);
writer.write_u32(usize::from(face[2]) as u32);
}
}
_ => unreachable!(),
}
}
Ok(())
}
}
impl ConnectivityEncoder for Sequential {
type Err = Err;
type Config = Config;
type Output = ();
fn encode_connectivity<W>(self, faces: &[[PointIdx; 3]], writer: &mut W) -> Result<(), Err>
where
W: ByteWriter,
{
writer.write_u64(faces.len() as u64);
let encoder_method_id = self.cfg.encoder_method.get_id();
writer.write_u8(encoder_method_id);
self.encode_direct_indices(faces, writer)?;
Ok(())
}
}
#[derive(Clone, Debug)]
pub struct Config {
pub encoder_method: Method,
}
impl ConfigType for Config {
fn default() -> Self {
Config {
encoder_method: Method::DirectIndices,
}
}
}
#[remain::sorted]
#[derive(thiserror::Error, Debug)]
pub enum Err {
#[error("Invalid vertex count")]
SharedError(crate::shared::connectivity::sequential::Err),
}