Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework Sketches v2 #1828

Merged
merged 3 commits into from
May 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions crates/fj-kernel/src/algorithms/approx/sketch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left this as a todo!() for now as I'm not aware that we need to approximate Sketches directly yet, we always first turn them into faces/shells and then approximate?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, fair enough. We can fill this in once required 👍

}
}
6 changes: 3 additions & 3 deletions crates/fj-kernel/src/algorithms/sweep/sketch.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
use fj_math::Vector;

use crate::{
objects::{Sketch, Solid},
objects::{Sketch, Solid, Surface},
operations::Insert,
services::Services,
storage::Handle,
};

use super::{Sweep, SweepCache};

impl Sweep for Handle<Sketch> {
impl Sweep for (Handle<Sketch>, Handle<Surface>) {
type Swept = Handle<Solid>;

fn sweep_with_cache(
Expand All @@ -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);
}
Expand Down
1 change: 0 additions & 1 deletion crates/fj-kernel/src/algorithms/transform/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ mod cycle;
mod edge;
mod face;
mod shell;
mod sketch;
mod solid;
mod surface;
mod vertex;
Expand Down
21 changes: 0 additions & 21 deletions crates/fj-kernel/src/algorithms/transform/sketch.rs

This file was deleted.

1 change: 1 addition & 0 deletions crates/fj-kernel/src/geometry/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//! Types that are tied to objects, but aren't objects themselves

pub mod curve;
pub mod region;
pub mod surface;
77 changes: 77 additions & 0 deletions crates/fj-kernel/src/geometry/region.rs
Original file line number Diff line number Diff line change
@@ -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)
}
}
17 changes: 7 additions & 10 deletions crates/fj-kernel/src/objects/full/face.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use fj_interop::mesh::Color;
use fj_math::Winding;

use crate::{
geometry::region::Region,
objects::{Cycle, Surface},
storage::Handle,
};
Expand Down Expand Up @@ -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 {
Expand All @@ -52,9 +51,7 @@ impl Face {

Self {
surface,
exterior,
interiors,
color,
region: Region::new(exterior, interiors, color),
}
}

Expand All @@ -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
Expand Down
25 changes: 18 additions & 7 deletions crates/fj-kernel/src/objects/full/sketch.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
use std::collections::BTreeSet;

use crate::{
objects::{Face, FaceSet},
geometry::region::Region,
objects::{FaceSet, Surface},
services::Services,
storage::Handle,
};

Expand All @@ -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()
}
}