mirror of https://github.com/hannobraun/Fornjot
Merge pull request #1828 from A-Walrus/sketch_face_v2
Rework Sketches v2
This commit is contained in:
commit
2d15ac0555
|
@ -12,9 +12,9 @@ impl Approx for &Sketch {
|
|||
|
||||
fn approx_with_cache(
|
||||
self,
|
||||
tolerance: impl Into<Tolerance>,
|
||||
cache: &mut Self::Cache,
|
||||
_tolerance: impl Into<Tolerance>,
|
||||
_cache: &mut Self::Cache,
|
||||
) -> Self::Approximation {
|
||||
self.faces().approx_with_cache(tolerance, cache)
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use fj_math::Vector;
|
||||
|
||||
use crate::{
|
||||
objects::{Sketch, Solid},
|
||||
objects::{Sketch, Solid, Surface},
|
||||
operations::Insert,
|
||||
services::Services,
|
||||
storage::Handle,
|
||||
|
@ -9,7 +9,7 @@ use crate::{
|
|||
|
||||
use super::{Sweep, SweepCache};
|
||||
|
||||
impl Sweep for Handle<Sketch> {
|
||||
impl Sweep for (Handle<Sketch>, Handle<Surface>) {
|
||||
type Swept = Handle<Solid>;
|
||||
|
||||
fn sweep_with_cache(
|
||||
|
@ -21,7 +21,7 @@ impl Sweep for Handle<Sketch> {
|
|||
let path = path.into();
|
||||
|
||||
let mut shells = Vec::new();
|
||||
for face in self.faces().clone() {
|
||||
for face in self.0.faces(self.1, services) {
|
||||
let shell = face.sweep_with_cache(path, cache, services);
|
||||
shells.push(shell);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ mod cycle;
|
|||
mod edge;
|
||||
mod face;
|
||||
mod shell;
|
||||
mod sketch;
|
||||
mod solid;
|
||||
mod surface;
|
||||
mod vertex;
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
use fj_math::Transform;
|
||||
|
||||
use crate::{objects::Sketch, services::Services};
|
||||
|
||||
use super::{TransformCache, TransformObject};
|
||||
|
||||
impl TransformObject for Sketch {
|
||||
fn transform_with_cache(
|
||||
self,
|
||||
transform: &Transform,
|
||||
services: &mut Services,
|
||||
cache: &mut TransformCache,
|
||||
) -> Self {
|
||||
let faces =
|
||||
self.faces().into_iter().cloned().map(|face| {
|
||||
face.transform_with_cache(transform, services, cache)
|
||||
});
|
||||
|
||||
Self::new(faces)
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
//! Types that are tied to objects, but aren't objects themselves
|
||||
|
||||
pub mod curve;
|
||||
pub mod region;
|
||||
pub mod surface;
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
//! A single, continues 2d region
|
||||
use fj_interop::mesh::Color;
|
||||
|
||||
use crate::{
|
||||
objects::{Cycle, Face, Surface},
|
||||
operations::Insert,
|
||||
services::Services,
|
||||
storage::Handle,
|
||||
};
|
||||
|
||||
/// A single, continuous 2d region, may contain holes. Once applied to a
|
||||
/// [`Surface`] becomes a [`Face`]
|
||||
///
|
||||
/// 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: Vec<Handle<Cycle>>,
|
||||
color: Option<Color>,
|
||||
) -> Self {
|
||||
Self {
|
||||
exterior,
|
||||
interiors,
|
||||
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
|
||||
}
|
||||
|
||||
/// Convert the 2D region to a 3D face, by applying it to a surface.
|
||||
pub fn face(
|
||||
&self,
|
||||
surface: Handle<Surface>,
|
||||
services: &mut Services,
|
||||
) -> Handle<Face> {
|
||||
let face: Face = Face::new(
|
||||
surface,
|
||||
self.exterior().clone(),
|
||||
self.interiors().cloned(),
|
||||
self.color,
|
||||
);
|
||||
face.insert(services)
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ use fj_interop::mesh::Color;
|
|||
use fj_math::Winding;
|
||||
|
||||
use crate::{
|
||||
geometry::region::Region,
|
||||
objects::{Cycle, Surface},
|
||||
storage::Handle,
|
||||
};
|
||||
|
@ -35,9 +36,7 @@ use crate::{
|
|||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
|
||||
pub struct Face {
|
||||
surface: Handle<Surface>,
|
||||
exterior: Handle<Cycle>,
|
||||
interiors: Vec<Handle<Cycle>>,
|
||||
color: Option<Color>,
|
||||
region: Region,
|
||||
}
|
||||
|
||||
impl Face {
|
||||
|
@ -52,9 +51,7 @@ impl Face {
|
|||
|
||||
Self {
|
||||
surface,
|
||||
exterior,
|
||||
interiors,
|
||||
color,
|
||||
region: Region::new(exterior, interiors, color),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,24 +62,24 @@ impl Face {
|
|||
|
||||
/// Access the cycle that bounds the face on the outside
|
||||
pub fn exterior(&self) -> &Handle<Cycle> {
|
||||
&self.exterior
|
||||
self.region.exterior()
|
||||
}
|
||||
|
||||
/// Access the cycles that bound the face on the inside
|
||||
///
|
||||
/// Each of these cycles defines a hole in the face.
|
||||
pub fn interiors(&self) -> impl Iterator<Item = &Handle<Cycle>> + '_ {
|
||||
self.interiors.iter()
|
||||
self.region.interiors()
|
||||
}
|
||||
|
||||
/// Access all cycles of the face (both exterior and interior)
|
||||
pub fn all_cycles(&self) -> impl Iterator<Item = &Handle<Cycle>> + '_ {
|
||||
[self.exterior()].into_iter().chain(self.interiors())
|
||||
self.region.all_cycles()
|
||||
}
|
||||
|
||||
/// Access the color of the face
|
||||
pub fn color(&self) -> Option<Color> {
|
||||
self.color
|
||||
self.region.color()
|
||||
}
|
||||
|
||||
/// Determine handed-ness of the face's front-side coordinate system
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
use std::collections::BTreeSet;
|
||||
|
||||
use crate::{
|
||||
objects::{Face, FaceSet},
|
||||
geometry::region::Region,
|
||||
objects::{FaceSet, Surface},
|
||||
services::Services,
|
||||
storage::Handle,
|
||||
};
|
||||
|
||||
|
@ -11,19 +15,26 @@ use crate::{
|
|||
/// currently validated.
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
|
||||
pub struct Sketch {
|
||||
faces: FaceSet,
|
||||
regions: BTreeSet<Region>,
|
||||
}
|
||||
|
||||
impl Sketch {
|
||||
/// Construct an empty instance of `Sketch`
|
||||
pub fn new(faces: impl IntoIterator<Item = Handle<Face>>) -> Self {
|
||||
pub fn new(regions: impl IntoIterator<Item = Region>) -> Self {
|
||||
Self {
|
||||
faces: faces.into_iter().collect(),
|
||||
regions: regions.into_iter().collect(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Access the faces of the sketch
|
||||
pub fn faces(&self) -> &FaceSet {
|
||||
&self.faces
|
||||
/// Apply the regions of the sketch to some [`Surface`]
|
||||
pub fn faces(
|
||||
&self,
|
||||
surface: Handle<Surface>,
|
||||
services: &mut Services,
|
||||
) -> FaceSet {
|
||||
self.regions
|
||||
.iter()
|
||||
.map(|r| r.face(surface.clone(), services))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue