use maplike::Get;
use crate::{
Dcel, Face, FaceId, HalfEdge, HalfEdgeId, Vertex, VertexId,
walkers::{
CirculateEdgesWithExcludesIter, CirculateEdgesWithExcludesReverseIter,
CirculateEdgesWithExcludesReverseWalker, CirculateEdgesWithExcludesWalker,
CirculateHalfEdgesWithExcludesIter, CirculateHalfEdgesWithExcludesReverseIter,
CirculateHalfEdgesWithExcludesReverseWalker, CirculateHalfEdgesWithExcludesWalker,
CirculateHalfSpokesReverseIter, CirculateVertexesWithExcludesIter,
CirculateVertexesWithExcludesReverseIter, CirculateVertexesWithExcludesReverseWalker,
CirculateVertexesWithExcludesWalker, CirculationHalfSpokesIter,
CirculationHalfSpokesReverseWalker, CirculationHalfSpokesWalker,
CirculationInterspokesIter, CirculationInterspokesReverseIter,
CirculationInterspokesReverseWalker, CirculationInterspokesWalker, CirculationSpokesIter,
CirculationSpokesReverseIter, CirculationSpokesReverseWalker, CirculationSpokesWalker,
HalfSpokesIter, HalfSpokesReverseIter, HalfSpokesReverseWalker, HalfSpokesWalker,
InterspokesIter, InterspokesReverseIter, InterspokesReverseWalker, InterspokesWalker,
SpokesIter, SpokesReverseIter, SpokesReverseWalker, SpokesWalker,
},
};
impl<VW, HEW, FW, VC: Get<usize, Value = Vertex<VW>>, HEC, FC> Dcel<VW, HEW, FW, VC, HEC, FC> {
#[inline]
pub fn vertex_half_spokes(
&self,
vertex: VertexId,
) -> HalfSpokesIter<'_, VW, HEW, FW, VC, HEC, FC> {
self.half_spokes(self.vertex_representative(vertex))
}
#[inline]
pub fn vertex_half_spokes_reverse(
&self,
vertex: VertexId,
) -> HalfSpokesReverseIter<'_, VW, HEW, FW, VC, HEC, FC> {
self.half_spokes_reverse(self.vertex_representative(vertex))
}
}
impl<VW, HEW, FW, VC: Get<usize, Value = Vertex<VW>>, HEC: Get<usize, Value = HalfEdge<HEW>>, FC>
Dcel<VW, HEW, FW, VC, HEC, FC>
{
#[inline]
pub fn vertex_rim_vertices(
&self,
vertex: VertexId,
) -> CirculateVertexesWithExcludesIter<'_, VW, HEW, FW, VC, HEC, FC> {
CirculateVertexesWithExcludesWalker {
circulator: self.vertex_rim_half_edges(vertex).walker(),
}
.iter(self)
}
#[inline]
pub fn vertex_rim_vertices_reverse(
&self,
vertex: VertexId,
) -> CirculateVertexesWithExcludesReverseIter<'_, VW, HEW, FW, VC, HEC, FC> {
CirculateVertexesWithExcludesReverseWalker {
circulator: self.vertex_rim_half_edges_reverse(vertex).walker(),
}
.iter(self)
}
}
impl<VW, HEW, FW, VC: Get<usize, Value = Vertex<VW>>, HEC: Get<usize, Value = HalfEdge<HEW>>, FC>
Dcel<VW, HEW, FW, VC, HEC, FC>
{
#[inline]
pub fn vertex_rim_half_edges(
&self,
vertex: VertexId,
) -> CirculateHalfEdgesWithExcludesIter<'_, VW, HEW, FW, VC, HEC, FC> {
let initial_half_edge = self.next(self.vertex_representative(vertex));
let excluded_half_edges = self
.vertex_spokes(vertex)
.flat_map(|edge| [edge.lesser(), edge.greater()])
.collect::<Vec<HalfEdgeId>>();
if self.check_if_boundary_vertex(vertex) {
return CirculateHalfEdgesWithExcludesWalker {
initial_half_edge,
curr_half_edge: None,
excluded_half_edges,
}
.iter(self);
}
self.circulate_half_edges_with_excludes(initial_half_edge, excluded_half_edges)
}
#[inline]
pub fn vertex_rim_half_edges_reverse(
&self,
vertex: VertexId,
) -> CirculateHalfEdgesWithExcludesReverseIter<'_, VW, HEW, FW, VC, HEC, FC> {
let initial_half_edge = self.prev(self.twin(self.vertex_representative(vertex)));
let excluded_half_edges = self
.vertex_spokes(vertex)
.flat_map(|edge| [edge.lesser(), edge.greater()])
.collect::<Vec<HalfEdgeId>>();
if self.check_if_boundary_vertex(vertex) {
return CirculateHalfEdgesWithExcludesReverseWalker {
initial_half_edge,
curr_half_edge: None,
excluded_half_edges,
}
.iter(self);
}
self.circulate_half_edges_with_excludes_reverse(initial_half_edge, excluded_half_edges)
}
}
impl<VW, HEW, FW, VC, HEC, FC> Dcel<VW, HEW, FW, VC, HEC, FC> {
#[inline]
pub fn half_spokes(
&self,
initial_half_edge: HalfEdgeId,
) -> HalfSpokesIter<'_, VW, HEW, FW, VC, HEC, FC> {
HalfSpokesWalker {
initial_half_edge,
curr_half_edge: Some(initial_half_edge),
}
.iter(self)
}
#[inline]
pub fn half_spokes_reverse(
&self,
initial_half_edge: HalfEdgeId,
) -> HalfSpokesReverseIter<'_, VW, HEW, FW, VC, HEC, FC> {
HalfSpokesReverseWalker {
initial_half_edge,
curr_half_edge: Some(initial_half_edge),
}
.iter(self)
}
}
impl<VW, HEW, FW, VC: Get<usize, Value = Vertex<VW>>, HEC: Get<usize, Value = HalfEdge<HEW>>, FC>
Dcel<VW, HEW, FW, VC, HEC, FC>
{
#[inline]
pub fn vertex_spokes(&self, vertex: VertexId) -> SpokesIter<'_, VW, HEW, FW, VC, HEC, FC> {
self.spokes(self.vertex_representative(vertex))
}
#[inline]
pub fn vertex_spokes_reverse(
&self,
vertex: VertexId,
) -> SpokesReverseIter<'_, VW, HEW, FW, VC, HEC, FC> {
self.spokes_reverse(self.vertex_representative(vertex))
}
}
impl<VW, HEW, FW, VC: Get<usize, Value = Vertex<VW>>, HEC: Get<usize, Value = HalfEdge<HEW>>, FC>
Dcel<VW, HEW, FW, VC, HEC, FC>
{
#[inline]
pub fn vertex_rim_edges(
&self,
vertex: VertexId,
) -> CirculateEdgesWithExcludesIter<'_, VW, HEW, FW, VC, HEC, FC> {
CirculateEdgesWithExcludesWalker {
circulator: self.vertex_rim_half_edges(vertex).walker(),
}
.iter(self)
}
#[inline]
pub fn vertex_rim_edges_reverse(
&self,
vertex: VertexId,
) -> CirculateEdgesWithExcludesReverseIter<'_, VW, HEW, FW, VC, HEC, FC> {
CirculateEdgesWithExcludesReverseWalker {
circulator: self.vertex_rim_half_edges_reverse(vertex).walker(),
}
.iter(self)
}
}
impl<VW, HEW, FW, VC: Get<usize, Value = Vertex<VW>>, HEC: Get<usize, Value = HalfEdge<HEW>>, FC>
Dcel<VW, HEW, FW, VC, HEC, FC>
{
#[inline]
pub fn vertex_interspokes(
&self,
vertex: VertexId,
) -> InterspokesIter<'_, VW, HEW, FW, VC, HEC, FC> {
self.interspokes(self.vertex_representative(vertex))
}
#[inline]
pub fn vertex_interspokes_reverse(
&self,
vertex: VertexId,
) -> InterspokesReverseIter<'_, VW, HEW, FW, VC, HEC, FC> {
self.interspokes_reverse(self.vertex_representative(vertex))
}
}
impl<VW, HEW, FW, VC, HEC: Get<usize, Value = HalfEdge<HEW>>, FC> Dcel<VW, HEW, FW, VC, HEC, FC> {
#[inline]
pub fn spokes(
&self,
initial_half_edge: HalfEdgeId,
) -> SpokesIter<'_, VW, HEW, FW, VC, HEC, FC> {
SpokesWalker {
circulator: HalfSpokesWalker {
initial_half_edge,
curr_half_edge: Some(initial_half_edge),
},
}
.iter(self)
}
#[inline]
pub fn spokes_reverse(
&self,
initial_half_edge: HalfEdgeId,
) -> SpokesReverseIter<'_, VW, HEW, FW, VC, HEC, FC> {
SpokesReverseWalker {
circulator: HalfSpokesReverseWalker {
initial_half_edge,
curr_half_edge: Some(initial_half_edge),
},
}
.iter(self)
}
#[inline]
pub fn interspokes(
&self,
initial_half_edge: HalfEdgeId,
) -> InterspokesIter<'_, VW, HEW, FW, VC, HEC, FC> {
InterspokesWalker {
initial_half_edge,
curr_half_edge: Some(initial_half_edge),
}
.iter(self)
}
#[inline]
pub fn interspokes_reverse(
&self,
initial_half_edge: HalfEdgeId,
) -> InterspokesReverseIter<'_, VW, HEW, FW, VC, HEC, FC> {
InterspokesReverseWalker {
initial_half_edge,
curr_half_edge: Some(initial_half_edge),
}
.iter(self)
}
}
impl<VW, HEW, FW, VC, HEC: Get<usize, Value = HalfEdge<HEW>>, FC> Dcel<VW, HEW, FW, VC, HEC, FC> {
#[inline]
pub fn circulate_vertices(
&self,
initial_half_edge: HalfEdgeId,
) -> CirculateVertexesWithExcludesIter<'_, VW, HEW, FW, VC, HEC, FC> {
self.circulate_vertices_with_excludes(initial_half_edge, std::iter::empty())
}
#[inline]
pub fn circulate_vertices_reverse(
&self,
initial_half_edge: HalfEdgeId,
) -> CirculateVertexesWithExcludesReverseIter<'_, VW, HEW, FW, VC, HEC, FC> {
self.circulate_vertices_with_excludes_reverse(initial_half_edge, std::iter::empty())
}
#[inline]
pub fn circulate_vertices_with_excludes(
&self,
initial_half_edge: HalfEdgeId,
excluded_half_edges: impl IntoIterator<Item = HalfEdgeId>,
) -> CirculateVertexesWithExcludesIter<'_, VW, HEW, FW, VC, HEC, FC> {
CirculateVertexesWithExcludesWalker {
circulator: self
.circulate_half_edges_with_excludes(initial_half_edge, excluded_half_edges)
.walker(),
}
.iter(self)
}
#[inline]
pub fn circulate_vertices_with_excludes_reverse(
&self,
initial_half_edge: HalfEdgeId,
excluded_half_edges: impl IntoIterator<Item = HalfEdgeId>,
) -> CirculateVertexesWithExcludesReverseIter<'_, VW, HEW, FW, VC, HEC, FC> {
CirculateVertexesWithExcludesReverseWalker {
circulator: self
.circulate_half_edges_with_excludes_reverse(initial_half_edge, excluded_half_edges)
.walker(),
}
.iter(self)
}
#[inline]
pub fn circulate_half_edges(
&self,
initial_half_edge: HalfEdgeId,
) -> CirculateHalfEdgesWithExcludesIter<'_, VW, HEW, FW, VC, HEC, FC> {
self.circulate_half_edges_with_excludes(initial_half_edge, std::iter::empty())
}
#[inline]
pub fn circulate_half_edges_reverse(
&self,
initial_half_edge: HalfEdgeId,
) -> CirculateHalfEdgesWithExcludesReverseIter<'_, VW, HEW, FW, VC, HEC, FC> {
self.circulate_half_edges_with_excludes_reverse(initial_half_edge, std::iter::empty())
}
#[inline]
pub fn circulate_half_edges_with_excludes(
&self,
initial_half_edge: HalfEdgeId,
excluded_half_edges: impl IntoIterator<Item = HalfEdgeId>,
) -> CirculateHalfEdgesWithExcludesIter<'_, VW, HEW, FW, VC, HEC, FC> {
CirculateHalfEdgesWithExcludesWalker {
initial_half_edge,
curr_half_edge: Some(initial_half_edge),
excluded_half_edges: excluded_half_edges.into_iter().collect(),
}
.iter(self)
}
#[inline]
pub fn circulate_half_edges_with_excludes_reverse(
&self,
initial_half_edge: HalfEdgeId,
excluded_half_edges: impl IntoIterator<Item = HalfEdgeId>,
) -> CirculateHalfEdgesWithExcludesReverseIter<'_, VW, HEW, FW, VC, HEC, FC> {
CirculateHalfEdgesWithExcludesReverseWalker {
initial_half_edge,
curr_half_edge: Some(initial_half_edge),
excluded_half_edges: excluded_half_edges.into_iter().collect(),
}
.iter(self)
}
#[inline]
pub fn circulate_edges(
&self,
initial_half_edge: HalfEdgeId,
) -> CirculateEdgesWithExcludesIter<'_, VW, HEW, FW, VC, HEC, FC> {
self.circulate_edges_with_excludes(initial_half_edge, std::iter::empty())
}
#[inline]
pub fn circulate_edges_reverse(
&self,
initial_half_edge: HalfEdgeId,
) -> CirculateEdgesWithExcludesReverseIter<'_, VW, HEW, FW, VC, HEC, FC> {
self.circulate_edges_with_excludes_reverse(initial_half_edge, std::iter::empty())
}
#[inline]
pub fn circulate_edges_with_excludes(
&self,
initial_half_edge: HalfEdgeId,
excluded_half_edges: impl IntoIterator<Item = HalfEdgeId>,
) -> CirculateEdgesWithExcludesIter<'_, VW, HEW, FW, VC, HEC, FC> {
CirculateEdgesWithExcludesWalker {
circulator: self
.circulate_half_edges_with_excludes(initial_half_edge, excluded_half_edges)
.walker(),
}
.iter(self)
}
#[inline]
pub fn circulate_edges_with_excludes_reverse(
&self,
initial_half_edge: HalfEdgeId,
excluded_half_edges: impl IntoIterator<Item = HalfEdgeId>,
) -> CirculateEdgesWithExcludesReverseIter<'_, VW, HEW, FW, VC, HEC, FC> {
CirculateEdgesWithExcludesReverseWalker {
circulator: self
.circulate_half_edges_with_excludes_reverse(initial_half_edge, excluded_half_edges)
.walker(),
}
.iter(self)
}
#[inline]
pub fn circulation_half_spokes(
&self,
initial_half_edge: HalfEdgeId,
excluded_half_edges: impl IntoIterator<Item = HalfEdgeId>,
) -> CirculationHalfSpokesIter<'_, VW, HEW, FW, VC, HEC, FC> {
CirculationHalfSpokesWalker {
circulator: self
.circulate_half_edges_with_excludes(initial_half_edge, excluded_half_edges)
.walker(),
half_spokes_walker: self.half_spokes(initial_half_edge).walker(),
prev_half_edge: self.prev(initial_half_edge),
}
.iter(self)
}
#[inline]
pub fn circulation_half_spokes_reverse(
&self,
initial_half_edge: HalfEdgeId,
excluded_half_edges: impl IntoIterator<Item = HalfEdgeId>,
) -> CirculateHalfSpokesReverseIter<'_, VW, HEW, FW, VC, HEC, FC> {
CirculationHalfSpokesReverseWalker {
circulator: self
.circulate_half_edges_with_excludes_reverse(initial_half_edge, excluded_half_edges)
.walker(),
half_spokes_walker: self.half_spokes(initial_half_edge).walker(),
prev_half_edge: self.next(initial_half_edge),
}
.iter(self)
}
#[inline]
pub fn circulation_spokes(
&self,
initial_half_edge: HalfEdgeId,
excluded_half_edges: impl IntoIterator<Item = HalfEdgeId>,
) -> CirculationSpokesIter<'_, VW, HEW, FW, VC, HEC, FC> {
CirculationSpokesWalker {
circulator: CirculationHalfSpokesWalker {
circulator: self
.circulate_half_edges_with_excludes(initial_half_edge, excluded_half_edges)
.walker(),
half_spokes_walker: self.half_spokes(initial_half_edge).walker(),
prev_half_edge: self.prev(initial_half_edge),
},
}
.iter(self)
}
#[inline]
pub fn circulation_spokes_reverse(
&self,
initial_half_edge: HalfEdgeId,
excluded_half_edges: impl IntoIterator<Item = HalfEdgeId>,
) -> CirculationSpokesReverseIter<'_, VW, HEW, FW, VC, HEC, FC> {
CirculationSpokesReverseWalker {
circulator: CirculationHalfSpokesReverseWalker {
circulator: self
.circulate_half_edges_with_excludes_reverse(
initial_half_edge,
excluded_half_edges,
)
.walker(),
half_spokes_walker: self.half_spokes(initial_half_edge).walker(),
prev_half_edge: self.next(initial_half_edge),
},
}
.iter(self)
}
#[inline]
pub fn circulation_interspokes(
&self,
initial_half_edge: HalfEdgeId,
excluded_half_edges: impl IntoIterator<Item = HalfEdgeId>,
) -> CirculationInterspokesIter<'_, VW, HEW, FW, VC, HEC, FC> {
CirculationInterspokesWalker {
circulator: CirculationHalfSpokesWalker {
circulator: self
.circulate_half_edges_with_excludes(initial_half_edge, excluded_half_edges)
.walker(),
half_spokes_walker: self.half_spokes(initial_half_edge).walker(),
prev_half_edge: self.prev(initial_half_edge),
},
}
.iter(self)
}
#[inline]
pub fn circulation_interspokes_reverse(
&self,
initial_half_edge: HalfEdgeId,
excluded_half_edges: impl IntoIterator<Item = HalfEdgeId>,
) -> CirculationInterspokesReverseIter<'_, VW, HEW, FW, VC, HEC, FC> {
CirculationInterspokesReverseWalker {
circulator: CirculationHalfSpokesReverseWalker {
circulator: self
.circulate_half_edges_with_excludes_reverse(
initial_half_edge,
excluded_half_edges,
)
.walker(),
half_spokes_walker: self.half_spokes(initial_half_edge).walker(),
prev_half_edge: self.prev(initial_half_edge),
},
}
.iter(self)
}
#[inline]
pub fn circulation_rim_half_edges(
&self,
initial_half_edge: HalfEdgeId,
excluded_half_edges: impl IntoIterator<Item = HalfEdgeId>,
) -> CirculateHalfEdgesWithExcludesIter<'_, VW, HEW, FW, VC, HEC, FC> {
let excluded_half_edges = excluded_half_edges.into_iter().collect::<Vec<HalfEdgeId>>();
let mut rim_excluded_half_edges: Vec<HalfEdgeId> = self
.circulate_edges(initial_half_edge)
.flat_map(|edge| [edge.lesser(), edge.greater()])
.collect();
rim_excluded_half_edges.extend(
self.circulation_spokes(initial_half_edge, excluded_half_edges.iter().copied())
.flat_map(|edge| [edge.lesser(), edge.greater()]),
);
rim_excluded_half_edges.extend(excluded_half_edges.iter().copied());
let Some(initial_half_spoke) = self
.circulation_half_spokes(initial_half_edge, excluded_half_edges.iter().copied())
.next()
else {
return CirculateHalfEdgesWithExcludesWalker {
initial_half_edge,
curr_half_edge: None,
excluded_half_edges: rim_excluded_half_edges,
}
.iter(self);
};
let initial_half_edge = self
.half_spokes(self.twin(initial_half_spoke))
.find(|half_spoke| !rim_excluded_half_edges.contains(half_spoke))
.unwrap();
self.circulate_half_edges_with_excludes(initial_half_edge, rim_excluded_half_edges)
}
#[inline]
pub fn circulation_rim_half_edges_reverse(
&self,
initial_half_edge: HalfEdgeId,
excluded_half_edges: impl IntoIterator<Item = HalfEdgeId>,
) -> CirculateHalfEdgesWithExcludesReverseIter<'_, VW, HEW, FW, VC, HEC, FC> {
let excluded_half_edges = excluded_half_edges.into_iter().collect::<Vec<HalfEdgeId>>();
let mut rim_excluded_half_edges: Vec<HalfEdgeId> = self
.circulate_edges_reverse(initial_half_edge)
.flat_map(|edge| [edge.lesser(), edge.greater()])
.collect();
rim_excluded_half_edges.extend(
self.circulation_spokes_reverse(initial_half_edge, excluded_half_edges.iter().copied())
.flat_map(|edge| [edge.lesser(), edge.greater()]),
);
rim_excluded_half_edges.extend(excluded_half_edges.iter().copied());
let Some(initial_half_spoke) = self
.circulation_half_spokes_reverse(initial_half_edge, excluded_half_edges.iter().copied())
.next()
else {
return CirculateHalfEdgesWithExcludesReverseWalker {
initial_half_edge,
curr_half_edge: None,
excluded_half_edges: rim_excluded_half_edges,
}
.iter(self);
};
let initial_half_edge = self
.half_spokes(self.twin(initial_half_spoke))
.find(|half_spoke| !rim_excluded_half_edges.contains(half_spoke))
.unwrap();
self.circulate_half_edges_with_excludes_reverse(initial_half_edge, rim_excluded_half_edges)
}
#[inline]
pub fn circulation_rim_edges(
&self,
initial_half_edge: HalfEdgeId,
excluded_half_edges: impl IntoIterator<Item = HalfEdgeId>,
) -> CirculateEdgesWithExcludesIter<'_, VW, HEW, FW, VC, HEC, FC> {
CirculateEdgesWithExcludesWalker {
circulator: self
.circulation_rim_half_edges(initial_half_edge, excluded_half_edges)
.walker(),
}
.iter(self)
}
#[inline]
pub fn circulation_rim_edges_reverse(
&self,
initial_half_edge: HalfEdgeId,
excluded_half_edges: impl IntoIterator<Item = HalfEdgeId>,
) -> CirculateEdgesWithExcludesReverseIter<'_, VW, HEW, FW, VC, HEC, FC> {
CirculateEdgesWithExcludesReverseWalker {
circulator: self
.circulation_rim_half_edges_reverse(initial_half_edge, excluded_half_edges)
.walker(),
}
.iter(self)
}
#[inline]
pub fn circulation_rim_vertices(
&self,
initial_half_edge: HalfEdgeId,
excluded_half_edges: impl IntoIterator<Item = HalfEdgeId>,
) -> CirculateVertexesWithExcludesIter<'_, VW, HEW, FW, VC, HEC, FC> {
CirculateVertexesWithExcludesWalker {
circulator: self
.circulation_rim_half_edges(initial_half_edge, excluded_half_edges)
.walker(),
}
.iter(self)
}
#[inline]
pub fn circulation_rim_vertices_reverse(
&self,
initial_half_edge: HalfEdgeId,
excluded_half_edges: impl IntoIterator<Item = HalfEdgeId>,
) -> CirculateVertexesWithExcludesReverseIter<'_, VW, HEW, FW, VC, HEC, FC> {
CirculateVertexesWithExcludesReverseWalker {
circulator: self
.circulation_rim_half_edges_reverse(initial_half_edge, excluded_half_edges)
.walker(),
}
.iter(self)
}
}
impl<
VW,
HEW,
FW,
VC: Get<usize, Value = Vertex<VW>>,
HEC: Get<usize, Value = HalfEdge<HEW>>,
FC: Get<usize, Value = Face<FW>>,
> Dcel<VW, HEW, FW, VC, HEC, FC>
{
#[inline]
pub fn face_vertices(
&self,
face: FaceId,
) -> CirculateVertexesWithExcludesIter<'_, VW, HEW, FW, VC, HEC, FC> {
CirculateVertexesWithExcludesWalker {
circulator: self.face_half_edges(face).walker(),
}
.iter(self)
}
#[inline]
pub fn face_vertices_reverse(
&self,
face: FaceId,
) -> CirculateVertexesWithExcludesReverseIter<'_, VW, HEW, FW, VC, HEC, FC> {
CirculateVertexesWithExcludesReverseWalker {
circulator: self.face_half_edges_reverse(face).walker(),
}
.iter(self)
}
}
impl<VW, HEW, FW, VC, HEC, FC: Get<usize, Value = Face<FW>>> Dcel<VW, HEW, FW, VC, HEC, FC> {
#[inline]
pub fn face_half_edges(
&self,
face: FaceId,
) -> CirculateHalfEdgesWithExcludesIter<'_, VW, HEW, FW, VC, HEC, FC> {
let Some(initial_half_edge) = self.face_representative(face) else {
return CirculateHalfEdgesWithExcludesWalker {
initial_half_edge: HalfEdgeId::new(0),
curr_half_edge: None,
excluded_half_edges: vec![],
}
.iter(self);
};
CirculateHalfEdgesWithExcludesWalker {
initial_half_edge,
curr_half_edge: Some(initial_half_edge),
excluded_half_edges: vec![],
}
.iter(self)
}
#[inline]
pub fn face_half_edges_reverse(
&self,
face: FaceId,
) -> CirculateHalfEdgesWithExcludesReverseIter<'_, VW, HEW, FW, VC, HEC, FC> {
let Some(initial_half_edge) = self.face_representative(face) else {
return CirculateHalfEdgesWithExcludesReverseWalker {
initial_half_edge: HalfEdgeId::new(0),
curr_half_edge: None,
excluded_half_edges: vec![],
}
.iter(self);
};
CirculateHalfEdgesWithExcludesReverseWalker {
initial_half_edge,
curr_half_edge: Some(initial_half_edge),
excluded_half_edges: vec![],
}
.iter(self)
}
#[inline]
pub fn face_edges(
&self,
face: FaceId,
) -> CirculateEdgesWithExcludesIter<'_, VW, HEW, FW, VC, HEC, FC> {
CirculateEdgesWithExcludesWalker {
circulator: self.face_half_edges(face).walker(),
}
.iter(self)
}
#[inline]
pub fn face_edges_reverse(
&self,
face: FaceId,
) -> CirculateEdgesWithExcludesReverseIter<'_, VW, HEW, FW, VC, HEC, FC> {
CirculateEdgesWithExcludesReverseWalker {
circulator: self.face_half_edges_reverse(face).walker(),
}
.iter(self)
}
}
impl<VW, HEW, FW, VC, HEC: Get<usize, Value = HalfEdge<HEW>>, FC: Get<usize, Value = Face<FW>>>
Dcel<VW, HEW, FW, VC, HEC, FC>
{
#[inline]
pub fn face_half_spokes(
&self,
face: FaceId,
) -> CirculationHalfSpokesIter<'_, VW, HEW, FW, VC, HEC, FC> {
let Some(initial_half_edge) = self.face_representative(face) else {
return CirculationHalfSpokesWalker {
circulator: CirculateHalfEdgesWithExcludesWalker {
initial_half_edge: HalfEdgeId::new(0),
curr_half_edge: None,
excluded_half_edges: vec![],
},
half_spokes_walker: HalfSpokesWalker {
initial_half_edge: HalfEdgeId::new(0),
curr_half_edge: None,
},
prev_half_edge: HalfEdgeId::new(0),
}
.iter(self);
};
self.circulation_half_spokes(initial_half_edge, std::iter::empty())
}
#[inline]
pub fn face_half_spokes_reverse(
&self,
face: FaceId,
) -> CirculateHalfSpokesReverseIter<'_, VW, HEW, FW, VC, HEC, FC> {
let Some(initial_half_edge) = self.face_representative(face) else {
return CirculationHalfSpokesReverseWalker {
circulator: CirculateHalfEdgesWithExcludesReverseWalker {
initial_half_edge: HalfEdgeId::new(0),
curr_half_edge: None,
excluded_half_edges: vec![],
},
half_spokes_walker: HalfSpokesWalker {
initial_half_edge: HalfEdgeId::new(0),
curr_half_edge: None,
},
prev_half_edge: HalfEdgeId::new(0),
}
.iter(self);
};
self.circulation_half_spokes_reverse(initial_half_edge, std::iter::empty())
}
#[inline]
pub fn face_spokes(&self, face: FaceId) -> CirculationSpokesIter<'_, VW, HEW, FW, VC, HEC, FC> {
let Some(initial_half_edge) = self.face_representative(face) else {
return CirculationSpokesWalker {
circulator: CirculationHalfSpokesWalker {
circulator: CirculateHalfEdgesWithExcludesWalker {
initial_half_edge: HalfEdgeId::new(0),
curr_half_edge: None,
excluded_half_edges: vec![],
},
half_spokes_walker: HalfSpokesWalker {
initial_half_edge: HalfEdgeId::new(0),
curr_half_edge: None,
},
prev_half_edge: HalfEdgeId::new(0),
},
}
.iter(self);
};
self.circulation_spokes(initial_half_edge, std::iter::empty())
}
#[inline]
pub fn face_spokes_reverse(
&self,
face: FaceId,
) -> CirculationSpokesReverseIter<'_, VW, HEW, FW, VC, HEC, FC> {
let Some(initial_half_edge) = self.face_representative(face) else {
return CirculationSpokesReverseWalker {
circulator: CirculationHalfSpokesReverseWalker {
circulator: CirculateHalfEdgesWithExcludesReverseWalker {
initial_half_edge: HalfEdgeId::new(0),
curr_half_edge: None,
excluded_half_edges: vec![],
},
half_spokes_walker: HalfSpokesWalker {
initial_half_edge: HalfEdgeId::new(0),
curr_half_edge: None,
},
prev_half_edge: HalfEdgeId::new(0),
},
}
.iter(self);
};
self.circulation_spokes_reverse(initial_half_edge, std::iter::empty())
}
#[inline]
pub fn face_interspokes(
&self,
face: FaceId,
) -> CirculationInterspokesIter<'_, VW, HEW, FW, VC, HEC, FC> {
let Some(initial_half_edge) = self.face_representative(face) else {
return CirculationInterspokesWalker {
circulator: CirculationHalfSpokesWalker {
circulator: CirculateHalfEdgesWithExcludesWalker {
initial_half_edge: HalfEdgeId::new(0),
curr_half_edge: None,
excluded_half_edges: vec![],
},
half_spokes_walker: HalfSpokesWalker {
initial_half_edge: HalfEdgeId::new(0),
curr_half_edge: None,
},
prev_half_edge: HalfEdgeId::new(0),
},
}
.iter(self);
};
self.circulation_interspokes(initial_half_edge, std::iter::empty())
}
#[inline]
pub fn face_interspokes_reverse(
&self,
face: FaceId,
) -> CirculationInterspokesReverseIter<'_, VW, HEW, FW, VC, HEC, FC> {
let Some(initial_half_edge) = self.face_representative(face) else {
return CirculationInterspokesReverseWalker {
circulator: CirculationHalfSpokesReverseWalker {
circulator: CirculateHalfEdgesWithExcludesReverseWalker {
initial_half_edge: HalfEdgeId::new(0),
curr_half_edge: None,
excluded_half_edges: vec![],
},
half_spokes_walker: HalfSpokesWalker {
initial_half_edge: HalfEdgeId::new(0),
curr_half_edge: None,
},
prev_half_edge: HalfEdgeId::new(0),
},
}
.iter(self);
};
self.circulation_interspokes_reverse(initial_half_edge, std::iter::empty())
}
#[inline]
pub fn face_rim_half_edges(
&self,
face: FaceId,
) -> CirculateHalfEdgesWithExcludesIter<'_, VW, HEW, FW, VC, HEC, FC> {
let Some(initial_half_edge) = self.face_representative(face) else {
return CirculateHalfEdgesWithExcludesWalker {
initial_half_edge: HalfEdgeId::new(0),
curr_half_edge: None,
excluded_half_edges: vec![],
}
.iter(self);
};
self.circulation_rim_half_edges(initial_half_edge, std::iter::empty())
}
#[inline]
pub fn face_rim_half_edges_reverse(
&self,
face: FaceId,
) -> CirculateHalfEdgesWithExcludesReverseIter<'_, VW, HEW, FW, VC, HEC, FC> {
let Some(initial_half_edge) = self.face_representative(face) else {
return CirculateHalfEdgesWithExcludesReverseWalker {
initial_half_edge: HalfEdgeId::new(0),
curr_half_edge: None,
excluded_half_edges: vec![],
}
.iter(self);
};
self.circulation_rim_half_edges_reverse(initial_half_edge, std::iter::empty())
}
#[inline]
pub fn face_rim_vertices(
&self,
face: FaceId,
) -> CirculateVertexesWithExcludesIter<'_, VW, HEW, FW, VC, HEC, FC> {
let Some(initial_half_edge) = self.face_representative(face) else {
return CirculateVertexesWithExcludesWalker {
circulator: CirculateHalfEdgesWithExcludesWalker {
initial_half_edge: HalfEdgeId::new(0),
curr_half_edge: None,
excluded_half_edges: vec![],
},
}
.iter(self);
};
self.circulation_rim_vertices(initial_half_edge, std::iter::empty())
}
#[inline]
pub fn face_rim_vertices_reverse(
&self,
face: FaceId,
) -> CirculateVertexesWithExcludesReverseIter<'_, VW, HEW, FW, VC, HEC, FC> {
let Some(initial_half_edge) = self.face_representative(face) else {
return CirculateVertexesWithExcludesReverseWalker {
circulator: CirculateHalfEdgesWithExcludesReverseWalker {
initial_half_edge: HalfEdgeId::new(0),
curr_half_edge: None,
excluded_half_edges: vec![],
},
}
.iter(self);
};
self.circulation_rim_vertices_reverse(initial_half_edge, std::iter::empty())
}
#[inline]
pub fn face_rim_edges(
&self,
face: FaceId,
) -> CirculateEdgesWithExcludesIter<'_, VW, HEW, FW, VC, HEC, FC> {
let Some(initial_half_edge) = self.face_representative(face) else {
return CirculateEdgesWithExcludesWalker {
circulator: CirculateHalfEdgesWithExcludesWalker {
initial_half_edge: HalfEdgeId::new(0),
curr_half_edge: None,
excluded_half_edges: vec![],
},
}
.iter(self);
};
self.circulation_rim_edges(initial_half_edge, std::iter::empty())
}
#[inline]
pub fn face_rim_edges_reverse(
&self,
face: FaceId,
) -> CirculateEdgesWithExcludesReverseIter<'_, VW, HEW, FW, VC, HEC, FC> {
let Some(initial_half_edge) = self.face_representative(face) else {
return CirculateEdgesWithExcludesReverseWalker {
circulator: CirculateHalfEdgesWithExcludesReverseWalker {
initial_half_edge: HalfEdgeId::new(0),
curr_half_edge: None,
excluded_half_edges: vec![],
},
}
.iter(self);
};
self.circulation_rim_edges_reverse(initial_half_edge, std::iter::empty())
}
}
#[cfg(test)]
mod test {
use crate::{
Dcel, assert_face_boundary, assert_face_rim, assert_face_spokes_interspokes,
assert_vertex_rim, assert_vertex_spokes_interspokes, init_dcel_with_3x3_hex_mesh,
};
#[test]
fn test_vertex_rims() {
let dcel = init_dcel_with_3x3_hex_mesh!(Dcel<(i32, i32)>);
assert_vertex_rim!(&dcel, 0, 0);
assert_vertex_rim!(&dcel, 1, 0);
assert_vertex_rim!(&dcel, 2, 0);
assert_vertex_rim!(&dcel, 3, 0);
assert_vertex_rim!(&dcel, 4, 0);
assert_vertex_rim!(&dcel, 5, 12);
assert_vertex_rim!(&dcel, 6, 0);
assert_vertex_rim!(&dcel, 7, 0);
assert_vertex_rim!(&dcel, 8, 12);
assert_vertex_rim!(&dcel, 9, 12);
assert_vertex_rim!(&dcel, 10, 0);
assert_vertex_rim!(&dcel, 11, 0);
assert_vertex_rim!(&dcel, 12, 12);
assert_vertex_rim!(&dcel, 13, 0);
assert_vertex_rim!(&dcel, 14, 0);
assert_vertex_rim!(&dcel, 15, 12);
assert_vertex_rim!(&dcel, 16, 12);
assert_vertex_rim!(&dcel, 17, 12);
assert_vertex_rim!(&dcel, 18, 12);
assert_vertex_rim!(&dcel, 19, 0);
assert_vertex_rim!(&dcel, 20, 0);
assert_vertex_rim!(&dcel, 21, 0);
assert_vertex_rim!(&dcel, 22, 0);
assert_vertex_rim!(&dcel, 23, 0);
assert_vertex_rim!(&dcel, 24, 0);
assert_vertex_rim!(&dcel, 25, 0);
assert_vertex_rim!(&dcel, 26, 0);
assert_vertex_rim!(&dcel, 27, 0);
assert_vertex_rim!(&dcel, 28, 0);
assert_vertex_rim!(&dcel, 29, 0);
}
#[test]
fn test_vertex_spokes_interspokes() {
let dcel = init_dcel_with_3x3_hex_mesh!(Dcel<(i32, i32)>);
assert_vertex_spokes_interspokes!(&dcel, 0, 3);
assert_vertex_spokes_interspokes!(&dcel, 1, 2);
assert_vertex_spokes_interspokes!(&dcel, 2, 2);
assert_vertex_spokes_interspokes!(&dcel, 3, 2);
assert_vertex_spokes_interspokes!(&dcel, 4, 3);
assert_vertex_spokes_interspokes!(&dcel, 5, 3);
assert_vertex_spokes_interspokes!(&dcel, 6, 3);
assert_vertex_spokes_interspokes!(&dcel, 7, 2);
assert_vertex_spokes_interspokes!(&dcel, 8, 3);
assert_vertex_spokes_interspokes!(&dcel, 9, 3);
assert_vertex_spokes_interspokes!(&dcel, 10, 2);
assert_vertex_spokes_interspokes!(&dcel, 11, 2);
assert_vertex_spokes_interspokes!(&dcel, 12, 3);
assert_vertex_spokes_interspokes!(&dcel, 13, 3);
assert_vertex_spokes_interspokes!(&dcel, 14, 3);
assert_vertex_spokes_interspokes!(&dcel, 15, 3);
assert_vertex_spokes_interspokes!(&dcel, 16, 3);
assert_vertex_spokes_interspokes!(&dcel, 17, 3);
assert_vertex_spokes_interspokes!(&dcel, 18, 3);
assert_vertex_spokes_interspokes!(&dcel, 19, 2);
assert_vertex_spokes_interspokes!(&dcel, 20, 3);
assert_vertex_spokes_interspokes!(&dcel, 21, 2);
assert_vertex_spokes_interspokes!(&dcel, 22, 2);
assert_vertex_spokes_interspokes!(&dcel, 23, 2);
assert_vertex_spokes_interspokes!(&dcel, 24, 2);
assert_vertex_spokes_interspokes!(&dcel, 25, 3);
assert_vertex_spokes_interspokes!(&dcel, 26, 2);
assert_vertex_spokes_interspokes!(&dcel, 27, 3);
assert_vertex_spokes_interspokes!(&dcel, 28, 2);
assert_vertex_spokes_interspokes!(&dcel, 29, 2);
}
#[test]
fn test_face_boundaries() {
let dcel = init_dcel_with_3x3_hex_mesh!(Dcel<(i32, i32)>);
assert_face_boundary!(&dcel, 0, 0);
assert_face_boundary!(&dcel, 1, 6);
assert_face_boundary!(&dcel, 2, 6);
assert_face_boundary!(&dcel, 3, 6);
assert_face_boundary!(&dcel, 4, 6);
assert_face_boundary!(&dcel, 5, 6);
assert_face_boundary!(&dcel, 6, 6);
assert_face_boundary!(&dcel, 7, 6);
assert_face_boundary!(&dcel, 8, 6);
assert_face_boundary!(&dcel, 9, 6);
}
#[test]
fn test_face_spokes_interspokes() {
let dcel = init_dcel_with_3x3_hex_mesh!(Dcel<(i32, i32)>);
assert_face_spokes_interspokes!(&dcel, 0, 0);
assert_face_spokes_interspokes!(&dcel, 1, 3);
assert_face_spokes_interspokes!(&dcel, 2, 5);
assert_face_spokes_interspokes!(&dcel, 3, 4);
assert_face_spokes_interspokes!(&dcel, 4, 6);
assert_face_spokes_interspokes!(&dcel, 5, 6);
assert_face_spokes_interspokes!(&dcel, 6, 4);
assert_face_spokes_interspokes!(&dcel, 7, 3);
assert_face_spokes_interspokes!(&dcel, 8, 5);
assert_face_spokes_interspokes!(&dcel, 9, 4);
}
#[test]
fn test_face_rims() {
let dcel = init_dcel_with_3x3_hex_mesh!(Dcel<(i32, i32)>);
assert_face_rim!(&dcel, 0, 0);
assert_face_rim!(&dcel, 5, 18);
}
}