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 edge;
mod face; mod face;
mod shell; mod shell;
mod solid;
mod surface; mod surface;
pub use self::{ pub use self::{
cycle::BuildCycle, cycle::BuildCycle,
edge::BuildHalfEdge, edge::BuildHalfEdge,
face::{BuildFace, Polygon}, face::{BuildFace, Polygon},
shell::{BuildShell, Tetrahedron}, shell::{BuildShell, TetrahedronShell},
solid::{BuildSolid, Tetrahedron},
surface::BuildSurface, surface::BuildSurface,
}; };

View File

@ -2,7 +2,9 @@ use fj_math::Point;
use crate::{ use crate::{
objects::{Face, Shell}, objects::{Face, Shell},
operations::{Insert, IsInsertedYes, JoinCycle, UpdateFace}, operations::{
Insert, IsInserted, IsInsertedNo, IsInsertedYes, JoinCycle, UpdateFace,
},
services::Services, services::Services,
}; };
@ -31,7 +33,7 @@ pub trait BuildShell {
fn tetrahedron( fn tetrahedron(
points: [impl Into<Point<3>>; 4], points: [impl Into<Point<3>>; 4],
services: &mut Services, services: &mut Services,
) -> Tetrahedron { ) -> TetrahedronShell {
let [a, b, c, d] = points.map(Into::into); let [a, b, c, d] = points.map(Into::into);
let abc = Face::triangle([a, b, c], services); let abc = Face::triangle([a, b, c], services);
@ -64,7 +66,7 @@ pub trait BuildShell {
let [abc, bad, dac, cbd] = triangles; let [abc, bad, dac, cbd] = triangles;
Tetrahedron { TetrahedronShell {
shell, shell,
abc, abc,
bad, bad,
@ -83,9 +85,9 @@ impl BuildShell for Shell {}
/// `d`, in the order in which they are passed. /// `d`, in the order in which they are passed.
/// ///
/// Returned by [`BuildShell::tetrahedron`]. /// Returned by [`BuildShell::tetrahedron`].
pub struct Tetrahedron { pub struct TetrahedronShell<I: IsInserted = IsInsertedNo> {
/// The shell that forms the tetrahedron /// The shell that forms the tetrahedron
pub shell: Shell, pub shell: I::T<Shell>,
/// The face formed by the points `a`, `b`, and `c`. /// The face formed by the points `a`, `b`, and `c`.
pub abc: Polygon<3, IsInsertedYes>, 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, storage::Handle,
}; };
use super::Polygon; use super::{Polygon, TetrahedronShell};
/// Insert an object into its respective store /// 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::{ pub use self::{
build::{ build::{
BuildCycle, BuildFace, BuildHalfEdge, BuildShell, BuildSurface, BuildCycle, BuildFace, BuildHalfEdge, BuildShell, BuildSolid,
Polygon, Tetrahedron, BuildSurface, Polygon, Tetrahedron, TetrahedronShell,
}, },
insert::{Insert, IsInserted, IsInsertedNo, IsInsertedYes}, insert::{Insert, IsInserted, IsInsertedNo, IsInsertedYes},
join::JoinCycle, join::JoinCycle,
update::{UpdateCycle, UpdateFace, UpdateHalfEdge, UpdateShell}, update::{
UpdateCycle, UpdateFace, UpdateHalfEdge, UpdateShell, UpdateSolid,
},
}; };

View File

@ -2,8 +2,9 @@ mod cycle;
mod edge; mod edge;
mod face; mod face;
mod shell; mod shell;
mod solid;
pub use self::{ pub use self::{
cycle::UpdateCycle, edge::UpdateHalfEdge, face::UpdateFace, 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(()) Ok(())
} }
#[test] #[test]
fn shell_not_watertight() -> anyhow::Result<()> { fn shell_not_watertight() -> anyhow::Result<()> {
let mut services = Services::new(); let mut services = Services::new();