Merge pull request #377 from hannobraun/kernel

Extract `fj-kernel` from `fj-app`
This commit is contained in:
Hanno Braun 2022-03-17 18:06:14 +01:00 committed by GitHub
commit 761b1fd865
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 206 additions and 139 deletions

27
Cargo.lock generated
View File

@ -626,23 +626,19 @@ name = "fj-app"
version = "0.5.0" version = "0.5.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"approx 0.5.1",
"bytemuck", "bytemuck",
"clap", "clap",
"figment", "figment",
"fj", "fj",
"fj-debug", "fj-debug",
"fj-kernel",
"fj-math", "fj-math",
"futures", "futures",
"libloading", "libloading",
"map-macro",
"nalgebra", "nalgebra",
"notify", "notify",
"parking_lot 0.12.0",
"parry2d-f64",
"parry3d-f64", "parry3d-f64",
"serde", "serde",
"spade",
"thiserror", "thiserror",
"threemf", "threemf",
"tracing", "tracing",
@ -659,6 +655,23 @@ dependencies = [
"parry3d-f64", "parry3d-f64",
] ]
[[package]]
name = "fj-kernel"
version = "0.5.0"
dependencies = [
"anyhow",
"approx 0.5.1",
"fj-debug",
"fj-math",
"map-macro",
"nalgebra",
"parking_lot 0.12.0",
"parry2d-f64",
"parry3d-f64",
"spade",
"thiserror",
]
[[package]] [[package]]
name = "fj-math" name = "fj-math"
version = "0.5.0" version = "0.5.0"
@ -1129,9 +1142,9 @@ dependencies = [
[[package]] [[package]]
name = "map-macro" name = "map-macro"
version = "0.2.0" version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3dec3b229449b1a54bd96dc32108086263d6830624e576dc0e6c80e619a0130" checksum = "9d5b0858fc6e216d2d6222d661021d9b184550acd757fbd80a8f86224069422c"
[[package]] [[package]]
name = "matchers" name = "matchers"

View File

@ -4,6 +4,7 @@ members = [
"fj", "fj",
"fj-app", "fj-app",
"fj-debug", "fj-debug",
"fj-kernel",
"fj-math", "fj-math",
"models/cuboid", "models/cuboid",
@ -16,5 +17,6 @@ members = [
default-members = [ default-members = [
"fj-app", "fj-app",
"fj-debug", "fj-debug",
"fj-kernel",
"fj-math", "fj-math",
] ]

View File

@ -13,17 +13,12 @@ categories = ["mathematics", "rendering"]
[dependencies] [dependencies]
anyhow = "1.0.56" anyhow = "1.0.56"
approx = "0.5.1"
bytemuck = "1.8.0" bytemuck = "1.8.0"
futures = "0.3.21" futures = "0.3.21"
libloading = "0.7.2" libloading = "0.7.2"
map-macro = "0.2.0"
nalgebra = "0.30.0" nalgebra = "0.30.0"
notify = "5.0.0-pre.14" notify = "5.0.0-pre.14"
parking_lot = "0.12.0"
parry2d-f64 = "0.8.0"
parry3d-f64 = "0.8.0" parry3d-f64 = "0.8.0"
spade = "2.0.0"
thiserror = "1.0.30" thiserror = "1.0.30"
threemf = "0.2.0" threemf = "0.2.0"
tracing = "0.1.32" tracing = "0.1.32"
@ -47,6 +42,10 @@ path = "../fj"
version = "0.5.0" version = "0.5.0"
path = "../fj-debug" path = "../fj-debug"
[dependencies.fj-kernel]
version = "0.5.0"
path = "../fj-kernel"
[dependencies.fj-math] [dependencies.fj-math]
version = "0.5.0" version = "0.5.0"
path = "../fj-math" path = "../fj-math"

View File

@ -1,3 +0,0 @@
pub mod approximation;
pub mod sweep;
pub mod triangulation;

View File

@ -1,9 +0,0 @@
pub mod curves;
pub mod points;
pub mod surfaces;
pub use self::{
curves::{Circle, Curve, Line},
points::Point,
surfaces::Surface,
};

View File

@ -3,9 +3,9 @@ mod camera;
mod config; mod config;
mod graphics; mod graphics;
mod input; mod input;
mod kernel;
mod mesh; mod mesh;
mod model; mod model;
mod operations;
mod window; mod window;
use std::collections::HashSet; use std::collections::HashSet;
@ -30,9 +30,9 @@ use crate::{
camera::Camera, camera::Camera,
config::Config, config::Config,
graphics::{DrawConfig, Renderer}, graphics::{DrawConfig, Renderer},
kernel::shapes::ToShape as _,
mesh::MeshMaker, mesh::MeshMaker,
model::Model, model::Model,
operations::ToShape as _,
window::Window, window::Window,
}; };

View File

@ -1,11 +1,10 @@
use fj_debug::DebugInfo; use fj_debug::DebugInfo;
use fj_math::{Aabb, Point, Scalar}; use fj_kernel::{
use crate::kernel::{
geometry::Surface, geometry::Surface,
shape::Shape, shape::Shape,
topology::{edges::Cycle, faces::Face}, topology::{Cycle, Face},
}; };
use fj_math::{Aabb, Point, Scalar};
use super::ToShape; use super::ToShape;

View File

@ -1,16 +1,11 @@
use std::collections::HashMap; use std::collections::HashMap;
use fj_debug::DebugInfo; use fj_debug::DebugInfo;
use fj_math::{Aabb, Scalar}; use fj_kernel::{
use crate::kernel::{
shape::Shape, shape::Shape,
topology::{ topology::{Cycle, Edge, Face, Vertex},
edges::{Cycle, Edge},
faces::Face,
vertices::Vertex,
},
}; };
use fj_math::{Aabb, Scalar};
use super::ToShape; use super::ToShape;

View File

@ -1,16 +1,11 @@
use std::collections::HashMap; use std::collections::HashMap;
use fj_debug::DebugInfo; use fj_debug::DebugInfo;
use fj_math::{Aabb, Scalar}; use fj_kernel::{
use crate::kernel::{
shape::Shape, shape::Shape,
topology::{ topology::{Cycle, Edge, Face, Vertex},
edges::{Cycle, Edge},
faces::Face,
vertices::Vertex,
},
}; };
use fj_math::{Aabb, Scalar};
use super::ToShape; use super::ToShape;

View File

@ -6,10 +6,9 @@ pub mod sweep;
pub mod transform; pub mod transform;
use fj_debug::DebugInfo; use fj_debug::DebugInfo;
use fj_kernel::shape::Shape;
use fj_math::{Aabb, Scalar}; use fj_math::{Aabb, Scalar};
use super::shape::Shape;
/// Implemented by all shapes /// Implemented by all shapes
pub trait ToShape { pub trait ToShape {
/// Compute the boundary representation of the shape /// Compute the boundary representation of the shape

View File

@ -1,11 +1,10 @@
use fj_debug::DebugInfo; use fj_debug::DebugInfo;
use fj_math::{Aabb, Point, Scalar}; use fj_kernel::{
use crate::kernel::{
geometry::Surface, geometry::Surface,
shape::Shape, shape::Shape,
topology::{edges::Cycle, faces::Face, vertices::Vertex}, topology::{Cycle, Face, Vertex},
}; };
use fj_math::{Aabb, Point, Scalar};
use super::ToShape; use super::ToShape;

View File

@ -1,8 +1,7 @@
use fj_debug::DebugInfo; use fj_debug::DebugInfo;
use fj_kernel::{algorithms::sweep_shape, shape::Shape};
use fj_math::{Aabb, Scalar, Vector}; use fj_math::{Aabb, Scalar, Vector};
use crate::kernel::{algorithms::sweep::sweep_shape, shape::Shape};
use super::ToShape; use super::ToShape;
impl ToShape for fj::Sweep { impl ToShape for fj::Sweep {

View File

@ -1,9 +1,8 @@
use fj_debug::DebugInfo; use fj_debug::DebugInfo;
use fj_kernel::shape::Shape;
use fj_math::{Aabb, Scalar, Transform}; use fj_math::{Aabb, Scalar, Transform};
use parry3d_f64::math::Isometry; use parry3d_f64::math::Isometry;
use crate::kernel::shape::Shape;
use super::ToShape; use super::ToShape;
impl ToShape for fj::Transform { impl ToShape for fj::Transform {

31
fj-kernel/Cargo.toml Normal file
View File

@ -0,0 +1,31 @@
[package]
name = "fj-kernel"
version = "0.5.0"
edition = "2021"
description = "The world needs another CAD program."
readme = "../README.md"
repository = "https://github.com/hannobraun/fornjot"
license = "0BSD"
keywords = ["cad", "programmatic", "code-cad"]
categories = ["mathematics"]
[dependencies]
anyhow = "1.0.56"
approx = "0.5.1"
map-macro = "0.2.0"
nalgebra = "0.30.0"
parking_lot = "0.12.0"
parry2d-f64 = "0.8.0"
parry3d-f64 = "0.8.0"
spade = "2.0.0"
thiserror = "1.0.30"
[dependencies.fj-debug]
version = "0.5.0"
path = "../fj-debug"
[dependencies.fj-math]
version = "0.5.0"
path = "../fj-math"

View File

@ -2,11 +2,7 @@ use std::collections::HashSet;
use fj_math::{Point, Scalar, Segment}; use fj_math::{Point, Scalar, Segment};
use crate::kernel::topology::{ use crate::topology::{Cycle, Edge, Face, Vertex};
edges::{Cycle, Edge},
faces::Face,
vertices::Vertex,
};
/// An approximation of an edge, multiple edges, or a face /// An approximation of an edge, multiple edges, or a face
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
@ -134,10 +130,10 @@ mod tests {
use fj_math::{Point, Scalar, Segment}; use fj_math::{Point, Scalar, Segment};
use map_macro::set; use map_macro::set;
use crate::kernel::{ use crate::{
geometry::Surface, geometry::Surface,
shape::Shape, shape::Shape,
topology::{edges::Cycle, faces::Face, vertices::Vertex}, topology::{Cycle, Face, Vertex},
}; };
use super::{approximate_edge, Approximation}; use super::{approximate_edge, Approximation};

View File

@ -0,0 +1,13 @@
//! Collection of algorithms that are used by the kernel
//!
//! Algorithmic code is collected in this module, to keep other modules focused
//! on their respective purpose.
mod approximation;
mod sweep;
mod triangulation;
pub use self::{
approximation::Approximation, sweep::sweep_shape,
triangulation::triangulate,
};

View File

@ -2,14 +2,10 @@ use std::collections::HashMap;
use fj_math::{Scalar, Transform, Triangle, Vector}; use fj_math::{Scalar, Transform, Triangle, Vector};
use crate::kernel::{ use crate::{
geometry::{surfaces::Swept, Surface}, geometry::{Surface, SweptCurve},
shape::{Handle, Shape}, shape::{Handle, Shape},
topology::{ topology::{Cycle, Edge, Face, Vertex},
edges::{Cycle, Edge},
faces::Face,
vertices::Vertex,
},
}; };
use super::approximation::Approximation; use super::approximation::Approximation;
@ -236,11 +232,12 @@ pub fn sweep_shape(
let top_edge = let top_edge =
source_to_top.edges.get(edge_source).unwrap().clone(); source_to_top.edges.get(edge_source).unwrap().clone();
let surface = let surface = target.geometry().add_surface(
target.geometry().add_surface(Surface::Swept(Swept { Surface::SweptCurve(SweptCurve {
curve: bottom_edge.get().curve(), curve: bottom_edge.get().curve(),
path, path,
})); }),
);
let cycle = target let cycle = target
.topology() .topology()
@ -323,10 +320,10 @@ impl Relation {
mod tests { mod tests {
use fj_math::{Point, Scalar, Vector}; use fj_math::{Point, Scalar, Vector};
use crate::kernel::{ use crate::{
geometry::{surfaces::Swept, Surface}, geometry::{Surface, SweptCurve},
shape::{Handle, Shape}, shape::{Handle, Shape},
topology::{edges::Cycle, faces::Face, vertices::Vertex}, topology::{Cycle, Face, Vertex},
}; };
use super::sweep_shape; use super::sweep_shape;
@ -407,8 +404,8 @@ mod tests {
}) })
.unwrap(); .unwrap();
let surface = shape.geometry().add_surface(Surface::Swept( let surface = shape.geometry().add_surface(Surface::SweptCurve(
Swept::plane_from_points( SweptCurve::plane_from_points(
[a, b, c].map(|vertex| vertex.get().point()), [a, b, c].map(|vertex| vertex.get().point()),
), ),
)); ));

View File

@ -2,7 +2,7 @@ use fj_math::Scalar;
use parry2d_f64::utils::point_in_triangle::{corner_direction, Orientation}; use parry2d_f64::utils::point_in_triangle::{corner_direction, Orientation};
use spade::HasPosition; use spade::HasPosition;
use crate::kernel::geometry; use crate::geometry;
/// Create a Delaunay triangulation of all points /// Create a Delaunay triangulation of all points
pub fn triangulate( pub fn triangulate(

View File

@ -22,6 +22,7 @@ impl Circle {
self.center self.center
} }
/// Create a new instance that is transformed by `transform`
#[must_use] #[must_use]
pub fn transform(self, transform: &Transform) -> Self { pub fn transform(self, transform: &Transform) -> Self {
let radius = self.radius.to_xyz(); let radius = self.radius.to_xyz();
@ -75,6 +76,10 @@ impl Circle {
Vector::from([x, y, Scalar::ZERO]) Vector::from([x, y, Scalar::ZERO])
} }
/// Approximate the circle
///
/// `tolerance` specifies how much the approximation is allowed to deviate
/// from the circle.
pub fn approx(&self, tolerance: Scalar, out: &mut Vec<Point<3>>) { pub fn approx(&self, tolerance: Scalar, out: &mut Vec<Point<3>>) {
let radius = self.radius.magnitude(); let radius = self.radius.magnitude();

View File

@ -28,7 +28,7 @@ impl Line {
self.origin self.origin
} }
/// Transform the line /// Create a new instance that is transformed by `transform`
#[must_use] #[must_use]
pub fn transform(self, transform: &Transform) -> Self { pub fn transform(self, transform: &Transform) -> Self {
Self { Self {

View File

@ -1,10 +1,10 @@
mod circle; mod circle;
mod line; mod line;
use fj_math::{Point, Scalar, Transform, Vector};
pub use self::{circle::Circle, line::Line}; pub use self::{circle::Circle, line::Line};
use fj_math::{Point, Scalar, Transform, Vector};
/// A one-dimensional shape /// A one-dimensional shape
/// ///
/// The word "curve" is used as an umbrella term for all one-dimensional shapes, /// The word "curve" is used as an umbrella term for all one-dimensional shapes,
@ -32,6 +32,7 @@ impl Curve {
} }
} }
/// Create a new instance that is transformed by `transform`
#[must_use] #[must_use]
pub fn transform(self, transform: &Transform) -> Self { pub fn transform(self, transform: &Transform) -> Self {
match self { match self {

View File

@ -0,0 +1,16 @@
//! Geometry objects
//!
//! Simplifying a bit, geometry is responsible for where things are, but now how
//! they are related. The types in this module are referred to by the types in
//! [`crate::topology`], which are responsible for defining how objects are
//! related.
mod curves;
mod points;
mod surfaces;
pub use self::{
curves::{Circle, Curve, Line},
points::Point,
surfaces::{Surface, SweptCurve},
};

View File

@ -1,11 +1,11 @@
pub mod swept; pub mod swept;
pub use self::swept::Swept; pub use self::swept::SweptCurve;
use fj_math::{Point, Transform, Vector}; use fj_math::{Point, Transform, Vector};
use nalgebra::vector; use nalgebra::vector;
use crate::kernel::geometry; use crate::geometry;
use super::{Curve, Line}; use super::{Curve, Line};
@ -13,13 +13,13 @@ use super::{Curve, Line};
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)] #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub enum Surface { pub enum Surface {
/// A swept curve /// A swept curve
Swept(Swept), SweptCurve(SweptCurve),
} }
impl Surface { impl Surface {
/// Construct a `Surface` that represents the x-y plane /// Construct a `Surface` that represents the x-y plane
pub fn x_y_plane() -> Self { pub fn x_y_plane() -> Self {
Self::Swept(Swept { Self::SweptCurve(SweptCurve {
curve: Curve::Line(Line { curve: Curve::Line(Line {
origin: Point::origin(), origin: Point::origin(),
direction: vector![1., 0., 0.].into(), direction: vector![1., 0., 0.].into(),
@ -32,7 +32,9 @@ impl Surface {
#[must_use] #[must_use]
pub fn transform(self, transform: &Transform) -> Self { pub fn transform(self, transform: &Transform) -> Self {
match self { match self {
Self::Swept(surface) => Self::Swept(surface.transform(transform)), Self::SweptCurve(surface) => {
Self::SweptCurve(surface.transform(transform))
}
} }
} }
@ -42,7 +44,9 @@ impl Surface {
point_3d: Point<3>, point_3d: Point<3>,
) -> geometry::Point<2> { ) -> geometry::Point<2> {
let point_2d = match self { let point_2d = match self {
Self::Swept(surface) => surface.point_model_to_surface(&point_3d), Self::SweptCurve(surface) => {
surface.point_model_to_surface(&point_3d)
}
}; };
geometry::Point::new(point_2d, point_3d) geometry::Point::new(point_2d, point_3d)
@ -51,14 +55,16 @@ impl Surface {
/// Convert a point in surface coordinates to model coordinates /// Convert a point in surface coordinates to model coordinates
pub fn point_surface_to_model(&self, point: &Point<2>) -> Point<3> { pub fn point_surface_to_model(&self, point: &Point<2>) -> Point<3> {
match self { match self {
Self::Swept(surface) => surface.point_surface_to_model(point), Self::SweptCurve(surface) => surface.point_surface_to_model(point),
} }
} }
/// Convert a vector in surface coordinates to model coordinates /// Convert a vector in surface coordinates to model coordinates
pub fn vector_surface_to_model(&self, vector: &Vector<2>) -> Vector<3> { pub fn vector_surface_to_model(&self, vector: &Vector<2>) -> Vector<3> {
match self { match self {
Self::Swept(surface) => surface.vector_surface_to_model(vector), Self::SweptCurve(surface) => {
surface.vector_surface_to_model(vector)
}
} }
} }
} }

View File

@ -1,10 +1,10 @@
use fj_math::{Point, Transform, Vector}; use fj_math::{Point, Transform, Vector};
use crate::kernel::geometry::Curve; use crate::geometry::Curve;
/// A surface that was swept from a curve /// A surface that was swept from a curve
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)] #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct Swept { pub struct SweptCurve {
/// The curve that this surface was swept from /// The curve that this surface was swept from
pub curve: Curve, pub curve: Curve,
@ -12,11 +12,11 @@ pub struct Swept {
pub path: Vector<3>, pub path: Vector<3>,
} }
impl Swept { impl SweptCurve {
/// Construct a plane from 3 points /// Construct a plane from 3 points
#[cfg(test)] #[cfg(test)]
pub fn plane_from_points([a, b, c]: [Point<3>; 3]) -> Self { pub fn plane_from_points([a, b, c]: [Point<3>; 3]) -> Self {
use crate::kernel::geometry::Line; use crate::geometry::Line;
let curve = Curve::Line(Line::from_points([a, b])); let curve = Curve::Line(Line::from_points([a, b]));
let path = c - a; let path = c - a;
@ -57,13 +57,13 @@ mod tests {
use fj_math::{Point, Vector}; use fj_math::{Point, Vector};
use crate::kernel::geometry::{Curve, Line}; use crate::geometry::{Curve, Line};
use super::Swept; use super::SweptCurve;
#[test] #[test]
fn point_model_to_surface() { fn point_model_to_surface() {
let swept = Swept { let swept = SweptCurve {
curve: Curve::Line(Line { curve: Curve::Line(Line {
origin: Point::from([1., 0., 0.]), origin: Point::from([1., 0., 0.]),
direction: Vector::from([0., 2., 0.]), direction: Vector::from([0., 2., 0.]),
@ -76,7 +76,7 @@ mod tests {
verify(&swept, Point::from([1., 1.])); verify(&swept, Point::from([1., 1.]));
verify(&swept, Point::from([2., 3.])); verify(&swept, Point::from([2., 3.]));
fn verify(swept: &Swept, surface_point: Point<2>) { fn verify(swept: &SweptCurve, surface_point: Point<2>) {
let point = swept.point_surface_to_model(&surface_point); let point = swept.point_surface_to_model(&surface_point);
let result = swept.point_model_to_surface(&point); let result = swept.point_model_to_surface(&point);
@ -86,7 +86,7 @@ mod tests {
#[test] #[test]
fn point_surface_to_model() { fn point_surface_to_model() {
let swept = Swept { let swept = SweptCurve {
curve: Curve::Line(Line { curve: Curve::Line(Line {
origin: Point::from([1., 0., 0.]), origin: Point::from([1., 0., 0.]),
direction: Vector::from([0., 2., 0.]), direction: Vector::from([0., 2., 0.]),
@ -102,7 +102,7 @@ mod tests {
#[test] #[test]
fn vector_surface_to_model() { fn vector_surface_to_model() {
let swept = Swept { let swept = SweptCurve {
curve: Curve::Line(Line { curve: Curve::Line(Line {
origin: Point::from([1., 0., 0.]), origin: Point::from([1., 0., 0.]),
direction: Vector::from([0., 2., 0.]), direction: Vector::from([0., 2., 0.]),

View File

@ -76,8 +76,9 @@
//! on a per-shape basis. Forcing the user to deal with these issues up-front //! on a per-shape basis. Forcing the user to deal with these issues up-front
//! should lead to less work overall. //! should lead to less work overall.
#![deny(missing_docs)]
pub mod algorithms; pub mod algorithms;
pub mod geometry; pub mod geometry;
pub mod shape; pub mod shape;
pub mod shapes;
pub mod topology; pub mod topology;

View File

@ -1,8 +1,8 @@
use fj_math::{Point, Transform}; use fj_math::{Point, Transform};
use crate::kernel::{ use crate::{
geometry::{Curve, Surface}, geometry::{Curve, Surface},
topology::faces::Face, topology::Face,
}; };
use super::{ use super::{

View File

@ -5,6 +5,9 @@ use super::{
Store, Store,
}; };
/// An iterator over geometric or topological objects
///
/// Returned by various methods of the [`Shape`] API.
pub struct Iter<'r, T> { pub struct Iter<'r, T> {
inner: Inner<'r, T>, inner: Inner<'r, T>,
} }

View File

@ -1,10 +1,12 @@
pub mod geometry; //! The API used for creating and manipulating shapes
pub mod handle; //!
pub mod iter; //! See [`Shape`], which is the main entry point to this API.
pub mod topology;
pub mod validate;
use fj_math::{Point, Scalar}; mod geometry;
mod handle;
mod iter;
mod topology;
mod validate;
pub use self::{ pub use self::{
geometry::Geometry, geometry::Geometry,
@ -14,13 +16,11 @@ pub use self::{
validate::{ValidationError, ValidationResult}, validate::{ValidationError, ValidationResult},
}; };
use fj_math::{Point, Scalar};
use super::{ use super::{
geometry::{Curve, Surface}, geometry::{Curve, Surface},
topology::{ topology::{Cycle, Edge, Face, Vertex},
edges::{Cycle, Edge},
faces::Face,
vertices::Vertex,
},
}; };
use self::handle::Storage; use self::handle::Storage;
@ -109,6 +109,12 @@ impl Shape {
} }
} }
impl Default for Shape {
fn default() -> Self {
Self::new()
}
}
type Points = Store<Point<3>>; type Points = Store<Point<3>>;
type Curves = Store<Curve>; type Curves = Store<Curve>;
type Surfaces = Store<Surface>; type Surfaces = Store<Surface>;

View File

@ -3,13 +3,9 @@ use std::collections::HashSet;
use fj_debug::DebugInfo; use fj_debug::DebugInfo;
use fj_math::{Point, Scalar, Triangle, Vector}; use fj_math::{Point, Scalar, Triangle, Vector};
use crate::kernel::{ use crate::{
geometry::{Circle, Curve, Line}, geometry::{Circle, Curve, Line},
topology::{ topology::{Cycle, Edge, Face, Vertex},
edges::{Cycle, Edge},
faces::Face,
vertices::Vertex,
},
}; };
use super::{ use super::{
@ -243,6 +239,7 @@ impl Topology<'_> {
Iter::new(self.geometry.faces) Iter::new(self.geometry.faces)
} }
/// Triangulate the shape
pub fn triangles( pub fn triangles(
&self, &self,
tolerance: Scalar, tolerance: Scalar,
@ -261,14 +258,10 @@ mod tests {
use fj_math::{Point, Scalar}; use fj_math::{Point, Scalar};
use crate::kernel::{ use crate::{
geometry::{Curve, Line, Surface}, geometry::{Curve, Line, Surface},
shape::{handle::Handle, Shape, ValidationError}, shape::{handle::Handle, Shape, ValidationError},
topology::{ topology::{Cycle, Edge, Face, Vertex},
edges::{Cycle, Edge},
faces::Face,
vertices::Vertex,
},
}; };
const MIN_DISTANCE: f64 = 5e-7; const MIN_DISTANCE: f64 = 5e-7;

View File

@ -1,12 +1,8 @@
use std::collections::HashSet; use std::collections::HashSet;
use crate::kernel::{ use crate::{
geometry::{Curve, Surface}, geometry::{Curve, Surface},
topology::{ topology::{Cycle, Edge, Face, Vertex},
edges::{Cycle, Edge},
faces::Face,
vertices::Vertex,
},
}; };
use super::Handle; use super::Handle;

View File

@ -1,6 +1,6 @@
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
use crate::kernel::{geometry::Curve, shape::Handle}; use crate::{geometry::Curve, shape::Handle};
use super::vertices::Vertex; use super::vertices::Vertex;
@ -16,6 +16,7 @@ use super::vertices::Vertex;
/// equality of topological objects. /// equality of topological objects.
#[derive(Clone, Debug, Eq, Ord, PartialOrd)] #[derive(Clone, Debug, Eq, Ord, PartialOrd)]
pub struct Cycle { pub struct Cycle {
/// The edges that make up the cycle
pub edges: Vec<Handle<Edge>>, pub edges: Vec<Handle<Edge>>,
} }

View File

@ -8,8 +8,8 @@ use fj_math::{Aabb, Scalar, Segment, Triangle};
use parry2d_f64::query::{Ray as Ray2, RayCast as _}; use parry2d_f64::query::{Ray as Ray2, RayCast as _};
use parry3d_f64::query::Ray as Ray3; use parry3d_f64::query::Ray as Ray3;
use crate::kernel::{ use crate::{
algorithms::{approximation::Approximation, triangulation::triangulate}, algorithms::{triangulate, Approximation},
geometry::Surface, geometry::Surface,
shape::Handle, shape::Handle,
}; };
@ -43,6 +43,8 @@ pub enum Face {
/// It might be less error-prone to specify the edges in surface /// It might be less error-prone to specify the edges in surface
/// coordinates. /// coordinates.
cycles: Vec<Handle<Cycle>>, cycles: Vec<Handle<Cycle>>,
/// The color of the face
color: [u8; 4], color: [u8; 4],
}, },
@ -88,6 +90,7 @@ impl Face {
} }
} }
/// Triangulate the face
pub fn triangles( pub fn triangles(
&self, &self,
tolerance: Scalar, tolerance: Scalar,

View File

@ -1,5 +1,10 @@
//! Topological objects //! Topological objects
//! //!
//! Simplifying a bit, topology is responsible for defining how objects are
//! related, as opposed to geometry, which is responsible for where things are.
//!
//! The types in this module use the types from [`crate::geometry`].
//!
//! # Equality //! # Equality
//! //!
//! Equality of topological objects is defined in terms of the geometry they //! Equality of topological objects is defined in terms of the geometry they
@ -11,6 +16,12 @@
//! definition of identity. Two [`Handle`]s are only considered equal, if they //! definition of identity. Two [`Handle`]s are only considered equal, if they
//! refer to objects in the same memory location. //! refer to objects in the same memory location.
pub mod edges; mod edges;
pub mod faces; mod faces;
pub mod vertices; mod vertices;
pub use self::{
edges::{Cycle, Edge},
faces::Face,
vertices::Vertex,
};

View File

@ -2,7 +2,7 @@ use std::hash::Hash;
use fj_math::Point; use fj_math::Point;
use crate::kernel::shape::Handle; use crate::shape::Handle;
/// A vertex /// A vertex
/// ///
@ -19,6 +19,7 @@ use crate::kernel::shape::Handle;
/// equality of topological objects. /// equality of topological objects.
#[derive(Clone, Debug, Eq, Ord, PartialOrd)] #[derive(Clone, Debug, Eq, Ord, PartialOrd)]
pub struct Vertex { pub struct Vertex {
/// The point that defines the location of the vertex
pub point: Handle<Point<3>>, pub point: Handle<Point<3>>,
} }