Files
solidcraft-upstream/vendor/truck-geometry/src/errors.rs
T

191 lines
8.0 KiB
Rust

use thiserror::Error;
/// Error handler for [`Error`](./errors/enum.Error.html)
pub type Result<T> = std::result::Result<T, Error>;
/// Geometrical Errors
#[derive(Debug, PartialEq, Error)]
pub enum Error {
/// The following operations are failed if the knot vector has zero range.
/// * Creating `BSplineCurve` or `BSplineSurface`,
/// * Calculating bspline basis functions, or
/// * Normalizing the knot vector.
/// # Examples
/// ```
/// use truck_geometry::prelude::*;
/// use truck_geometry::errors::Error;
/// let mut knot_vec = KnotVec::from(vec![0.0, 0.0, 0.0, 0.0]);
/// assert_eq!(knot_vec.try_normalize(), Err(Error::ZeroRange));
/// assert_eq!(knot_vec.try_bspline_basis_functions(1, 0.0), Err(Error::ZeroRange));
///
/// let ctrl_pts = vec![Vector2::new(0.0, 0.0), Vector2::new(1.0, 1.0)];
/// assert!(matches!(BSplineCurve::try_new(knot_vec, ctrl_pts), Err(Error::ZeroRange)));
/// ```
#[error("This knot vector consists single value.")]
ZeroRange,
/// Fails concatting two knot vectors if there is a difference between the back knot of
/// the former knot vector and the front knot of the latter knot vector.
/// # Examples
/// ```
/// use truck_geometry::prelude::*;
/// use truck_geometry::errors::Error;
/// let mut knot_vec0 = KnotVec::from(vec![0.0, 0.0, 1.0, 1.0]);
/// let knot_vec1 = KnotVec::from(vec![2.0, 2.0, 3.0, 3.0]);
/// assert!(matches!(knot_vec0.try_concat(&knot_vec1, 1), Err(Error::DifferentBackFront(1.0, 2.0))));
/// ```
#[error("Cannot concat two knot vectors whose the back of the first and the front of the second are different.
the back of the first knot vector: {0}
the front of the second knot vector: {1}")]
DifferentBackFront(f64, f64),
/// If the knot vector is not clamped, then one cannot concat the vector with another knot vector.
/// # Examples
/// ```
/// use truck_geometry::prelude::*;
/// use truck_geometry::errors::Error;
/// let mut knot_vec0 = KnotVec::from(vec![0.0, 0.0, 1.0, 1.0]);
/// let knot_vec1 = KnotVec::from(vec![2.0, 2.0, 3.0, 3.0]);
/// assert!(matches!(knot_vec0.try_concat(&knot_vec1, 2), Err(Error::NotClampedKnotVector)));
/// ```
#[error("This knot vector is not clamped.")]
NotClampedKnotVector,
/// Creating a knot vector by `KnotVec::try_from()` is failed if the given vector is not sorted.
/// `<KnotVec as From<Vec<f64>>>::from()` does not panic by this error because sorts the given
/// vector before creating the knot vector. So, `KnotVec::try_from()` is more efficient than
/// `<KnotVec as From<Vec<f64>>>::from()`.
/// # Examples
/// ```
/// use truck_geometry::prelude::*;
/// use truck_geometry::errors::Error;
/// use std::convert::*;
///
/// assert!(matches!(KnotVec::try_from(vec![1.0, 3.0, 0.0, 2.0]), Err(Error::NotSortedVector)));
/// assert_eq!(
/// <KnotVec as From<Vec<f64>>>::from(vec![1.0, 3.0, 0.0, 2.0]),
/// KnotVec::try_from(vec![0.0, 1.0, 2.0, 3.0]).unwrap(),
/// );
/// ```
#[error("This knot vector is not sorted.")]
NotSortedVector,
/// The given degree is too large to calculate bspline basis functions.
/// # Examples
/// ```
/// use truck_geometry::prelude::*;
/// use truck_geometry::errors::Error;
///
/// // a knot vector with length = 4.
/// let knot_vec = KnotVec::from(vec![0.0, 0.0, 1.0, 1.0]);
/// assert!(matches!(
/// knot_vec.try_bspline_basis_functions(5, 0.5),
/// Err(Error::TooLargeDegree(4, 5)),
/// ));
/// ```
#[error(
"This knot vector is too short compared to the degree.
the length of knot_vec: {0}
the degree: {1}"
)]
TooLargeDegree(usize, usize),
/// The specified knot cannot be removed.
/// # Examples
/// ```
/// use truck_geometry::prelude::*;
/// use truck_geometry::errors::Error;
/// let knot_vec = KnotVec::bezier_knot(2);
/// let ctrl_pts = vec![Vector2::new(-1.0, 1.0), Vector2::new(0.0, -1.0), Vector2::new(1.0, 1.0)];
/// let mut bspcurve = BSplineCurve::new(knot_vec, ctrl_pts);
/// let org_curve = bspcurve.clone();
/// bspcurve.add_knot(0.5).add_knot(0.5).add_knot(0.25).add_knot(0.75);
/// assert!(bspcurve.try_remove_knot(3).is_ok());
/// assert!(matches!(bspcurve.try_remove_knot(2), Err(Error::CannotRemoveKnot(2))));
/// ```
#[error("The {0}th knot in this knot vector cannot be removed.")]
CannotRemoveKnot(usize),
/// Empty vector of points cannot construct B-spline.
/// # Examples
/// ```
/// use truck_geometry::prelude::*;
/// use truck_geometry::errors::Error;
///
/// let knot_vec = KnotVec::bezier_knot(2);
/// let ctrl_pts: Vec<Vector4> = Vec::new();
/// assert!(matches!(
/// BSplineCurve::try_new(knot_vec, ctrl_pts),
/// Err(Error::EmptyControlPoints),
/// ));
/// ```
#[error("The control point must not be empty.")]
EmptyControlPoints,
/// The knot vector of B-spline curves or B-spline surfaces must be longer than the corresponded
/// array of control points.
/// # Examples
/// ```
/// use truck_geometry::prelude::*;
/// use truck_geometry::errors::Error;
/// let knot_vec = KnotVec::from(vec![0.0, 1.0, 2.0]);
/// let ctrl_pts = vec![Vector2::new(0.0, 0.0), Vector2::new(0.0, 0.0), Vector2::new(0.0, 0.0), Vector2::new(0.0, 0.0)];
/// assert!(matches!(
/// BSplineCurve::try_new(knot_vec, ctrl_pts),
/// Err(Error::TooShortKnotVector(3, 4)),
/// ));
/// ```
#[error(
"The knot vector must be more than the control points.
the length of knot_vec: {0}
the number of control points: {1}"
)]
TooShortKnotVector(usize, usize),
/// The length of the given arrays of control points to create a B-spline surface is irregular.
/// # Examples
/// ```
/// use truck_geometry::prelude::*;
/// use truck_geometry::errors::Error;
/// let knot_vecs = (KnotVec::bezier_knot(2), KnotVec::bezier_knot(2));
/// let ctrl_pts = vec![
/// vec![Vector2::new(1.0, 2.0), Vector2::new(1.0, 2.0)], // length = 2
/// vec![Vector2::new(1.0, 2.0)] // length = 1
/// ];
/// assert!(matches!(
/// BSplineSurface::try_new(knot_vecs, ctrl_pts),
/// Err(Error::IrregularControlPoints),
/// ));
/// ```
#[error("The number of control points is irregular")]
IrregularControlPoints,
/// The vector of control points and the one of weights have different length.
/// # Examples
/// ```
/// use truck_geometry::prelude::*;
/// use truck_geometry::errors::Error;
/// let bspcurve = BSplineCurve::new(
/// KnotVec::bezier_knot(2),
/// vec![Point2::new(0.0, 1.0), Point2::new(2.0, 3.0), Point2::new(4.0, 5.0)],
/// );
/// let weights = vec![1.0, 2.0]; // less than control points
///
/// assert!(matches!(
/// NurbsCurve::<Vector3>::try_from_bspline_and_weights(bspcurve, weights),
/// Err(Error::DifferentLength),
/// ));
/// ```
#[error("The vector of control points and the one of weights have different length.")]
DifferentLength,
}
#[test]
#[rustfmt::skip]
fn print_messages() {
use std::io::Write;
let stderr = &mut std::io::stderr();
writeln!(stderr, "****** test of the expressions of error messages ******\n").unwrap();
writeln!(stderr, "{}\n", Error::ZeroRange).unwrap();
writeln!(stderr, "{}\n", Error::DifferentBackFront(0.0, 1.0)).unwrap();
writeln!(stderr, "{}\n", Error::NotClampedKnotVector).unwrap();
writeln!(stderr, "{}\n", Error::NotSortedVector).unwrap();
writeln!(stderr, "{}\n", Error::TooLargeDegree(1, 2)).unwrap();
writeln!(stderr, "{}\n", Error::CannotRemoveKnot(7)).unwrap();
writeln!(stderr, "{}\n", Error::EmptyControlPoints).unwrap();
writeln!(stderr, "{}\n", Error::TooShortKnotVector(1, 2)).unwrap();
writeln!(stderr, "{}\n", Error::IrregularControlPoints).unwrap();
writeln!(stderr, "*******************************************************").unwrap();
}