Skip to content

Commit

Permalink
Merge pull request #2321 from hannobraun/surface
Browse files Browse the repository at this point in the history
Define special surface to represent 2D space
  • Loading branch information
hannobraun authored Apr 25, 2024
2 parents 78fa96d + 7fc8a18 commit 73fd64f
Show file tree
Hide file tree
Showing 13 changed files with 89 additions and 41 deletions.
8 changes: 8 additions & 0 deletions crates/fj-core/src/geometry/geometry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ pub struct Geometry {
half_edge: BTreeMap<Handle<HalfEdge>, HalfEdgeGeom>,
surface: BTreeMap<Handle<Surface>, SurfaceGeom>,

space_2d: Handle<Surface>,

xy_plane: Handle<Surface>,
xz_plane: Handle<Surface>,
yz_plane: Handle<Surface>,
Expand All @@ -26,6 +28,8 @@ impl Geometry {
half_edge: BTreeMap::new(),
surface: BTreeMap::new(),

space_2d: topology.surfaces.space_2d(),

xy_plane: topology.surfaces.xy_plane(),
xz_plane: topology.surfaces.xz_plane(),
yz_plane: topology.surfaces.yz_plane(),
Expand Down Expand Up @@ -69,6 +73,10 @@ impl Geometry {
surface: Handle<Surface>,
geometry: SurfaceGeom,
) {
if surface == self.space_2d {
panic!("Attempting to define geometry for 2D space");
}

if self.surface.contains_key(&surface)
&& (surface == self.xy_plane
|| surface == self.xz_plane
Expand Down
6 changes: 3 additions & 3 deletions crates/fj-core/src/operations/build/sketch.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::topology::Sketch;
use crate::topology::{Sketch, Topology};

/// Build a [`Sketch`]
///
Expand All @@ -7,8 +7,8 @@ use crate::topology::Sketch;
/// [module-level documentation]: super
pub trait BuildSketch {
/// Create a sketch with no regions
fn empty() -> Sketch {
Sketch::new([])
fn empty(topology: &Topology) -> Sketch {
Sketch::new(topology.surfaces.space_2d(), [])
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/fj-core/src/operations/replace/curve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ impl ReplaceCurve for Sketch {
}

if replacement_happened {
ReplaceOutput::Updated(Sketch::new(regions))
ReplaceOutput::Updated(Sketch::new(self.surface().clone(), regions))
} else {
ReplaceOutput::Original(self.clone())
}
Expand Down
2 changes: 1 addition & 1 deletion crates/fj-core/src/operations/replace/half_edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ impl ReplaceHalfEdge for Sketch {
}

if replacement_happened {
ReplaceOutput::Updated(Sketch::new(regions))
ReplaceOutput::Updated(Sketch::new(self.surface().clone(), regions))
} else {
ReplaceOutput::Original(self.clone())
}
Expand Down
4 changes: 2 additions & 2 deletions crates/fj-core/src/operations/replace/vertex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ impl ReplaceVertex for Sketch {
}

if replacement_happened {
ReplaceOutput::Updated(Sketch::new(regions))
ReplaceOutput::Updated(Sketch::new(self.surface().clone(), regions))
} else {
ReplaceOutput::Original(self.clone())
}
Expand Down Expand Up @@ -317,7 +317,7 @@ impl ReplaceVertex for Handle<Sketch> {
}

if replacement_happened {
ReplaceOutput::Updated(Sketch::new(regions))
ReplaceOutput::Updated(Sketch::new(self.surface().clone(), regions))
} else {
ReplaceOutput::Original(self.clone())
}
Expand Down
4 changes: 2 additions & 2 deletions crates/fj-core/src/operations/update/sketch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ impl UpdateSketch for Sketch {
{
let regions = regions.into_iter().map(|region| region.insert(core));
let regions = self.regions().iter().cloned().chain(regions);
Sketch::new(regions)
Sketch::new(self.surface().clone(), regions)
}

fn update_region<T, R>(
Expand All @@ -69,6 +69,6 @@ impl UpdateSketch for Sketch {
}),
)
.expect("Region not found");
Sketch::new(regions)
Sketch::new(self.surface().clone(), regions)
}
}
2 changes: 1 addition & 1 deletion crates/fj-core/src/topology/objects/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
topology::{Cycle, ObjectSet},
};

/// A single, continuous 2d region, may contain holes
/// 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
Expand Down
14 changes: 12 additions & 2 deletions crates/fj-core/src/topology/objects/sketch.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,32 @@
use crate::{
storage::Handle,
topology::{ObjectSet, Region},
topology::{ObjectSet, Region, Surface},
};

/// A 2-dimensional shape
#[derive(Clone, Debug)]
pub struct Sketch {
surface: Handle<Surface>,
regions: ObjectSet<Region>,
}

impl Sketch {
/// Construct an empty instance of `Sketch`
pub fn new(regions: impl IntoIterator<Item = Handle<Region>>) -> Self {
pub fn new(
surface: Handle<Surface>,
regions: impl IntoIterator<Item = Handle<Region>>,
) -> Self {
Self {
surface,
regions: regions.into_iter().collect(),
}
}

/// Access the surface of the sketch
pub fn surface(&self) -> &Handle<Surface> {
&self.surface
}

/// Access the regions of the sketch
pub fn regions(&self) -> &ObjectSet<Region> {
&self.regions
Expand Down
15 changes: 15 additions & 0 deletions crates/fj-core/src/topology/stores.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ impl Topology {
pub struct Surfaces {
store: Store<Surface>,

space_2d: Handle<Surface>,

xy_plane: Handle<Surface>,
xz_plane: Handle<Surface>,
yz_plane: Handle<Surface>,
Expand All @@ -66,6 +68,15 @@ impl Surfaces {
self.store.insert(handle, surface);
}

/// Access the surface representing 2D space
///
/// Every other surface is a 2D subspace within a 3D space. This surface is
/// special, in that it represents the 2D space which is not located in a 3D
/// space.
pub fn space_2d(&self) -> Handle<Surface> {
self.space_2d.clone()
}

/// Access the xy-plane
pub fn xy_plane(&self) -> Handle<Surface> {
self.xy_plane.clone()
Expand All @@ -86,6 +97,9 @@ impl Default for Surfaces {
fn default() -> Self {
let mut store: Store<Surface> = Store::new();

let space_2d = store.reserve();
store.insert(space_2d.clone(), Surface::new());

let xy_plane = store.reserve();
store.insert(xy_plane.clone(), Surface::new());

Expand All @@ -97,6 +111,7 @@ impl Default for Surfaces {

Self {
store,
space_2d,
xy_plane,
xz_plane,
yz_plane,
Expand Down
67 changes: 41 additions & 26 deletions crates/fj-core/src/validate/sketch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,14 +137,21 @@ mod tests {

let region = <Region as BuildRegion>::circle([0., 0.], 1., &mut core)
.insert(&mut core);
let valid_sketch = Sketch::new(vec![region.clone()]).insert(&mut core);
let valid_sketch = Sketch::new(
core.layers.topology.surfaces.space_2d(),
vec![region.clone()],
)
.insert(&mut core);
valid_sketch.validate_and_return_first_error(&core.layers.geometry)?;

let shared_cycle = region.exterior();
let invalid_sketch = Sketch::new(vec![
Region::new(shared_cycle.clone(), vec![]).insert(&mut core),
Region::new(shared_cycle.clone(), vec![]).insert(&mut core),
]);
let invalid_sketch = Sketch::new(
core.layers.topology.surfaces.space_2d(),
vec![
Region::new(shared_cycle.clone(), vec![]).insert(&mut core),
Region::new(shared_cycle.clone(), vec![]).insert(&mut core),
],
);
assert_contains_err!(
core,
invalid_sketch,
Expand All @@ -165,18 +172,24 @@ mod tests {
&mut core,
)
.insert(&mut core);
let valid_sketch = Sketch::new(vec![region.clone()]).insert(&mut core);
let valid_sketch = Sketch::new(
core.layers.topology.surfaces.space_2d(),
vec![region.clone()],
)
.insert(&mut core);
valid_sketch.validate_and_return_first_error(&core.layers.geometry)?;

let exterior = region.exterior();
let cloned_edges: Vec<_> =
exterior.half_edges().iter().cloned().collect();
let interior = Cycle::new(cloned_edges).insert(&mut core);

let invalid_sketch =
Sketch::new(vec![
let invalid_sketch = Sketch::new(
core.layers.topology.surfaces.space_2d(),
vec![
Region::new(exterior.clone(), vec![interior]).insert(&mut core)
]);
],
);
assert_contains_err!(
core,
invalid_sketch,
Expand All @@ -195,10 +208,10 @@ mod tests {
let valid_outer_circle = HalfEdge::circle([0., 0.], 1., &mut core);
let valid_exterior =
Cycle::new(vec![valid_outer_circle.clone()]).insert(&mut core);
let valid_sketch =
Sketch::new(vec![
Region::new(valid_exterior.clone(), vec![]).insert(&mut core)
]);
let valid_sketch = Sketch::new(
core.layers.topology.surfaces.space_2d(),
vec![Region::new(valid_exterior.clone(), vec![]).insert(&mut core)],
);
valid_sketch.validate_and_return_first_error(&core.layers.geometry)?;

let invalid_outer_circle = HalfEdge::from_sibling(
Expand All @@ -208,10 +221,12 @@ mod tests {
);
let invalid_exterior =
Cycle::new(vec![invalid_outer_circle.clone()]).insert(&mut core);
let invalid_sketch =
Sketch::new(vec![
let invalid_sketch = Sketch::new(
core.layers.topology.surfaces.space_2d(),
vec![
Region::new(invalid_exterior.clone(), vec![]).insert(&mut core)
]);
],
);
assert_contains_err!(
core,
invalid_sketch,
Expand All @@ -238,20 +253,20 @@ mod tests {

let valid_interior =
Cycle::new(vec![cw_inner_circle.clone()]).insert(&mut core);
let valid_sketch = Sketch::new(vec![Region::new(
exterior.clone(),
vec![valid_interior],
)
.insert(&mut core)]);
let valid_sketch = Sketch::new(
core.layers.topology.surfaces.space_2d(),
vec![Region::new(exterior.clone(), vec![valid_interior])
.insert(&mut core)],
);
valid_sketch.validate_and_return_first_error(&core.layers.geometry)?;

let invalid_interior =
Cycle::new(vec![inner_circle.clone()]).insert(&mut core);
let invalid_sketch = Sketch::new(vec![Region::new(
exterior.clone(),
vec![invalid_interior],
)
.insert(&mut core)]);
let invalid_sketch = Sketch::new(
core.layers.topology.surfaces.space_2d(),
vec![Region::new(exterior.clone(), vec![invalid_interior])
.insert(&mut core)],
);
assert_contains_err!(
core,
invalid_sketch,
Expand Down
2 changes: 1 addition & 1 deletion models/cuboid/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub fn model(size: impl Into<Vector<3>>, core: &mut fj::core::Core) -> Solid {
let bottom_surface = core.layers.topology.surfaces.xy_plane();
let sweep_path = Vector::from([Scalar::ZERO, Scalar::ZERO, z]);

Sketch::empty()
Sketch::empty(&core.layers.topology)
.add_regions(
[Region::polygon(
[
Expand Down
2 changes: 1 addition & 1 deletion models/spacer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub fn model(
let bottom_surface = core.layers.topology.surfaces.xy_plane();
let sweep_path = Vector::from([0., 0., height]);

Sketch::empty()
Sketch::empty(&core.layers.topology)
.add_regions(
[Region::circle(Point::origin(), outer, core).add_interiors(
[Cycle::circle(Point::origin(), inner, core).reverse(core)],
Expand Down
2 changes: 1 addition & 1 deletion models/star/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub fn model(
let bottom_surface = core.layers.topology.surfaces.xy_plane();
let sweep_path = Vector::from([0., 0., h]);

Sketch::empty()
Sketch::empty(&core.layers.topology)
.add_regions(
[Region::polygon(outer_points, core).add_interiors(
[Cycle::polygon(inner_points, core).reverse(core)],
Expand Down

0 comments on commit 73fd64f

Please sign in to comment.