Skip to content

Commit

Permalink
Merge pull request #591 from hannobraun/edge
Browse files Browse the repository at this point in the history
Add local representation of curve to `Edge`
  • Loading branch information
hannobraun authored May 16, 2022
2 parents 7891175 + 9726984 commit 9a51fa7
Show file tree
Hide file tree
Showing 10 changed files with 42 additions and 47 deletions.
6 changes: 3 additions & 3 deletions crates/fj-kernel/src/algorithms/sweep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ pub fn sweep_shape(

struct Relation {
vertices: HashMap<Handle<Vertex<3>>, Handle<Vertex<3>>>,
edges: HashMap<Handle<Edge>, Handle<Edge>>,
edges: HashMap<Handle<Edge<3>>, Handle<Edge<3>>>,
cycles: HashMap<Handle<Cycle>, Handle<Cycle>>,
}

Expand All @@ -248,7 +248,7 @@ impl Relation {

fn vertices_for_edge(
&self,
edge: &Handle<Edge>,
edge: &Handle<Edge<3>>,
) -> Option<[Handle<Vertex<3>>; 2]> {
edge.get().vertices.map(|vertices| {
vertices.map(|vertex| {
Expand All @@ -257,7 +257,7 @@ impl Relation {
})
}

fn edges_for_cycle(&self, cycle: &Handle<Cycle>) -> Vec<Handle<Edge>> {
fn edges_for_cycle(&self, cycle: &Handle<Cycle>) -> Vec<Handle<Edge<3>>> {
cycle
.get()
.edges
Expand Down
9 changes: 3 additions & 6 deletions crates/fj-kernel/src/shape/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ impl Shape {
/// Access iterator over all edges
///
/// The caller must not make any assumptions about the order of edges.
pub fn edges(&self) -> Iter<Edge> {
pub fn edges(&self) -> Iter<Edge<3>> {
self.stores.edges.iter()
}

Expand Down Expand Up @@ -229,10 +229,7 @@ mod tests {
assert!(shape.get_handle(&surface.get()).as_ref() == Some(&surface));

let vertex = Vertex::new(point);
let edge = Edge {
curve,
vertices: None,
};
let edge = Edge::new(curve, None);

assert!(shape.get_handle(&vertex).is_none());
assert!(shape.get_handle(&edge).is_none());
Expand Down Expand Up @@ -393,7 +390,7 @@ mod tests {
self.insert(Surface::xy_plane()).unwrap()
}

fn add_edge(&mut self) -> anyhow::Result<Handle<Edge>> {
fn add_edge(&mut self) -> anyhow::Result<Handle<Edge<3>>> {
let points = [(); 2].map(|()| {
let point = self.next_point;
self.next_point.x += Scalar::ONE;
Expand Down
11 changes: 11 additions & 0 deletions crates/fj-kernel/src/shape/local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,17 @@ impl<Local, Canonical: Object> LocalForm<Local, Canonical> {
}
}

impl<Canonical: Object> LocalForm<Canonical, Canonical> {
/// Construct a new instance of `LocalForm` without a local form
///
/// It's possible that an object's local and canonical forms are the same.
/// This is a convenience constructor that constructs a `LocalForm` instance
/// for such a situation.
pub fn canonical_only(canonical: Handle<Canonical>) -> Self {
Self::new(canonical.get(), canonical)
}
}

impl<Local, Canonical: Object> PartialEq for LocalForm<Local, Canonical>
where
Local: PartialEq,
Expand Down
4 changes: 2 additions & 2 deletions crates/fj-kernel/src/shape/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ impl private::Sealed for Curve<3> {}
impl private::Sealed for Surface {}

impl private::Sealed for Vertex<3> {}
impl private::Sealed for Edge {}
impl private::Sealed for Edge<3> {}
impl private::Sealed for Cycle {}
impl private::Sealed for Face {}

Expand All @@ -27,7 +27,7 @@ impl Object for Curve<3> {}
impl Object for Surface {}

impl Object for Vertex<3> {}
impl Object for Edge {}
impl Object for Edge<3> {}
impl Object for Cycle {}
impl Object for Face {}

Expand Down
2 changes: 1 addition & 1 deletion crates/fj-kernel/src/shape/stores.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ pub type Curves = Store<Curve<3>>;
pub type Surfaces = Store<Surface>;

pub type Vertices = Store<Vertex<3>>;
pub type Edges = Store<Edge>;
pub type Edges = Store<Edge<3>>;
pub type Cycles = Store<Cycle>;
pub type Faces = Store<Face>;

Expand Down
10 changes: 5 additions & 5 deletions crates/fj-kernel/src/shape/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ impl Validate for Vertex<3> {
}
}

impl Validate for Edge {
impl Validate for Edge<3> {
fn validate(
&self,
_: Scalar,
Expand All @@ -71,8 +71,8 @@ impl Validate for Edge {
let mut missing_curve = None;
let mut missing_vertices = HashSet::new();

if !stores.curves.contains(&self.curve) {
missing_curve = Some(self.curve.clone());
if !stores.curves.contains(self.curve.canonical()) {
missing_curve = Some(self.curve.canonical().clone());
}
for vertices in &self.vertices {
for vertex in vertices {
Expand Down Expand Up @@ -225,7 +225,7 @@ impl ValidationError {

/// Indicate whether validation found a missing edge
#[cfg(test)]
pub fn missing_edge(&self, edge: &Handle<Edge>) -> bool {
pub fn missing_edge(&self, edge: &Handle<Edge<3>>) -> bool {
if let Self::Structural(StructuralIssues { missing_edges, .. }) = self {
return missing_edges.contains(edge);
}
Expand Down Expand Up @@ -276,7 +276,7 @@ pub struct StructuralIssues {
pub missing_vertices: HashSet<Handle<Vertex<3>>>,

/// Missing edges found in cycle validation
pub missing_edges: HashSet<Handle<Edge>>,
pub missing_edges: HashSet<Handle<Edge<3>>>,

/// Missing surface found in face validation
pub missing_surface: Option<Handle<Surface>>,
Expand Down
11 changes: 4 additions & 7 deletions crates/fj-kernel/src/topology/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,13 @@ impl<'r> EdgeBuilder<'r> {
}

/// Build a circle from a radius
pub fn build_circle(self, radius: Scalar) -> ValidationResult<Edge> {
pub fn build_circle(self, radius: Scalar) -> ValidationResult<Edge<3>> {
let curve = self.shape.insert(Curve::Circle(Circle {
center: Point::origin(),
a: Vector::from([radius, Scalar::ZERO, Scalar::ZERO]),
b: Vector::from([Scalar::ZERO, radius, Scalar::ZERO]),
}))?;
let edge = self.shape.insert(Edge {
curve,
vertices: None,
})?;
let edge = self.shape.insert(Edge::new(curve, None))?;

Ok(edge)
}
Expand All @@ -65,7 +62,7 @@ impl<'r> EdgeBuilder<'r> {
pub fn build_line_segment_from_points(
self,
vertices: [impl Into<Point<3>>; 2],
) -> ValidationResult<Edge> {
) -> ValidationResult<Edge<3>> {
// Can be cleaned up with `try_map`, once that is stable:
// https://doc.rust-lang.org/std/primitive.array.html#method.try_map
let vertices = vertices
Expand All @@ -84,7 +81,7 @@ impl<'r> EdgeBuilder<'r> {
pub fn build_line_segment_from_vertices(
self,
vertices: [Handle<Vertex<3>>; 2],
) -> ValidationResult<Edge> {
) -> ValidationResult<Edge<3>> {
let curve = self.shape.insert(Curve::Line(Line::from_points(
vertices.clone().map(|vertex| vertex.get().point()),
)))?;
Expand Down
4 changes: 2 additions & 2 deletions crates/fj-kernel/src/topology/cycles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use super::{CycleBuilder, Edge};
#[derive(Clone, Debug, Eq, Ord, PartialOrd)]
pub struct Cycle {
/// The edges that make up the cycle
pub edges: Vec<Handle<Edge>>,
pub edges: Vec<Handle<Edge<3>>>,
}

impl Cycle {
Expand All @@ -35,7 +35,7 @@ impl Cycle {
///
/// This is a convenience method that saves the caller from dealing with the
/// [`Handle`]s.
pub fn edges(&self) -> impl Iterator<Item = Edge> + '_ {
pub fn edges(&self) -> impl Iterator<Item = Edge<3>> + '_ {
self.edges.iter().map(|handle| handle.get())
}
}
Expand Down
30 changes: 10 additions & 20 deletions crates/fj-kernel/src/topology/edges.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::hash::{Hash, Hasher};

use crate::{
geometry::Curve,
shape::{Handle, LocalForm, Shape},
Expand All @@ -19,14 +17,14 @@ use super::{vertices::Vertex, EdgeBuilder};
/// An edge that is part of a [`Shape`] must be structurally sound. That means
/// the curve and any vertices that it refers to, must be part of the same
/// shape.
#[derive(Clone, Debug, Eq, Ord, PartialOrd)]
pub struct Edge {
#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct Edge<const D: usize> {
/// Access the curve that defines the edge's geometry
///
/// The edge can be a segment of the curve that is bounded by two vertices,
/// or if the curve is continuous (i.e. connects to itself), the edge could
/// be defined by the whole curve, and have no bounding vertices.
pub curve: Handle<Curve<3>>,
pub curve: LocalForm<Curve<D>, Curve<3>>,

/// Access the vertices that bound the edge on the curve
///
Expand All @@ -35,7 +33,7 @@ pub struct Edge {
pub vertices: Option<[LocalForm<Vertex<1>, Vertex<3>>; 2]>,
}

impl Edge {
impl Edge<3> {
/// Construct an instance of `Edge`
///
/// # Implementation Note
Expand All @@ -60,9 +58,12 @@ impl Edge {
curve: Handle<Curve<3>>,
vertices: Option<[Handle<Vertex<3>>; 2]>,
) -> Self {
let curve = LocalForm::canonical_only(curve);

let vertices = vertices.map(|vertices| {
vertices.map(|canonical| {
let local = curve
.canonical()
.get()
.point_to_curve_coords(canonical.get().point())
.local();
Expand All @@ -78,13 +79,15 @@ impl Edge {
pub fn builder(shape: &mut Shape) -> EdgeBuilder {
EdgeBuilder::new(shape)
}
}

impl<const D: usize> Edge<D> {
/// Access the curve that the edge refers to
///
/// This is a convenience method that saves the caller from dealing with the
/// [`Handle`].
pub fn curve(&self) -> Curve<3> {
self.curve.get()
self.curve.canonical().get()
}

/// Access the vertices that the edge refers to
Expand All @@ -97,16 +100,3 @@ impl Edge {
.map(|[a, b]| [a.canonical().get(), b.canonical().get()])
}
}

impl PartialEq for Edge {
fn eq(&self, other: &Self) -> bool {
self.curve() == other.curve() && self.vertices == other.vertices
}
}

impl Hash for Edge {
fn hash<H: Hasher>(&self, state: &mut H) {
self.curve().hash(state);
self.vertices.hash(state);
}
}
2 changes: 1 addition & 1 deletion crates/fj-operations/src/group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ fn copy_shape(orig: Shape, target: &mut Shape) {
vertices.insert(vertex_orig, vertex);
}
for edge_orig in orig.edges() {
let curve = curves[&edge_orig.get().curve].clone();
let curve = curves[edge_orig.get().curve.canonical()].clone();
let vertices = edge_orig.get().vertices.as_ref().map(|vs| {
vs.clone()
.map(|vertex| vertices[vertex.canonical()].clone())
Expand Down

0 comments on commit 9a51fa7

Please sign in to comment.