Merge pull request #1815 from hannobraun/operations

Add API for building and updating `Solid`s
This commit is contained in:
Hanno Braun 2023-05-04 12:39:37 +02:00 committed by GitHub
commit 6fc68a996c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 94 additions and 11 deletions

View File

@ -2,12 +2,14 @@ mod cycle;
mod edge;
mod face;
mod shell;
mod solid;
mod surface;
pub use self::{
cycle::BuildCycle,
edge::BuildHalfEdge,
face::{BuildFace, Polygon},
shell::{BuildShell, Tetrahedron},
shell::{BuildShell, TetrahedronShell},
solid::{BuildSolid, Tetrahedron},
surface::BuildSurface,
};

View File

@ -2,7 +2,9 @@ use fj_math::Point;
use crate::{
objects::{Face, Shell},
operations::{Insert, IsInsertedYes, JoinCycle, UpdateFace},
operations::{
Insert, IsInserted, IsInsertedNo, IsInsertedYes, JoinCycle, UpdateFace,
},
services::Services,
};
@ -31,7 +33,7 @@ pub trait BuildShell {
fn tetrahedron(
points: [impl Into<Point<3>>; 4],
services: &mut Services,
) -> Tetrahedron {
) -> TetrahedronShell {
let [a, b, c, d] = points.map(Into::into);
let abc = Face::triangle([a, b, c], services);
@ -64,7 +66,7 @@ pub trait BuildShell {
let [abc, bad, dac, cbd] = triangles;
Tetrahedron {
TetrahedronShell {
shell,
abc,
bad,
@ -83,9 +85,9 @@ impl BuildShell for Shell {}
/// `d`, in the order in which they are passed.
///
/// Returned by [`BuildShell::tetrahedron`].
pub struct Tetrahedron {
pub struct TetrahedronShell<I: IsInserted = IsInsertedNo> {
/// The shell that forms the tetrahedron
pub shell: Shell,
pub shell: I::T<Shell>,
/// The face formed by the points `a`, `b`, and `c`.
pub abc: Polygon<3, IsInsertedYes>,

View File

@ -0,0 +1,44 @@
use fj_math::Point;
use crate::{
objects::{Shell, Solid},
operations::{
build::shell::BuildShell, Insert, IsInsertedYes, TetrahedronShell,
UpdateSolid,
},
services::Services,
};
/// Build a [`Solid`]
pub trait BuildSolid {
/// Build an empty solid
fn empty() -> Solid {
Solid::new([])
}
/// Build a tetrahedron from the provided points
///
/// See [`BuildShell::tetrahedron`] for more information.
fn tetrahedron(
points: [impl Into<Point<3>>; 4],
services: &mut Services,
) -> Tetrahedron {
let shell = Shell::tetrahedron(points, services).insert(services);
let solid = Solid::empty().add_shell(shell.shell.clone());
Tetrahedron { solid, shell }
}
}
impl BuildSolid for Solid {}
/// A tetrahedron
///
/// Returned by [`BuildSolid::tetrahedron`].
pub struct Tetrahedron {
/// The solid that forms the tetrahedron
pub solid: Solid,
/// The shell of the tetrahedron
pub shell: TetrahedronShell<IsInsertedYes>,
}

View File

@ -7,7 +7,7 @@ use crate::{
storage::Handle,
};
use super::Polygon;
use super::{Polygon, TetrahedronShell};
/// Insert an object into its respective store
///
@ -91,3 +91,17 @@ impl<const D: usize> Insert for Polygon<D, IsInsertedNo> {
}
}
}
impl Insert for TetrahedronShell<IsInsertedNo> {
type Inserted = TetrahedronShell<IsInsertedYes>;
fn insert(self, services: &mut Services) -> Self::Inserted {
TetrahedronShell {
shell: self.shell.insert(services),
abc: self.abc,
bad: self.bad,
dac: self.dac,
cbd: self.cbd,
}
}
}

View File

@ -7,10 +7,12 @@ mod update;
pub use self::{
build::{
BuildCycle, BuildFace, BuildHalfEdge, BuildShell, BuildSurface,
Polygon, Tetrahedron,
BuildCycle, BuildFace, BuildHalfEdge, BuildShell, BuildSolid,
BuildSurface, Polygon, Tetrahedron, TetrahedronShell,
},
insert::{Insert, IsInserted, IsInsertedNo, IsInsertedYes},
join::JoinCycle,
update::{UpdateCycle, UpdateFace, UpdateHalfEdge, UpdateShell},
update::{
UpdateCycle, UpdateFace, UpdateHalfEdge, UpdateShell, UpdateSolid,
},
};

View File

@ -2,8 +2,9 @@ mod cycle;
mod edge;
mod face;
mod shell;
mod solid;
pub use self::{
cycle::UpdateCycle, edge::UpdateHalfEdge, face::UpdateFace,
shell::UpdateShell,
shell::UpdateShell, solid::UpdateSolid,
};

View File

@ -0,0 +1,17 @@
use crate::{
objects::{Shell, Solid},
storage::Handle,
};
/// Update a [`Solid`]
pub trait UpdateSolid {
/// Add a shell to the solid
fn add_shell(&self, shell: Handle<Shell>) -> Solid;
}
impl UpdateSolid for Solid {
fn add_shell(&self, shell: Handle<Shell>) -> Solid {
let shells = self.shells().cloned().chain([shell]);
Solid::new(shells)
}
}

View File

@ -235,6 +235,7 @@ mod tests {
Ok(())
}
#[test]
fn shell_not_watertight() -> anyhow::Result<()> {
let mut services = Services::new();