fn new(polytope: &Concrete) -> Self {
        let mut extra_vertices = Vec::new();
        let mut triangles = Vec::new();
        let empty_els = ElementList::new();

        // Either returns a reference to the element list of a given rank, or
        // returns a reference to an empty element list.
        let elements_or = |r| polytope.get_element_list(r).unwrap_or(&empty_els);

        let edges = elements_or(2);
        let faces = elements_or(3);

        let concrete_vertex_len = polytope.vertices.len() as u16;

        // We render each face separately.
        for face in faces {
            // We tesselate this path.
            let cycles = CycleList::from_edges(face.subs.iter().map(|&i| &edges[i].subs));
            if let Some(path) = path(&cycles, &polytope.vertices) {
                let mut geometry: VertexBuffers<_, u16> = VertexBuffers::new();

                // Configures all of the options of the tessellator.
                FillTessellator::new()
                    .tessellate_with_ids(
                        path.id_iter(),
                        &path,
                        None,
                        &FillOptions::with_fill_rule(Default::default(), FillRule::EvenOdd)
                            .with_tolerance(EPS),
                        &mut BuffersBuilder::new(&mut geometry, |vertex: FillVertex<'_>| {
                            vertex.sources().next().unwrap()
                        }),
                    )
                    .unwrap();

                // Maps EndpointIds to the indices in the original vertex list.
                let mut id_to_idx = Vec::new();
                for cycle in cycles {
                    for idx in cycle {
                        id_to_idx.push(idx);
                    }
                }

                // We map the output vertices to the original ones, and add any
                // extra vertices that may be needed.
                let mut vertex_hash = HashMap::new();

                for (new_id, vertex_source) in geometry.vertices.into_iter().enumerate() {
                    let new_id = new_id as u16;

                    match vertex_source {
                        // This is one of the concrete vertices of the polytope.
                        VertexSource::Endpoint { id } => {
                            vertex_hash.insert(new_id, id_to_idx[id.to_usize()] as u16);
                        }

                        // This is a new vertex that has been added to the tesselation.
                        VertexSource::Edge { from, to, t } => {
                            let from = &polytope.vertices[id_to_idx[from.to_usize()]];
                            let to = &polytope.vertices[id_to_idx[to.to_usize()]];

                            let t = t as Float;
                            let p = from * (1.0 - t) + to * t;

                            vertex_hash
                                .insert(new_id, concrete_vertex_len + extra_vertices.len() as u16);

                            extra_vertices.push(p);
                        }
                    }
                }

                // Add all of the new indices we've found onto the triangle vector.
                for new_idx in geometry
                    .indices
                    .iter()
                    .map(|idx| *vertex_hash.get(idx).unwrap())
                {
                    triangles.push(new_idx);
                }
            }
        }

        Self {
            extra_vertices,
            triangles,
        }
    }
/// Creates a new triangulation from a polytope.
Creates a new triangulation from a polytope.
Creates a new triangulation from a polytope .
fn new(polytope: &Concrete) -> Self {
        let mut extra_vertices = Vec::new();
        let mut triangles = Vec::new();
        let empty_els = ElementList::new();
        // Either returns a reference to the element list of a given rank, or
        // returns a reference to an empty element list.
        let elements_or = |r| polytope.get_element_list(r).unwrap_or(&empty_els);
        let edges = elements_or(2);
        let faces = elements_or(3);
        let concrete_vertex_len = polytope.vertices.len() as u16;
        // We render each face separately.
        for face in faces {
            // We tesselate this path.
            let cycles = CycleList::from_edges(face.subs.iter().map(|&i| &edges[i].subs));
            if let Some(path) = path(&cycles, &polytope.vertices) {
                let mut geometry: VertexBuffers<_, u16> = VertexBuffers::new();
                // Configures all of the options of the tessellator.
                FillTessellator::new()
                    .tessellate_with_ids(
                        path.id_iter(),
                        &path,
                        None,
                        &FillOptions::with_fill_rule(Default::default(), FillRule::EvenOdd)
                            .with_tolerance(EPS),
                        &mut BuffersBuilder::new(&mut geometry, |vertex: FillVertex<'_>| {
                            vertex.sources().next().unwrap()
                        }),
                    )
                    .unwrap();
                // Maps EndpointIds to the indices in the original vertex list.
                let mut id_to_idx = Vec::new();
                for cycle in cycles {
                    for idx in cycle {
                        id_to_idx.push(idx);
                    }
                }
                // We map the output vertices to the original ones, and add any
                // extra vertices that may be needed.
                let mut vertex_hash = HashMap::new();
                for (new_id, vertex_source) in geometry.vertices.into_iter().enumerate() {
                    let new_id = new_id as u16;
                    match vertex_source {
                        // This is one of the concrete vertices of the polytope.
                        VertexSource::Endpoint { id } => {
                            vertex_hash.insert(new_id, id_to_idx[id.to_usize()] as u16);
                        }
                        // This is a new vertex that has been added to the tesselation.
                        VertexSource::Edge { from, to, t } => {
                            let from = &polytope.vertices[id_to_idx[from.to_usize()]];
                            let to = &polytope.vertices[id_to_idx[to.to_usize()]];
                            let t = t as Float;
                            let p = from * (1.0 - t) + to * t;
                            vertex_hash
                                .insert(new_id, concrete_vertex_len + extra_vertices.len() as u16);
                            extra_vertices.push(p);
                        }
                    }
                }
                // Add all of the new indices we've found onto the triangle vector.
                for new_idx in geometry
                    .indices
                    .iter()
                    .map(|idx| *vertex_hash.get(idx).unwrap())
                {
                    triangles.push(new_idx);
                }
            }
        }
        Self {
            extra_vertices,
            triangles,
        }
    }
fn new ( polytope : & Concrete ) -> Self { let mut extra_vertices = Vec :: new ( ) ; let mut triangles = Vec :: new ( ) ; let empty_els = ElementList :: new ( ) ; // Either returns a reference to the element list of a given rank, or // returns a reference to an empty element list. let elements_or = | r | polytope . get_element_list ( r ) . unwrap_or ( & empty_els ) ; let edges = elements_or ( 2 ) ; let faces = elements_or ( 3 ) ; let concrete_vertex_len = polytope . vertices . len ( ) as u16 ; // We render each face separately. for face in faces { // We tesselate this path. let cycles = CycleList :: from_edges ( face . subs . iter ( ) . map ( | & i | & edges [ i ] . subs ) ) ; if let Some ( path ) = path ( & cycles , & polytope . vertices ) { let mut geometry : VertexBuffers < _ , u16 > = VertexBuffers :: new ( ) ; // Configures all of the options of the tessellator. FillTessellator :: new ( ) . tessellate_with_ids ( path . id_iter ( ) , & path , None , & FillOptions :: with_fill_rule ( Default :: default ( ) , FillRule :: EvenOdd ) . with_tolerance ( EPS ) , & mut BuffersBuilder :: new ( & mut geometry , | vertex : FillVertex < ' _ > | { vertex . sources ( ) . next ( ) . unwrap ( ) } ) , ) . unwrap ( ) ; // Maps EndpointIds to the indices in the original vertex list. let mut id_to_idx = Vec :: new ( ) ; for cycle in cycles { for idx in cycle { id_to_idx . push ( idx ) ; } } // We map the output vertices to the original ones, and add any // extra vertices that may be needed. let mut vertex_hash = HashMap :: new ( ) ; for ( new_id , vertex_source ) in geometry . vertices . into_iter ( ) . enumerate ( ) { let new_id = new_id as u16 ; match vertex_source { // This is one of the concrete vertices of the polytope. VertexSource :: Endpoint { id } => { vertex_hash . insert ( new_id , id_to_idx [ id . to_usize ( ) ] as u16 ) ; } // This is a new vertex that has been added to the tesselation. VertexSource :: Edge { from , to , t } => { let from = & polytope . vertices [ id_to_idx [ from . to_usize ( ) ] ] ; let to = & polytope . vertices [ id_to_idx [ to . to_usize ( ) ] ] ; let t = t as Float ; let p = from * ( 1.0 - t ) + to * t ; vertex_hash . insert ( new_id , concrete_vertex_len + extra_vertices . len ( ) as u16 ) ; extra_vertices . push ( p ) ; } } } // Add all of the new indices we've found onto the triangle vector. for new_idx in geometry . indices . iter ( ) . map ( | idx | * vertex_hash . get ( idx ) . unwrap ( ) ) { triangles . push ( new_idx ) ; } } } Self { extra_vertices , triangles , } }
Creates a new triangulation from a polytope.
Creates a new triangulation from a polytope .
polytope
&Concrete
polytope
&Concrete