Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::rc::Rc;
- use std::cell::{RefCell, RefMut, Ref};
- use std::ptr;
- #[derive(Debug)]
- struct SharedRcOption<T>(Option<Rc<RefCell<T>>>);
- impl<T> SharedRcOption<T> {
- fn none() -> Self {
- Self(None)
- }
- fn new(element: T) -> Self {
- Self(Some(Rc::new(RefCell::new(element))))
- }
- fn empty(&self) -> bool {
- self.0.is_none()
- }
- fn borrow_mut(&mut self) -> RefMut<T> {
- self.0.as_mut().expect(
- "Empty SharedRCOption cannot be unwrapped"
- ).borrow_mut()
- }
- fn borrow(&self) -> Ref<T> {
- self.0.as_ref().expect(
- "Empty SharedRCOption cannot be unwrapped"
- ).borrow()
- }
- fn clear(&mut self) {
- self.0 = None;
- }
- }
- impl<T> Clone for SharedRcOption<T> {
- fn clone(&self) -> Self {
- Self(self.0.clone())
- }
- }
- trait ToShared where Self: Sized {
- fn to_shared(self) -> SharedRcOption<Self> {
- SharedRcOption::new(self)
- }
- }
- #[derive(Debug)]
- struct Face {
- neighbor_edge: SharedRcOption<HalfEdge>,
- }
- #[derive(Debug)]
- struct Vertex {
- location: [i32; 2],
- outgoing: SharedRcOption<HalfEdge>,
- }
- impl Vertex {
- fn new(location: [i32; 2]) -> Self {
- Self {
- location,
- outgoing: SharedRcOption::none(),
- }
- }
- }
- #[derive(Debug)]
- struct HalfEdge {
- next: SharedRcOption<HalfEdge>,
- opposite: SharedRcOption<HalfEdge>,
- end_vertex: SharedRcOption<Vertex>,
- face: SharedRcOption<Face>,
- }
- impl HalfEdge {
- fn empty() -> Self {
- Self {
- next: SharedRcOption::none(),
- opposite: SharedRcOption::none(),
- end_vertex: SharedRcOption::none(),
- face: SharedRcOption::none(),
- }
- }
- fn connect(mut from: SharedRcOption<Vertex>, to: SharedRcOption<Vertex>) -> SharedRcOption<Self> {
- let mut opposite = Self {
- end_vertex: from.clone(),
- ..Self::empty()
- }.to_shared();
- let new_edge = Self {
- opposite: opposite.clone(),
- end_vertex: to,
- ..Self::empty()
- }.to_shared();
- if from.borrow().outgoing.empty() {
- from.borrow_mut().outgoing = new_edge.clone();
- }
- opposite.borrow_mut().opposite = new_edge.clone();
- new_edge
- }
- }
- impl ToShared for HalfEdge {}
- impl ToShared for Face {}
- impl ToShared for Vertex {}
- struct Mesh {
- vertices: Vec<SharedRcOption<Vertex>>,
- }
- impl Mesh {
- fn new(start_coordinates: [i32; 2]) -> Self {
- Self { vertices: vec![Vertex::new(start_coordinates).to_shared()] }
- }
- fn line_to(&mut self, from: SharedRcOption<Vertex>, to: [i32; 2]) -> SharedRcOption<HalfEdge> {
- if from.borrow().location == to {
- panic!("Cannot connect a vertex with a new vertex at the same coordinates");
- }
- let target_vertex = Vertex::new(to).to_shared();
- self.vertices.push(target_vertex.clone());
- HalfEdge::connect(from, target_vertex)
- }
- fn connect(&mut self, from: SharedRcOption<Vertex>, to: SharedRcOption<Vertex>) -> SharedRcOption<HalfEdge> {
- if ptr::eq(&*from.borrow(), &*to.borrow()) {
- panic!("Cannot connect a vertex with itself");
- }
- HalfEdge::connect(from, to)
- }
- }
- fn main() {
- let mut mesh = Mesh::new([0, 0]);
- let edge = mesh.line_to(mesh.vertices[0].clone(), [2, 4]);
- let start = mesh.vertices[0].borrow().location;
- let target_1 = edge.borrow().end_vertex.borrow().location;
- let target_2 = edge.borrow().opposite.borrow().end_vertex.borrow().location;
- let target_3 = edge.borrow().opposite.borrow().opposite.borrow().end_vertex.borrow().location;
- let target_4 = edge.borrow().opposite.borrow().opposite.borrow().opposite.borrow().end_vertex.borrow().location;
- mesh.connect(mesh.vertices[1].clone(), mesh.vertices[1].clone());
- println!(
- "{:?} -> {:?} | {:?} -> {:?} | {:?} -> {:?}",
- start, target_1,
- target_1, target_2,
- target_4, target_3,
- );
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement