Skip to content

Commit

Permalink
Merge pull request #36 from mattatz/develop
Browse files Browse the repository at this point in the history
0.1.39
  • Loading branch information
mattatz authored Dec 17, 2024
2 parents 917dd0c + 9c4efb5 commit 649017f
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 2 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "curvo"
version = "0.1.38"
version = "0.1.39"
authors = ["Masatatsu Nakamura <masatatsu.nakamura@gmail.com"]
edition = "2021"
keywords = ["nurbs", "modeling", "graphics", "3d"]
Expand Down
8 changes: 8 additions & 0 deletions src/surface/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,10 @@
pub mod nurbs_surface;
pub use nurbs_surface::*;

/// The direction to flip the surface.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FlipDirection {
U,
V,
UV,
}
59 changes: 59 additions & 0 deletions src/surface/nurbs_surface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ use crate::{
SurfaceClosestParameterNewton, SurfaceClosestParameterProblem,
};

use super::FlipDirection;

/// NURBS surface representation
/// by generics, it can be used for 2D or 3D curves with f32 or f64 scalar types
#[derive(Clone, Debug)]
Expand Down Expand Up @@ -88,6 +90,11 @@ where
self.v_knots.domain(self.v_degree)
}

/// Get the u and v domain of the knot vector by degree
pub fn knots_domain(&self) -> ((T, T), (T, T)) {
(self.u_knots_domain(), self.v_knots_domain())
}

pub fn control_points(&self) -> &Vec<Vec<OPoint<T, D>>> {
&self.control_points
}
Expand Down Expand Up @@ -450,6 +457,58 @@ where
skl
}

/// Flip the surface in u or v direction
/// # Example
/// ```
/// use curvo::prelude::*;
/// use nalgebra::{Point3, Vector3};
/// use approx::assert_relative_eq;
/// let sphere = NurbsSurface3D::try_sphere(&Point3::origin(), &Vector3::x(), &Vector3::y(), 1.0).unwrap();
/// let (ud, vd) = sphere.knots_domain();
/// let p0 = sphere.point_at(ud.0, vd.0);
///
/// let u_flipped = sphere.flip(FlipDirection::U);
/// let (u_flipped_ud, u_flipped_vd) = u_flipped.knots_domain();
/// let p1 = u_flipped.point_at(u_flipped_ud.1, u_flipped_vd.0);
///
/// let v_flipped = sphere.flip(FlipDirection::V);
/// let (v_flipped_ud, v_flipped_vd) = v_flipped.knots_domain();
/// let p2 = v_flipped.point_at(v_flipped_ud.0, v_flipped_vd.1);
/// assert_relative_eq!(p0, p2, epsilon = 1e-8);
///
/// let uv_flipped = sphere.flip(FlipDirection::UV);
/// let (uv_flipped_ud, uv_flipped_vd) = uv_flipped.knots_domain();
/// let p3 = uv_flipped.point_at(uv_flipped_ud.1, uv_flipped_vd.1);
/// assert_relative_eq!(p0, p3, epsilon = 1e-8);
/// ```
pub fn flip(&self, direction: FlipDirection) -> Self {
let mut flipped = self.clone();

// flip in u direction
match direction {
FlipDirection::U | FlipDirection::UV => {
flipped.control_points = flipped.control_points.iter().rev().cloned().collect();
flipped.u_knots = flipped.u_knots.inverse();
}
_ => {}
}

// flip in v direction
match direction {
FlipDirection::V | FlipDirection::UV => {
flipped.control_points = flipped
.control_points
.iter()
.map(|row| row.iter().rev().cloned().collect())
.collect();
flipped.v_knots = flipped.v_knots.inverse();
}
_ => {}
}

flipped
}

/// Extrude a NURBS curve to create a NURBS surface
pub fn extrude(
profile: &NurbsCurve<T, D>,
Expand Down

0 comments on commit 649017f

Please sign in to comment.