Struct truck_topology::Face [−][src]
Face, attatched to a simple and closed wire.
The constructors Face::new()
, Face::try_new()
, and Face::new_unchecked()
create a different faces each time, even if the boundary wires are the same one.
A face is uniquely identified by their id
.
use truck_topology::*; use std::iter::FromIterator; let v = Vertex::news(&[(), ()]); let edge0 = Edge::new(&v[0], &v[1], ()); let edge1 = Edge::new(&v[1], &v[0], ()); let wire = Wire::from_iter(vec![&edge0, &edge1]); let face0 = Face::new(vec![wire.clone()], ()); let face1 = Face::new(vec![wire], ()); assert_ne!(face0.id(), face1.id());
Implementations
impl<P, C, S> Face<P, C, S>
[src]
pub fn try_new(boundaries: Vec<Wire<P, C>>, surface: S) -> Result<Face<P, C, S>>
[src]
Creates a new face by a wire.
Failure
All wires in boundaries
must be non-empty, simple and closed. If not, returns the following errors:
- If a wire is empty, then returns
Error::EmptyWire
. - If a wire is not closed, then returns
Error::NotClosedWire
. - If a wire is closed but not simple, then returns
Error::NotSimpleWire
.
Examples
let v = Vertex::news(&[(); 4]); let mut wire = Wire::from(vec![ Edge::new(&v[0], &v[1], ()), Edge::new(&v[1], &v[2], ()), Edge::new(&v[2], &v[3], ()), Edge::new(&v[3], &v[0], ()), ]); assert!(Face::try_new(vec![wire], ()).is_ok());
pub fn new(boundaries: Vec<Wire<P, C>>, surface: S) -> Face<P, C, S>
[src]
pub fn new_unchecked(boundaries: Vec<Wire<P, C>>, surface: S) -> Face<P, C, S>
[src]
Creates a new face by a wire.
Remarks
This method is prepared only for performance-critical development and is not recommended.
This method does NOT check the regularity conditions of Face::try_new()
.
The programmer must guarantee this condition before using this method.
pub fn debug_new(boundaries: Vec<Wire<P, C>>, surface: S) -> Face<P, C, S>
[src]
Creates a new face by a wire.
Remarks
This method check the regularity conditions of Face::try_new()
in the debug mode.
The programmer must guarantee this condition before using this method.
pub fn boundaries(&self) -> Vec<Wire<P, C>>ⓘ
[src]
Returns the boundaries of the face.
Examples
use truck_topology::*; let v = Vertex::news(&[(); 3]); let wire = Wire::from(vec![ Edge::new(&v[0], &v[1], ()), Edge::new(&v[1], &v[2], ()), Edge::new(&v[2], &v[0], ()), ]); let mut face = Face::new(vec![wire], ()); let boundaries = face.boundaries(); for (i, vert) in boundaries[0].vertex_iter().enumerate() { assert_eq!(vert, v[i]); } // If invert the face, the boundaries is also inverted. face.invert(); assert_eq!(boundaries[0].inverse(), face.boundaries()[0]);
pub fn into_boundaries(self) -> Vec<Wire<P, C>>ⓘ
[src]
Consumes self
and returns the entity of its boundaries.
let v = Vertex::news(&[(), (), ()]); let wire = Wire::from(vec![ Edge::new(&v[0], &v[1], ()), Edge::new(&v[1], &v[2], ()), Edge::new(&v[2], &v[0], ()), ]); let mut face = Face::new(vec![wire], ()); let boundaries = face.clone().into_boundaries(); for (i, vert) in boundaries[0].vertex_iter().enumerate() { assert_eq!(vert, v[i]); } // If invert the face, the boundaries is also inverted. face.invert(); assert_eq!(boundaries[0].inverse(), face.into_boundaries()[0]);
pub fn absolute_boundaries(&self) -> &Vec<Wire<P, C>>ⓘ
[src]
Returns the reference of the boundaries wire which is generated by constructor.
Examples
use truck_topology::*; let v = Vertex::news(&[(), (), ()]); let wire = Wire::from(vec![ Edge::new(&v[0], &v[1], ()), Edge::new(&v[1], &v[2], ()), Edge::new(&v[2], &v[0], ()), ]); let mut face = Face::new(vec![wire], ()); let boundaries = face.boundaries(); face.invert(); // The result of face.boudnary() is already inversed. assert_eq!(face.boundaries()[0], boundaries[0].inverse()); // The absolute boundaries does never change. assert_eq!(face.absolute_boundaries(), &boundaries);
pub fn boundary_iters(&self) -> Vec<BoundaryIter<'_, P, C>>ⓘ
[src]
Returns an iterator over all edges in the boundaries.
use truck_topology::*; let v = Vertex::news(&[(), (), ()]); let wire = Wire::from(vec![ Edge::new(&v[0], &v[1], ()), Edge::new(&v[1], &v[2], ()), Edge::new(&v[2], &v[0], ()), ]); let mut face = Face::new(vec![wire], ()); face.invert(); let boundaries = face.boundaries().clone(); let edge_iter0 = boundaries.iter().flat_map(Wire::edge_iter); let edge_iter1 = face.boundary_iters().into_iter().flatten(); for (edge0, edge1) in edge_iter0.zip(edge_iter1) { assert_eq!(edge0, &edge1); }
pub fn try_add_boundary(&mut self, wire: Wire<P, C>) -> Result<()> where
S: Clone,
[src]
S: Clone,
Adds a boundary to the face.
Examples
use truck_topology::*; let v = Vertex::news(&[(), (), (), (), (), ()]); let wire0 = Wire::from(vec![ Edge::new(&v[0], &v[1], ()), Edge::new(&v[1], &v[2], ()), Edge::new(&v[2], &v[0], ()), ]); let wire1 = Wire::from(vec![ Edge::new(&v[3], &v[4], ()), Edge::new(&v[4], &v[5], ()), Edge::new(&v[5], &v[3], ()), ]); let mut face0 = Face::new(vec![wire0.clone()], ()); face0.try_add_boundary(wire1.clone()).unwrap(); let face1 = Face::new(vec![wire0, wire1], ()); assert_eq!(face0.boundaries(), face1.boundaries());
Remarks
- If the face is inverted, then the added wire is inverted as absolute bounday.
use truck_topology::*; let v = Vertex::news(&[(), (), (), (), (), ()]); let wire0 = Wire::from(vec![ Edge::new(&v[0], &v[1], ()), Edge::new(&v[1], &v[2], ()), Edge::new(&v[2], &v[0], ()), ]); let wire1 = Wire::from(vec![ Edge::new(&v[3], &v[4], ()), Edge::new(&v[5], &v[4], ()).inverse(), Edge::new(&v[5], &v[3], ()), ]); let mut face = Face::new(vec![wire0], ()); face.invert(); face.try_add_boundary(wire1.clone()).unwrap(); // The boundary is added in compatible with the face orientation. assert_eq!(face.boundaries()[1], wire1); // The absolute bounday is inverted! let iter0 = face.absolute_boundaries()[1].edge_iter(); let iter1 = wire1.edge_iter().rev(); for (edge0, edge1) in iter0.zip(iter1) { assert_eq!(edge0.id(), edge1.id()); assert_eq!(edge0.orientation(), !edge1.orientation()); }
- This method renew the face id.
use truck_topology::*; let v = Vertex::news(&[(), (), (), (), (), ()]); let wire0 = Wire::from(vec![ Edge::new(&v[0], &v[1], ()), Edge::new(&v[1], &v[2], ()), Edge::new(&v[2], &v[0], ()), ]); let wire1 = Wire::from(vec![ Edge::new(&v[3], &v[4], ()), Edge::new(&v[5], &v[4], ()).inverse(), Edge::new(&v[5], &v[3], ()), ]); let mut face0 = Face::new(vec![wire0], ()); let face1 = face0.clone(); assert_eq!(face0.id(), face1.id()); face0.try_add_boundary(wire1).unwrap(); assert_ne!(face0.id(), face1.id());
pub fn add_boundary(&mut self, wire: Wire<P, C>) where
S: Clone,
[src]
S: Clone,
Adds a boundary to the face.
Examples
use truck_topology::*; let v = Vertex::news(&[(), (), (), (), (), ()]); let wire0 = Wire::from(vec![ Edge::new(&v[0], &v[1], ()), Edge::new(&v[1], &v[2], ()), Edge::new(&v[2], &v[0], ()), ]); let wire1 = Wire::from(vec![ Edge::new(&v[3], &v[4], ()), Edge::new(&v[4], &v[5], ()), Edge::new(&v[5], &v[3], ()), ]); let mut face0 = Face::new(vec![wire0.clone()], ()); face0.add_boundary(wire1.clone()); let face1 = Face::new(vec![wire0, wire1], ()); assert_eq!(face0.boundaries(), face1.boundaries());
Remarks
- If the face is inverted, then the added wire is inverted as absolute bounday.
use truck_topology::*; let v = Vertex::news(&[(), (), (), (), (), ()]); let wire0 = Wire::from(vec![ Edge::new(&v[0], &v[1], ()), Edge::new(&v[1], &v[2], ()), Edge::new(&v[2], &v[0], ()), ]); let wire1 = Wire::from(vec![ Edge::new(&v[3], &v[4], ()), Edge::new(&v[5], &v[4], ()).inverse(), Edge::new(&v[5], &v[3], ()), ]); let mut face = Face::new(vec![wire0], ()); face.invert(); face.add_boundary(wire1.clone()); // The boundary is added in compatible with the face orientation. assert_eq!(face.boundaries()[1], wire1); // The absolute bounday is inverted! let iter0 = face.absolute_boundaries()[1].edge_iter(); let iter1 = wire1.edge_iter().rev(); for (edge0, edge1) in iter0.zip(iter1) { assert_eq!(edge0.id(), edge1.id()); assert_eq!(edge0.orientation(), !edge1.orientation()); }
- This method renew the face id.
use truck_topology::*; let v = Vertex::news(&[(), (), (), (), (), ()]); let wire0 = Wire::from(vec![ Edge::new(&v[0], &v[1], ()), Edge::new(&v[1], &v[2], ()), Edge::new(&v[2], &v[0], ()), ]); let wire1 = Wire::from(vec![ Edge::new(&v[3], &v[4], ()), Edge::new(&v[5], &v[4], ()).inverse(), Edge::new(&v[5], &v[3], ()), ]); let mut face0 = Face::new(vec![wire0], ()); let face1 = face0.clone(); assert_eq!(face0.id(), face1.id()); face0.add_boundary(wire1); assert_ne!(face0.id(), face1.id());
pub fn orientation(&self) -> bool
[src]
Returns the orientation of face.
The result of this method is the same with self.boundaries() == self.absolute_boundaries().clone()
.
Moreover, if this method returns false, self.boundaries() == self.absolute_boundaries().inverse()
.
pub fn try_lock_surface(&self) -> TryLockResult<MutexGuard<'_, S>>
[src]
Returns the id of face.
Examples
use truck_topology::*; let v = Vertex::news(&[(), (), ()]); let wire = Wire::from(vec![ Edge::new(&v[0], &v[1], ()), Edge::new(&v[1], &v[2], ()), Edge::new(&v[2], &v[0], ()), ]); let face0 = Face::new(vec![wire], 0); let face1 = face0.clone(); // Two faces have the same content. assert_eq!(*face0.try_lock_surface().unwrap(), 0); assert_eq!(*face1.try_lock_surface().unwrap(), 0); { let mut surface = face0.try_lock_surface().unwrap(); *surface = 1; } // The contents of two vertices are synchronized. assert_eq!(*face0.try_lock_surface().unwrap(), 1); assert_eq!(*face1.try_lock_surface().unwrap(), 1); // The thread is not blocked even if the surface is already locked. let lock = face0.try_lock_surface(); assert!(face1.try_lock_surface().is_err());
pub fn lock_surface(&self) -> LockResult<MutexGuard<'_, S>>
[src]
Returns the id of face.
Examples
use truck_topology::*; let v = Vertex::news(&[(), (), ()]); let wire = Wire::from(vec![ Edge::new(&v[0], &v[1], ()), Edge::new(&v[1], &v[2], ()), Edge::new(&v[2], &v[0], ()), ]); let face0 = Face::new(vec![wire], 0); let face1 = face0.clone(); // Two faces have the same content. assert_eq!(*face0.lock_surface().unwrap(), 0); assert_eq!(*face1.lock_surface().unwrap(), 0); { let mut surface = face0.lock_surface().unwrap(); *surface = 1; } // The contents of two vertices are synchronized. assert_eq!(*face0.lock_surface().unwrap(), 1); assert_eq!(*face1.lock_surface().unwrap(), 1); // Check the behavior of `lock`. std::thread::spawn(move || { *face0.lock_surface().unwrap() = 2; }).join().expect("thread::spawn failed"); assert_eq!(*face1.lock_surface().unwrap(), 2);
pub fn invert(&mut self) -> &mut Self
[src]
Inverts the direction of the face.
Examples
use truck_topology::*; use truck_topology::errors::Error; let v = Vertex::news(&[(), (), ()]); let wire = Wire::from(vec![ Edge::new(&v[0], &v[1], ()), Edge::new(&v[1], &v[2], ()), Edge::new(&v[2], &v[0], ()), ]); let mut face = Face::new(vec![wire], ()); let org_face = face.clone(); let org_bdry = face.boundaries(); face.invert(); // Two faces are the same face. face.is_same(&org_face); // The boundaries is inverted. let inversed_edge_iter = org_bdry[0].inverse().edge_into_iter(); let face_edge_iter = &mut face.boundary_iters()[0]; for (edge0, edge1) in inversed_edge_iter.zip(face_edge_iter) { assert_eq!(edge0, edge1); }
pub fn is_same(&self, other: &Self) -> bool
[src]
Returns whether two faces are the same. Returns true
even if the orientaions are different.
Examples
use truck_topology::*; let v = Vertex::news(&[(); 3]); let wire = Wire::from(vec![ Edge::new(&v[0], &v[1], ()), Edge::new(&v[1], &v[2], ()), Edge::new(&v[2], &v[0], ()), ]); let face0 = Face::new(vec![wire], ()); let face1 = face0.inverse(); assert_ne!(face0, face1); assert!(face0.is_same(&face1));
pub fn id(&self) -> FaceID<S>
[src]
Returns the id that does not depend on the direction of the face.
Examples
use truck_topology::*; let v = Vertex::news(&[(); 3]); let wire = Wire::from(vec![ Edge::new(&v[0], &v[1], ()), Edge::new(&v[1], &v[2], ()), Edge::new(&v[2], &v[0], ()), ]); let face0 = Face::new(vec![wire.clone()], ()); let face1 = face0.inverse(); let face2 = Face::new(vec![wire], ()); assert_ne!(face0, face1); assert_ne!(face0, face2); assert_eq!(face0.id(), face1.id()); assert_ne!(face0.id(), face2.id());
pub fn inverse(&self) -> Face<P, C, S>
[src]
Returns the inverse face.
Examples
use truck_topology::*; use truck_topology::errors::Error; let v = Vertex::news(&[(), (), ()]); let wire = Wire::from(vec![ Edge::new(&v[0], &v[1], ()), Edge::new(&v[1], &v[2], ()), Edge::new(&v[2], &v[0], ()), ]); let mut face = Face::new(vec![wire], ()); let inverted = face.inverse(); // Two faces are the same face. assert!(face.is_same(&inverted)); // Two faces has the same id. assert_eq!(face.id(), inverted.id()); // The boundaries is inverted. let mut inversed_edge_iter = face.boundaries()[0].inverse().edge_into_iter(); let face_edge_iter = &mut inverted.boundary_iters()[0]; for (edge0, edge1) in inversed_edge_iter.zip(face_edge_iter) { assert_eq!(edge0, edge1); }
pub fn border_on(&self, other: &Face<P, C, S>) -> bool
[src]
Returns whether two faces self
and other
have a shared edge.
Examples
use truck_topology::*; use std::iter::FromIterator; let v = Vertex::news(&[(); 4]); let shared_edge = Edge::new(&v[0], &v[1], ()); let another_edge = Edge::new(&v[0], &v[1], ()); let inversed_edge = shared_edge.inverse(); let wire = vec![ Wire::from_iter(vec![&Edge::new(&v[2], &v[0], ()), &shared_edge, &Edge::new(&v[1], &v[2], ())]), Wire::from_iter(vec![&Edge::new(&v[2], &v[0], ()), &another_edge, &Edge::new(&v[1], &v[2], ())]), Wire::from_iter(vec![&Edge::new(&v[3], &v[0], ()), &shared_edge, &Edge::new(&v[1], &v[3], ())]), Wire::from_iter(vec![&Edge::new(&v[3], &v[1], ()), &inversed_edge, &Edge::new(&v[0], &v[3], ())]), ]; let face: Vec<_> = wire.into_iter().map(|w| Face::new(vec![w], ())).collect(); assert!(face[0].border_on(&face[2])); assert!(!face[1].border_on(&face[2])); assert!(face[0].border_on(&face[3]));
impl<P, C: Curve<Point = P>, S: Surface<Point = C::Point, Vector = C::Vector, Curve = C>> Face<P, C, S>
[src]
pub fn oriented_surface(&self) -> S
[src]
Returns the cloned surface in face. If face is inverted, then the returned surface is also inverted.
pub fn is_geometric_consistent(&self) -> bool where
P: Tolerance,
[src]
P: Tolerance,
Returns the consistence of the geometry of end vertices and the geometry of edge.
Trait Implementations
impl<P, C, S> Clone for Face<P, C, S>
[src]
impl<P: Debug, C: Debug, S: Debug> Debug for Face<P, C, S>
[src]
impl<P, C, S> Eq for Face<P, C, S>
[src]
impl<P, C, S> FromIterator<Face<P, C, S>> for Shell<P, C, S>
[src]
fn from_iter<I: IntoIterator<Item = Face<P, C, S>>>(iter: I) -> Shell<P, C, S>
[src]
impl<P, C, S> Hash for Face<P, C, S>
[src]
fn hash<H: Hasher>(&self, state: &mut H)
[src]
pub fn hash_slice<H>(data: &[Self], state: &mut H) where
H: Hasher,
1.3.0[src]
H: Hasher,
impl<P, C, S> PartialEq<Face<P, C, S>> for Face<P, C, S>
[src]
Auto Trait Implementations
impl<P, C, S> RefUnwindSafe for Face<P, C, S>
[src]
impl<P, C, S> Send for Face<P, C, S> where
C: Send,
P: Send,
S: Send,
[src]
C: Send,
P: Send,
S: Send,
impl<P, C, S> Sync for Face<P, C, S> where
C: Send,
P: Send,
S: Send,
[src]
C: Send,
P: Send,
S: Send,
impl<P, C, S> Unpin for Face<P, C, S>
[src]
impl<P, C, S> UnwindSafe for Face<P, C, S>
[src]
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
pub fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T> ToOwned for T where
T: Clone,
[src]
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
pub fn to_owned(&self) -> T
[src]
pub fn clone_into(&self, target: &mut T)
[src]
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
pub fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,