1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
//! A single, continues 2d region
use fj_interop::mesh::Color;
use crate::{objects::Cycle, storage::Handle};
/// A single, continuous 2d region, may contain holes
///
/// Interior cycles must have the opposite winding of the exterior cycle,
/// meaning on the front side of the region, they must appear clockwise. This
/// means that all [`HalfEdge`]s that bound a `Region` have the interior of the
/// region on their left side (on the region's front side).
///
/// [`HalfEdge`]: crate::objects::HalfEdge
#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct Region {
exterior: Handle<Cycle>,
interiors: Vec<Handle<Cycle>>,
color: Option<Color>,
}
impl Region {
/// Construct an instance of `Region`
pub fn new(
exterior: Handle<Cycle>,
interiors: impl IntoIterator<Item = Handle<Cycle>>,
color: Option<Color>,
) -> Self {
Self {
exterior,
interiors: interiors.into_iter().collect(),
color,
}
}
/// Access the cycle that bounds the region on the outside
pub fn exterior(&self) -> &Handle<Cycle> {
&self.exterior
}
/// Access the cycles that bound the region on the inside
///
/// Each of these cycles defines a hole in the region .
pub fn interiors(&self) -> impl Iterator<Item = &Handle<Cycle>> + '_ {
self.interiors.iter()
}
/// Access all cycles of the region (both exterior and interior)
pub fn all_cycles(&self) -> impl Iterator<Item = &Handle<Cycle>> + '_ {
[self.exterior()].into_iter().chain(self.interiors())
}
/// Access the color of the region
pub fn color(&self) -> Option<Color> {
self.color
}
}