triangulate/outputs/formats/
fan_to_list.rs

1use std::marker::PhantomData;
2
3use crate::{PolygonList, ListFormat, FanFormat, FanBuilder, ListBuilder, TriangleWinding};
4
5/// A wrapper which adapts a [ListFormat] to work as a [FanFormat], which is required for [PolygonList::triangulate]
6/// 
7/// Constructed with [ListFormat::into_fan_format].
8pub struct FanToListFormat<'p, P: PolygonList<'p> + ?Sized, LB: ListFormat<'p, P>>(LB, PhantomData<&'p P>);
9
10impl<'p, P: PolygonList<'p> + ?Sized, LB: ListFormat<'p, P>> FanToListFormat<'p, P, LB> {
11    pub(crate) fn new(list_builder: LB) -> Self {
12        Self(list_builder, PhantomData)
13    }
14}
15
16impl<'p, P: PolygonList<'p> + ?Sized, LB: ListFormat<'p, P>> FanFormat<'p, P> for FanToListFormat<'p, P, LB> {
17    type Builder = FanToListBuilder<'p, P, LB::Builder>;
18
19    fn initialize(self, polygon_list: &'p P, vi0: <P as PolygonList<'p>>::Index, vi1: <P as PolygonList<'p>>::Index, vi2: <P as PolygonList<'p>>::Index) -> Result<Self::Builder, <Self::Builder as FanBuilder<'p, P>>::Error> {
20        let mut list_builder = self.0.initialize(polygon_list)?;
21        list_builder.add_triangle(vi0.clone(), vi1, vi2.clone())?;
22        
23        let fan_builder = FanToListBuilder::new(list_builder, vi0, vi2);
24        Ok(fan_builder)
25    }
26}
27
28pub struct FanToListBuilder<'p, P: PolygonList<'p> + ?Sized, LB: ListBuilder<'p, P>> {
29    list_builder: LB,
30    vi0: P::Index,
31    vi1: P::Index,
32    _phantom: PhantomData<&'p P>,
33}
34
35impl<'p, P: PolygonList<'p> + ?Sized, LB: ListBuilder<'p, P>> FanToListBuilder<'p, P, LB> {
36    fn new(list_builder: LB, vi0: P::Index, vi1: P::Index) -> Self {
37        Self {
38            list_builder,
39            vi0,
40            vi1,
41            _phantom: PhantomData,
42        }
43    }
44}
45
46impl<'p, P: PolygonList<'p> + ?Sized, LB: ListBuilder<'p, P>> FanBuilder<'p, P> for FanToListBuilder<'p, P, LB> {
47    type Output = LB::Output;
48    type Error = LB::Error;
49
50    const WINDING: TriangleWinding = <LB as ListBuilder<'p, P>>::WINDING;
51
52    fn new_fan(&mut self, vi0: <P as PolygonList<'p>>::Index, vi1: <P as PolygonList<'p>>::Index, vi2: <P as PolygonList<'p>>::Index) -> Result<(), Self::Error> {
53        self.vi0 = vi0.clone();
54        self.vi1 = vi2.clone();
55        self.list_builder.add_triangle(vi0, vi1, vi2)
56    }
57
58    fn extend_fan(&mut self, vi: <P as PolygonList<'p>>::Index) -> Result<(), Self::Error> {
59        let vi1 = std::mem::replace(&mut self.vi1, vi.clone());
60        self.list_builder.add_triangle(self.vi0.clone(), vi1, vi)
61    }
62
63    fn build(self) -> Result<Self::Output, Self::Error> {
64        self.list_builder.build()
65    }
66
67    fn fail(self, error: &crate::TriangulationError<Self::Error>) {
68        self.list_builder.fail(error);
69    }
70}