draco_oxide/encode/connectivity/
mod.rs1pub mod config;
2pub(crate) mod edgebreaker;
3pub(crate) mod sequential;
4
5use std::fmt::Debug;
6
7use crate::encode::connectivity::edgebreaker::{DefaultTraversal, ValenceTraversal};
8use draco_oxide_core::bit_coder::ByteWriter;
9use draco_oxide_core::codec::connectivity::edgebreaker::EdgebreakerKind;
10use draco_oxide_core::mesh::ds::AttributeDS;
11use draco_oxide_core::types::{ConfigType, CornerIdx};
12
13pub fn encode_connectivity<'faces, W>(
17 adss: &mut [AttributeDS<'faces>],
18 writer: &mut W,
19 cfg: &super::Config,
20) -> Result<Vec<CornerIdx>, Err>
21where
22 W: ByteWriter,
23{
24 encode_connectivity_datatype_unpacked(adss, writer, cfg.connectivity.clone())
25}
26
27pub fn encode_connectivity_datatype_unpacked<'faces, W>(
30 adss: &mut [AttributeDS<'faces>],
31 writer: &mut W,
32 cfg: Config,
33) -> Result<Vec<CornerIdx>, Err>
34where
35 W: ByteWriter,
36{
37 let corners_of_edgebreaker = match cfg {
38 Config::Edgebreaker(cfg) => {
39 let result = match cfg.traversal {
40 EdgebreakerKind::Standard => {
41 let encoder =
42 edgebreaker::Edgebreaker::new(cfg, adss, |_| DefaultTraversal::new())?;
43 encoder.encode_connectivity(writer)?
44 }
45 EdgebreakerKind::Predictive => {
46 unimplemented!("Predictive edgebreaker encoding is not implemented yet");
47 }
48 EdgebreakerKind::Valence => {
49 let encoder = edgebreaker::Edgebreaker::new(cfg, adss, ValenceTraversal::new)?;
50 encoder.encode_connectivity(writer)?
51 }
52 };
53
54 result
55 }
56 Config::Sequential(cfg) => {
57 let num_points = adss[0].global_ds().num_points();
60 let faces = (0..adss[0].global_ds().num_faces())
61 .map(|i| {
62 let c = CornerIdx::from(3 * i);
63 [
64 adss[0].global_ds().point_idx(c),
65 adss[0].global_ds().point_idx(c.next()),
66 adss[0].global_ds().point_idx(c.next().next()),
67 ]
68 })
69 .collect::<Vec<_>>();
70 let encoder = sequential::Sequential::new(&faces, cfg, num_points);
71 encoder.encode_connectivity(writer)?
73 }
74 };
75 Ok(corners_of_edgebreaker)
76}
77
78pub trait ConnectivityEncoder {
82 type Err;
83 type Config;
84 fn encode_connectivity<W>(self, writer: &mut W) -> Result<Vec<CornerIdx>, Self::Err>
85 where
86 W: ByteWriter;
87}
88
89#[remain::sorted]
91#[derive(thiserror::Error, Debug)]
92pub enum Err {
93 #[error("Edgebreaker encoding error: {0}")]
95 EdgebreakerError(#[from] edgebreaker::Err),
96 #[error("Position attribute must be of type f32 or f64")]
98 PositionAttributeTypeError,
99 #[error("Sequential encoding error: {0}")]
101 SequentialError(#[from] sequential::Err),
102 #[error("Too many connectivity attributes")]
104 TooManyConnectivityAttributes,
105}
106
107#[remain::sorted]
110#[derive(Clone, Debug)]
111pub enum Config {
112 Edgebreaker(edgebreaker::Config),
114 Sequential(sequential::Config),
117}
118
119impl ConfigType for Config {
120 fn default() -> Self {
121 Self::Edgebreaker(edgebreaker::Config::default())
122 }
123}
124
125impl Config {
126 pub fn encoder_method(&self) -> draco_oxide_core::codec::header::EncoderMethod {
129 use draco_oxide_core::codec::header::EncoderMethod;
130 match self {
131 Config::Edgebreaker(_) => EncoderMethod::Edgebreaker,
132 Config::Sequential(_) => EncoderMethod::Sequential,
133 }
134 }
135}