Skip to content

Commit

Permalink
Merge pull request #1949 from hannobraun/queries
Browse files Browse the repository at this point in the history
Add infrastructure for non-trivial object queries
  • Loading branch information
hannobraun authored Jul 18, 2023
2 parents 3745941 + 75aba86 commit 5d1d399
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 3 deletions.
19 changes: 19 additions & 0 deletions crates/fj-core/src/geometry/bounding_vertices.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use crate::{
objects::Vertex,
storage::{Handle, HandleWrapper},
};

/// The bounding vertices of an edge
#[derive(Eq, PartialEq)]
pub struct BoundingVertices {
/// The bounding vertices
pub inner: [HandleWrapper<Vertex>; 2],
}

impl From<[Handle<Vertex>; 2]> for BoundingVertices {
fn from(vertices: [Handle<Vertex>; 2]) -> Self {
Self {
inner: vertices.map(Into::into),
}
}
}
2 changes: 2 additions & 0 deletions crates/fj-core/src/geometry/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
//! Types that are tied to objects, but aren't objects themselves
mod boundary;
mod bounding_vertices;
mod path;
mod surface;

pub use self::{
boundary::BoundaryOnCurve,
bounding_vertices::BoundingVertices,
path::{GlobalPath, SurfacePath},
surface::SurfaceGeometry,
};
1 change: 1 addition & 0 deletions crates/fj-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ pub mod algorithms;
pub mod geometry;
pub mod objects;
pub mod operations;
pub mod queries;
pub mod services;
pub mod storage;
pub mod validate;
4 changes: 1 addition & 3 deletions crates/fj-core/src/objects/kinds/cycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,7 @@ impl Cycle {

/// Access the half-edge after the provided one
///
/// # Panics
///
/// Panics, if the provided half-edge is not part of this cycle.
/// Returns `None`, if the provided `HalfEdge` is not part of the cycle.
pub fn half_edge_after(
&self,
half_edge: &Handle<HalfEdge>,
Expand Down
79 changes: 79 additions & 0 deletions crates/fj-core/src/queries.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//! Queries about objects
//!
//! Objects have methods that provide access to anything that the object itself
//! has direct access to. However, not all potentially interesting information
//! can be accessed that way. An example are the bounding vertices of an edge:
//! `HalfEdge` only stores its starting vertex, so you need a `Cycle` to get
//! both vertices.
//!
//! This module provides traits express such non-trivial queries, and implements
//! them for various objects that have the information to answer the query.
use crate::{
geometry::BoundingVertices,
objects::{Cycle, Face, HalfEdge, Region, Shell},
storage::Handle,
};

/// Determine the bounding vertices of an edge
pub trait BoundingVerticesOfEdge {
/// Determine the bounding vertices of an edge
///
/// Returns `None`, if the provided edge is not part of the object this
/// method is called on.
fn bounding_vertices_of_edge(
&self,
edge: &Handle<HalfEdge>,
) -> Option<BoundingVertices>;
}

impl BoundingVerticesOfEdge for Cycle {
fn bounding_vertices_of_edge(
&self,
edge: &Handle<HalfEdge>,
) -> Option<BoundingVertices> {
let start = edge.start_vertex().clone();
let end = self.half_edge_after(edge)?.start_vertex().clone();

Some(BoundingVertices::from([start, end]))
}
}

impl BoundingVerticesOfEdge for Region {
fn bounding_vertices_of_edge(
&self,
edge: &Handle<HalfEdge>,
) -> Option<BoundingVertices> {
for cycle in self.all_cycles() {
if let Some(vertices) = cycle.bounding_vertices_of_edge(edge) {
return Some(vertices);
}
}

None
}
}

impl BoundingVerticesOfEdge for Face {
fn bounding_vertices_of_edge(
&self,
edge: &Handle<HalfEdge>,
) -> Option<BoundingVertices> {
self.region().bounding_vertices_of_edge(edge)
}
}

impl BoundingVerticesOfEdge for Shell {
fn bounding_vertices_of_edge(
&self,
edge: &Handle<HalfEdge>,
) -> Option<BoundingVertices> {
for face in self.faces() {
if let Some(vertices) = face.bounding_vertices_of_edge(edge) {
return Some(vertices);
}
}

None
}
}

0 comments on commit 5d1d399

Please sign in to comment.