Skip to content

Commit

Permalink
Implement coherence validation of curves
Browse files Browse the repository at this point in the history
  • Loading branch information
hannobraun committed Sep 2, 2022
1 parent 95bb902 commit 8339ba9
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 2 deletions.
69 changes: 68 additions & 1 deletion crates/fj-kernel/src/algorithms/validate/coherence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,38 @@ use std::fmt;

use fj_math::{Point, Scalar};

use crate::objects::Vertex;
use crate::objects::{Curve, Vertex};

pub fn validate_curve(
curve: &Curve,
max_distance: impl Into<Scalar>,
) -> Result<(), CoherenceIssues> {
let max_distance = max_distance.into();

let points_curve = [-2., -1., 0., 1., 2.].map(|point| Point::from([point]));

for point_curve in points_curve {
let point_surface = curve.kind().point_from_curve_coords(point_curve);
let point_surface_as_global =
curve.surface().point_from_surface_coords(point_surface);
let point_global =
curve.global().kind().point_from_curve_coords(point_curve);

let distance = (point_surface_as_global - point_global).magnitude();

if distance > max_distance {
Err(CurveCoherenceMismatch {
point_curve,
point_surface,
point_surface_as_global,
point_global,
curve: *curve,
})?
}
}

Ok(())
}

pub fn validate_vertex(
vertex: &Vertex,
Expand Down Expand Up @@ -35,13 +66,49 @@ pub fn validate_vertex(
}

/// Issues in coherence validation
#[allow(clippy::large_enum_variant)]
#[derive(Debug, thiserror::Error)]
pub enum CoherenceIssues {
/// Mismatch between the surface and global forms of a curve
#[error("Mismatch between surface and global forms of curve")]
Curve(#[from] CurveCoherenceMismatch),

/// Mismatch between the local and global coordinates of a vertex
#[error("Mismatch between local and global coordinates of vertex")]
Vertex(#[from] VertexCoherenceMismatch),
}

/// A mismatch between the surface and global forms of a curve
///
/// Used in [`CoherenceIssues`].
#[derive(Debug, thiserror::Error)]
pub struct CurveCoherenceMismatch {
/// The curve coordinate for which a mismatch was found
pub point_curve: Point<1>,

/// The curve coordinate, converted to surface coordinates
pub point_surface: Point<2>,

/// The surface coordinates, converted to global coordinates
pub point_surface_as_global: Point<3>,

/// The curve coordinate, converted to global coordinates
pub point_global: Point<3>,

/// The incoherent curve
pub curve: Curve,
}

impl fmt::Display for CurveCoherenceMismatch {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"local: {:?} (converted to surface: {:?}; to global: {:?}), global: {:?},",
self.point_curve, self.point_surface, self.point_surface_as_global, self.point_global,
)
}
}

/// A mismatch between the local and global forms of a vertex
///
/// Used in [`CoherenceIssues`].
Expand Down
22 changes: 21 additions & 1 deletion crates/fj-kernel/src/algorithms/validate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ where
) -> Result<Validated<Self>, ValidationError> {
let mut global_vertices = HashSet::new();

for curve in self.curve_iter() {
coherence::validate_curve(curve, config.identical_max_distance)?;
}

for global_vertex in self.global_vertex_iter() {
uniqueness::validate_vertex(
global_vertex,
Expand Down Expand Up @@ -152,7 +156,7 @@ pub enum ValidationError {

#[cfg(test)]
mod tests {
use fj_math::{Point, Scalar};
use fj_math::{Line, Point, Scalar};

use crate::{
algorithms::validate::{Validate, ValidationConfig, ValidationError},
Expand All @@ -162,6 +166,22 @@ mod tests {
},
};

#[test]
fn coherence_curve() {
let line_global = Line::from_points([[0., 0., 0.], [1., 0., 0.]]);
let global_curve = GlobalCurve::from_kind(CurveKind::Line(line_global));

let line_surface = Line::from_points([[0., 0.], [2., 0.]]);
let curve = Curve::new(
Surface::xy_plane(),
CurveKind::Line(line_surface),
global_curve,
);

let result = curve.validate();
assert!(result.is_err());
}

#[test]
fn coherence_edge() {
let a = Point::from([0., 0., 0.]);
Expand Down

0 comments on commit 8339ba9

Please sign in to comment.