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

Expand and update operations API #1879

Merged
merged 11 commits into from
Jun 12, 2023
2 changes: 1 addition & 1 deletion crates/fj-core/src/algorithms/approx/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ mod tests {
let mut services = Services::new();

let surface = services.objects.surfaces.xz_plane();
let half_edge = HalfEdge::circle(1., &mut services);
let half_edge = HalfEdge::circle([0., 0.], 1., &mut services);

let tolerance = 1.;
let approx = (&half_edge, surface.deref()).approx(tolerance);
Expand Down
5 changes: 0 additions & 5 deletions crates/fj-core/src/geometry/curve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,6 @@ pub enum Curve {
}

impl Curve {
/// Build a circle from the given radius
pub fn circle_from_radius(radius: impl Into<Scalar>) -> Self {
Self::circle_from_center_and_radius(Point::origin(), radius)
}

/// Build a circle from the given radius
pub fn circle_from_center_and_radius(
center: impl Into<Point<2>>,
Expand Down
10 changes: 5 additions & 5 deletions crates/fj-core/src/objects/kinds/sketch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@ use crate::{
};

/// A 2-dimensional shape
///
/// # Implementation Note
///
/// The faces that make up the sketch must be in the same surface. This is not
/// currently validated.
#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct Sketch {
regions: BTreeSet<Region>,
Expand All @@ -26,6 +21,11 @@ impl Sketch {
}
}

/// Access the regions of the sketch
pub fn regions(&self) -> impl Iterator<Item = &Region> {
self.regions.iter()
}

/// Apply the regions of the sketch to some [`Surface`]
pub fn faces(
&self,
Expand Down
15 changes: 13 additions & 2 deletions crates/fj-core/src/operations/build/cycle.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use fj_math::Point;
use fj_math::{Point, Scalar};
use itertools::Itertools;

use crate::{
objects::{Cycle, HalfEdge},
operations::{BuildHalfEdge, Insert},
operations::{BuildHalfEdge, Insert, UpdateCycle},
services::Services,
};

Expand All @@ -14,6 +14,17 @@ pub trait BuildCycle {
Cycle::new([])
}

/// Build a circle
fn circle(
center: impl Into<Point<2>>,
radius: impl Into<Scalar>,
services: &mut Services,
) -> Cycle {
let circle =
HalfEdge::circle(center, radius, services).insert(services);
Cycle::empty().add_half_edges([circle])
}

/// Build a polygon
fn polygon<P, Ps>(points: Ps, services: &mut Services) -> Cycle
where
Expand Down
8 changes: 6 additions & 2 deletions crates/fj-core/src/operations/build/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,12 @@ pub trait BuildHalfEdge {
}

/// Create a circle
fn circle(radius: impl Into<Scalar>, services: &mut Services) -> HalfEdge {
let curve = Curve::circle_from_radius(radius);
fn circle(
center: impl Into<Point<2>>,
radius: impl Into<Scalar>,
services: &mut Services,
) -> HalfEdge {
let curve = Curve::circle_from_center_and_radius(center, radius);
let boundary =
[Scalar::ZERO, Scalar::TAU].map(|coord| Point::from([coord]));

Expand Down
22 changes: 4 additions & 18 deletions crates/fj-core/src/operations/build/sketch.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,10 @@
use fj_math::Point;

use crate::{
geometry::region::Region,
objects::{Cycle, Sketch},
operations::{BuildCycle, Insert},
services::Services,
};
use crate::objects::Sketch;

/// Build a [`Sketch`]
pub trait BuildSketch {
/// Build a polygon
fn polygon<P, Ps>(points: Ps, services: &mut Services) -> Sketch
where
P: Into<Point<2>>,
Ps: IntoIterator<Item = P>,
Ps::IntoIter: Clone + ExactSizeIterator,
{
let exterior = Cycle::polygon(points, services).insert(services);
let region = Region::new(exterior, Vec::new(), None);
Sketch::new([region])
/// Create a sketch with no regions
fn empty() -> Sketch {
Sketch::new([])
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/fj-core/src/operations/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ pub use self::{
join::cycle::JoinCycle,
update::{
cycle::UpdateCycle, edge::UpdateHalfEdge, face::UpdateFace,
shell::UpdateShell, solid::UpdateSolid,
shell::UpdateShell, sketch::UpdateSketch, solid::UpdateSolid,
},
};
1 change: 1 addition & 0 deletions crates/fj-core/src/operations/update/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ pub mod cycle;
pub mod edge;
pub mod face;
pub mod shell;
pub mod sketch;
pub mod solid;
55 changes: 55 additions & 0 deletions crates/fj-core/src/operations/update/sketch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use fj_math::{Point, Scalar};

use crate::{
geometry::region::Region,
objects::{Cycle, Sketch},
operations::{BuildCycle, Insert},
services::Services,
};

/// Update a [`Sketch`]
pub trait UpdateSketch {
/// Add a region to the sketch
fn add_region(&self, region: Region) -> Self;

/// Add a circle to the sketch
fn add_circle(
&self,
center: impl Into<Point<2>>,
radius: impl Into<Scalar>,
services: &mut Services,
) -> Self;

/// Add a polygon to the sketch
fn add_polygon<P, Ps>(&self, points: Ps, services: &mut Services) -> Self
where
P: Into<Point<2>>,
Ps: IntoIterator<Item = P>,
Ps::IntoIter: Clone + ExactSizeIterator;
}

impl UpdateSketch for Sketch {
fn add_region(&self, region: Region) -> Self {
Sketch::new(self.regions().cloned().chain([region]))
}

fn add_circle(
&self,
center: impl Into<Point<2>>,
radius: impl Into<Scalar>,
services: &mut Services,
) -> Self {
let exterior = Cycle::circle(center, radius, services).insert(services);
self.add_region(Region::new(exterior, [], None))
}

fn add_polygon<P, Ps>(&self, points: Ps, services: &mut Services) -> Self
where
P: Into<Point<2>>,
Ps: IntoIterator<Item = P>,
Ps::IntoIter: Clone + ExactSizeIterator,
{
let exterior = Cycle::polygon(points, services).insert(services);
self.add_region(Region::new(exterior, [], None))
}
}
23 changes: 12 additions & 11 deletions models/cuboid/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use fj::{
core::{
algorithms::sweep::Sweep,
objects::{Sketch, Solid},
operations::{BuildSketch, Insert},
operations::{BuildSketch, Insert, UpdateSketch},
services::Services,
storage::Handle,
},
Expand All @@ -12,16 +12,17 @@ use fj::{
pub fn cuboid(x: f64, y: f64, z: f64) -> Handle<Solid> {
let mut services = Services::new();

let sketch = Sketch::polygon(
[
[-x / 2., -y / 2.],
[x / 2., -y / 2.],
[x / 2., y / 2.],
[-x / 2., y / 2.],
],
&mut services,
)
.insert(&mut services);
let sketch = Sketch::empty()
.add_polygon(
[
[-x / 2., -y / 2.],
[x / 2., -y / 2.],
[x / 2., y / 2.],
[-x / 2., y / 2.],
],
&mut services,
)
.insert(&mut services);

let surface = services.objects.surfaces.xy_plane();

Expand Down