use fj_math::{Point, Scalar, Vector};
use crate::{
objects::{Curve, GlobalCurve, Surface},
path::SurfacePath,
stores::{Handle, HandleWrapper, Stores},
};
#[derive(Clone, Debug, Default, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct PartialCurve {
pub path: Option<SurfacePath>,
pub surface: Option<Handle<Surface>>,
pub global_form: Option<HandleWrapper<GlobalCurve>>,
}
impl PartialCurve {
pub fn with_path(mut self, path: Option<SurfacePath>) -> Self {
if let Some(path) = path {
self.path = Some(path);
}
self
}
pub fn with_surface(mut self, surface: Option<Handle<Surface>>) -> Self {
if let Some(surface) = surface {
self.surface = Some(surface);
}
self
}
pub fn with_global_form(
mut self,
global_form: Option<impl Into<HandleWrapper<GlobalCurve>>>,
) -> Self {
if let Some(global_form) = global_form {
self.global_form = Some(global_form.into());
}
self
}
pub fn as_u_axis(self) -> Self {
let a = Point::origin();
let b = a + Vector::unit_u();
self.as_line_from_points([a, b])
}
pub fn as_v_axis(self) -> Self {
let a = Point::origin();
let b = a + Vector::unit_v();
self.as_line_from_points([a, b])
}
pub fn as_circle_from_radius(self, radius: impl Into<Scalar>) -> Self {
self.with_path(Some(SurfacePath::circle_from_radius(radius)))
}
pub fn as_line_from_points(self, points: [impl Into<Point<2>>; 2]) -> Self {
self.with_path(Some(SurfacePath::line_from_points(points)))
}
pub fn build(self, stores: &Stores) -> Handle<Curve> {
let path = self.path.expect("Can't build `Curve` without path");
let surface =
self.surface.expect("Can't build `Curve` without surface");
let global_form = self
.global_form
.unwrap_or_else(|| GlobalCurve::new(stores).into());
Curve::new(surface, path, global_form, stores)
}
}
impl From<&Handle<Curve>> for PartialCurve {
fn from(curve: &Handle<Curve>) -> Self {
Self {
path: Some(curve.path()),
surface: Some(curve.surface().clone()),
global_form: Some(curve.global_form().clone().into()),
}
}
}