Struct truck_topology::Face[][src]

pub struct Face<P, C, S> { /* fields omitted */ }

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:

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]

Creates a new face by a wire.

Panic

All wires in boundaries must be non-empty, simple and closed.

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>>

Notable traits for Vec<u8, Global>

impl Write for Vec<u8, Global>
[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>>

Notable traits for Vec<u8, Global>

impl Write for Vec<u8, Global>
[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>>

Notable traits for Vec<u8, Global>

impl Write for Vec<u8, Global>
[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>>

Notable traits for Vec<u8, Global>

impl Write for Vec<u8, Global>
[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]

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

  1. 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());
}
  1. 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]

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

  1. 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());
}
  1. 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]

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]

impl<P, C, S> Hash for Face<P, C, S>[src]

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]

impl<P, C, S> Sync for Face<P, C, S> where
    C: Send,
    P: Send,
    S: Send
[src]

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]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.