use std::rc::Rc;
use std::cell::RefCell;
use edge::Edge;
use ptr::{
Ptr,
EdgePtr, EdgeRc,
VertPtr, VertRc,
FacePtr,
};
pub trait ToPtrVec<T> where Self: Iterator<Item=Ptr<T>> {
fn to_ptr_vec(self) -> Vec<Rc<RefCell<T>>>;
}
impl<I, T> ToPtrVec<T> for I where I: Iterator<Item=Ptr<T>> {
fn to_ptr_vec(self) -> Vec<Rc<RefCell<T>>> {
self.filter_map(|v| v.upgrade()).collect()
}
}
enum TwiceIterState {
First, Second, Done
}
pub struct EdgeAdjacentVertIterator<'a> {
state: TwiceIterState,
start: &'a Edge,
}
impl<'a> EdgeAdjacentVertIterator<'a> {
pub fn new(target: & Edge) -> EdgeAdjacentVertIterator {
EdgeAdjacentVertIterator {
state: TwiceIterState::First,
start: target,
}
}
}
impl<'a> Iterator for EdgeAdjacentVertIterator<'a> {
type Item = VertPtr;
fn next(&mut self) -> Option<VertPtr> {
match self.state {
TwiceIterState::First => {
self.state = TwiceIterState::Second;
Some(self.start.origin.clone())
},
TwiceIterState::Second => {
self.state = TwiceIterState::Done;
self.start.next.upgrade()
.map(|next_rc| next_rc.borrow().origin.clone())
},
TwiceIterState::Done => None,
}
}
}
pub struct EdgeAdjacentEdgeIterator {
vert_iter_1: Option<VertAdjacentEdgeIterator>,
vert_iter_2: Option<VertAdjacentEdgeIterator>,
state: DualIterState,
}
#[derive(Clone)]
enum DualIterState {
Both,
First,
Second,
Neither
}
impl EdgeAdjacentEdgeIterator {
pub fn new(target: & Edge) -> EdgeAdjacentEdgeIterator {
let iter_1_opt: Option<VertAdjacentEdgeIterator> = target.origin.upgrade()
.map(|vert_ptr: VertRc| vert_ptr.borrow().adjacent_edges());
let iter_2_opt: Option<VertAdjacentEdgeIterator> = target.next.upgrade()
.and_then(|edge_next: EdgeRc| edge_next.borrow().origin.upgrade())
.map(|vert_ptr: VertRc| vert_ptr.borrow().adjacent_edges());
let state = match (iter_1_opt.as_ref(), iter_2_opt.as_ref()) {
(Some(_), Some(_)) => DualIterState::Both,
(Some(_), None) => DualIterState::First,
(None, Some(_)) => DualIterState::Second,
(None, None) => DualIterState::Neither
};
EdgeAdjacentEdgeIterator {
state: state,
vert_iter_1: iter_1_opt,
vert_iter_2: iter_2_opt
}
}
}
impl Iterator for EdgeAdjacentEdgeIterator {
type Item = EdgePtr;
fn next(&mut self) -> Option<EdgePtr> {
match self.state {
DualIterState::Both => {
match self.vert_iter_1.as_mut().unwrap().next() {
val @ Some(..) => val,
None => {
self.state = DualIterState::Second;
self.vert_iter_2.as_mut().unwrap().next()
}
}
},
DualIterState::First => self.vert_iter_1.as_mut().unwrap().next(),
DualIterState::Second => self.vert_iter_2.as_mut().unwrap().next(),
DualIterState::Neither => None,
}
}
}
pub struct EdgeAdjacentFaceIterator<'a> {
start: &'a Edge,
state: TwiceIterState
}
impl<'a> EdgeAdjacentFaceIterator<'a> {
pub fn new(target: &'a Edge) -> EdgeAdjacentFaceIterator<'a> {
EdgeAdjacentFaceIterator {
start: target,
state: TwiceIterState::First
}
}
}
impl<'a> Iterator for EdgeAdjacentFaceIterator<'a> {
type Item = FacePtr;
fn next(&mut self) -> Option<FacePtr> {
match self.state {
TwiceIterState::First => {
self.state = TwiceIterState::Second;
Some(self.start.face.clone())
},
TwiceIterState::Second => {
self.state = TwiceIterState::Done;
self.start.pair.upgrade()
.map(|pair_rc: EdgeRc| pair_rc.borrow().face.clone())
},
TwiceIterState::Done => None
}
}
}
pub struct VertAdjacentVertIterator {
start: EdgePtr,
current: Option<EdgePtr>,
}
impl VertAdjacentVertIterator {
pub fn new(edge: EdgePtr) -> VertAdjacentVertIterator {
VertAdjacentVertIterator {
start: edge,
current: None,
}
}
}
impl Iterator for VertAdjacentVertIterator {
type Item = VertPtr;
fn next(&mut self) -> Option<VertPtr> {
match self.current.clone() {
Some(cur_weak) => cur_weak.upgrade()
.and_then(|cur_rc: EdgeRc| cur_rc.borrow().pair.upgrade())
.and_then(|pair_rc: EdgeRc| {
let next_weak: EdgePtr = pair_rc.borrow().next.clone();
Ptr::merge_upgrade(& next_weak, & self.start)
.and_then(|(next_rc, start_rc)| {
if next_rc == start_rc {
None
} else {
self.current = Some(next_weak);
Some(pair_rc.borrow().origin.clone())
}
})
}),
None => self.start.upgrade()
.and_then(|cur_rc: EdgeRc| cur_rc.borrow().pair.upgrade())
.map(|pair_rc: EdgeRc| {
self.current = Some(self.start.clone());
pair_rc.borrow().origin.clone()
}),
}
}
}
pub struct VertAdjacentEdgeIterator {
start: EdgePtr,
current: Option<EdgePtr>,
}
impl VertAdjacentEdgeIterator {
pub fn new(edge: EdgePtr) -> VertAdjacentEdgeIterator {
VertAdjacentEdgeIterator {
start: edge,
current: None
}
}
}
impl Iterator for VertAdjacentEdgeIterator {
type Item = EdgePtr;
fn next(&mut self) -> Option<EdgePtr> {
match self.current.clone() {
Some(cur_weak) => cur_weak.upgrade()
.and_then(|cur_rc: EdgeRc| cur_rc.borrow().pair.upgrade())
.map(|pair_rc: EdgeRc| pair_rc.borrow().next.clone())
.and_then(|next_weak: EdgePtr| {
Ptr::merge_upgrade(& next_weak, & self.start)
.and_then(|(next_rc, start_rc)| {
if next_rc == start_rc {
None
} else {
self.current = Some(next_weak.clone());
Some(next_weak)
}
})
}),
None => self.start.upgrade()
.map(|_: EdgeRc| {
self.current = Some(self.start.clone());
self.start.clone()
}),
}
}
}
pub struct VertAdjacentFaceIterator {
start: EdgePtr,
current: Option<EdgePtr>,
}
impl VertAdjacentFaceIterator {
pub fn new(edge: EdgePtr) -> VertAdjacentFaceIterator {
VertAdjacentFaceIterator {
start: edge,
current: None,
}
}
}
impl Iterator for VertAdjacentFaceIterator {
type Item = FacePtr;
fn next(&mut self) -> Option<FacePtr> {
match self.current.clone() {
Some(cur_weak) => cur_weak.upgrade()
.and_then(|cur_rc: EdgeRc| cur_rc.borrow().pair.upgrade())
.map(|pair_rc: EdgeRc| pair_rc.borrow().next.clone())
.and_then(|next_weak: EdgePtr| {
Ptr::merge_upgrade(& next_weak, & self.start)
.and_then(|(next_rc, start_rc)| {
if next_rc == start_rc {
None
} else {
self.current = Some(next_weak);
Some(next_rc.borrow().face.clone())
}
})
}),
None => self.start.upgrade()
.map(|cur_rc: EdgeRc| {
self.current = Some(self.start.clone());
cur_rc.borrow().face.clone()
}),
}
}
}
pub struct FaceAdjacentVertIterator {
start: EdgePtr,
current: Option<EdgePtr>,
}
impl FaceAdjacentVertIterator {
pub fn new(edge: EdgePtr) -> FaceAdjacentVertIterator {
FaceAdjacentVertIterator {
start: edge,
current: None,
}
}
}
impl Iterator for FaceAdjacentVertIterator {
type Item = VertPtr;
fn next(&mut self) -> Option<VertPtr> {
match self.current.clone() {
Some(cur_weak) => cur_weak.upgrade()
.map(|cur_rc: EdgeRc| cur_rc.borrow().next.clone())
.and_then(|next_weak: EdgePtr| {
Ptr::merge_upgrade(& next_weak, & self.start)
.and_then(|(next_rc, start_rc)| {
if next_rc == start_rc {
None
} else {
self.current = Some(next_weak);
Some(next_rc.borrow().origin.clone())
}
})
}),
None => self.start.upgrade()
.map(|cur_rc: EdgeRc| {
self.current = Some(self.start.clone());
cur_rc.borrow().origin.clone()
}),
}
}
}
pub struct FaceAdjacentEdgeIterator {
start: EdgePtr,
current: Option<EdgePtr>
}
impl FaceAdjacentEdgeIterator {
pub fn new(edge: EdgePtr) -> FaceAdjacentEdgeIterator {
FaceAdjacentEdgeIterator {
start: edge,
current: None
}
}
}
impl Iterator for FaceAdjacentEdgeIterator {
type Item = EdgePtr;
fn next(&mut self) -> Option<EdgePtr> {
match self.current.clone() {
Some(cur_weak) => cur_weak.upgrade()
.map(|cur_rc: EdgeRc| cur_rc.borrow().next.clone())
.and_then(|next_weak: EdgePtr| {
Ptr::merge_upgrade(& next_weak, & self.start)
.and_then(|(next_rc, start_rc)| {
if next_rc == start_rc {
None
} else {
self.current = Some(next_weak.clone());
Some(next_weak)
}
})
}),
None => {
self.current = Some(self.start.clone());
Some(self.start.clone())
},
}
}
}
pub struct FaceAdjacentFaceIterator {
start: EdgePtr,
current: Option<EdgePtr>,
}
impl FaceAdjacentFaceIterator {
pub fn new(edge: EdgePtr) -> FaceAdjacentFaceIterator {
FaceAdjacentFaceIterator {
start: edge,
current: None
}
}
}
impl Iterator for FaceAdjacentFaceIterator {
type Item = FacePtr;
fn next(&mut self) -> Option<FacePtr> {
match self.current.clone() {
Some(cur_weak) => cur_weak.upgrade()
.map(|cur_rc: EdgeRc| cur_rc.borrow().next.clone())
.and_then(|next_weak: EdgePtr| {
Ptr::merge_upgrade(& next_weak, & self.start)
.and_then(|(next_rc, start_rc)| {
if next_rc == start_rc {
None
} else {
next_rc.borrow().pair.upgrade()
.map(|pair_rc| {
self.current = Some(next_weak);
pair_rc.borrow().face.clone()
})
}
})
}),
None => self.start.upgrade()
.and_then(|edge_rc: EdgeRc| edge_rc.borrow().pair.upgrade())
.map(|pair_rc: EdgeRc| {
self.current = Some(self.start.clone());
pair_rc.borrow().face.clone()
}),
}
}
}