Skip to content

Commit

Permalink
Merge pull request #1205 from hannobraun/fj
Browse files Browse the repository at this point in the history
Document convenient syntax for `fj` operations
  • Loading branch information
hannobraun authored Oct 11, 2022
2 parents 461f95b + 0c0c6c1 commit f4ff958
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 31 deletions.
4 changes: 1 addition & 3 deletions crates/fj/src/angle.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use std::f64::consts::{PI, TAU};

// One gon in radians
const GON_RAD: f64 = PI / 200.;

/// An angle
#[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Angle {
// The value of the angle in radians
rad: f64,
Expand Down
18 changes: 14 additions & 4 deletions crates/fj/src/group.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

use crate::Shape;

/// A group of two 3-dimensional shapes
///
/// A group is a collection of disjoint shapes. It is not a union, in that the
/// shapes in the group are not allowed to touch or overlap.
///
/// # Examples
///
/// Convenient syntax for this operation is available through [`crate::syntax`].
///
/// ``` rust
/// # let a = fj::Sketch::from_points(vec![[0., 0.], [1., 0.], [0., 1.]]);
/// # let b = fj::Sketch::from_points(vec![[2., 0.], [3., 0.], [2., 1.]]);
/// use fj::syntax::*;
///
/// // `a` and `b` can be anything that converts to `fj::Shape`
/// let group = a.group(&b);
/// ```
///
/// # Limitations
///
/// Whether the shapes in the group touch or overlap is not currently checked.
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
pub struct Group {
/// The first of the shapes
Expand Down
5 changes: 1 addition & 4 deletions crates/fj/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,11 @@ pub use self::{
angle::*, group::Group, shape_2d::*, sweep::Sweep, transform::Transform,
};
pub use fj_proc::*;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

/// A shape
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
#[allow(improper_ctypes)] // Box isn't FFI-safe
pub enum Shape {
/// A group of two 3-dimensional shapes
Group(Box<Group>),
Expand Down
46 changes: 34 additions & 12 deletions crates/fj/src/shape_2d.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
#[cfg(feature = "serde")]
use serde::{de, ser, Deserialize, Serialize};
use std::mem;
use std::sync::atomic;

use crate::Shape;

/// A 2-dimensional shape
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
pub enum Shape2d {
/// A difference between two shapes
Expand All @@ -28,8 +26,21 @@ impl Shape2d {
}

/// A difference between two shapes
///
/// # Examples
///
/// Convenient syntax for this operation is available through [`crate::syntax`].
///
/// ``` rust
/// # let a = fj::Sketch::from_points(vec![[0., 0.], [1., 0.], [0., 1.]]);
/// # let b = fj::Sketch::from_points(vec![[2., 0.], [3., 0.], [2., 1.]]);
/// use fj::syntax::*;
///
/// // `a` and `b` can be anything that converts to `fj::Shape2d`
/// let difference = a.difference(&b);
/// ```
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
pub struct Difference2d {
shapes: [Shape2d; 2],
Expand Down Expand Up @@ -73,8 +84,19 @@ impl From<Difference2d> for Shape2d {
/// Nothing about these edges is checked right now, but algorithms might assume
/// that the edges are non-overlapping. If you create a `Sketch` with
/// overlapping edges, you're on your own.
///
/// # Examples
///
/// Convenient syntax for this operation is available through [`crate::syntax`].
///
/// ``` rust
/// use fj::syntax::*;
///
/// // `a` and `b` can be anything that converts to `fj::Shape`
/// let sketch = [[0., 0.], [1., 0.], [0., 1.]].sketch();
/// ```
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
pub struct Sketch {
chain: Chain,
Expand Down Expand Up @@ -119,7 +141,7 @@ impl Sketch {

/// A chain of elements that is part of a [`Sketch`]
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
pub enum Chain {
/// The chain is a circle
Expand All @@ -131,7 +153,7 @@ pub enum Chain {

/// A circle that is part of a [`Sketch`]
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
pub struct Circle {
/// The radius of the circle
Expand Down Expand Up @@ -267,10 +289,10 @@ impl Drop for PolyChain {
unsafe impl Send for PolyChain {}

#[cfg(feature = "serde")]
impl ser::Serialize for PolyChain {
impl serde::ser::Serialize for PolyChain {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: ser::Serializer,
S: serde::ser::Serializer,
{
let serde_sketch = PolyChainSerde {
points: self.to_points(),
Expand All @@ -281,10 +303,10 @@ impl ser::Serialize for PolyChain {
}

#[cfg(feature = "serde")]
impl<'de> de::Deserialize<'de> for PolyChain {
impl<'de> serde::de::Deserialize<'de> for PolyChain {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: de::Deserializer<'de>,
D: serde::de::Deserializer<'de>,
{
PolyChainSerde::deserialize(deserializer)
.map(|serde_sketch| PolyChain::from_points(serde_sketch.points))
Expand All @@ -302,7 +324,7 @@ impl<'de> de::Deserialize<'de> for PolyChain {
/// [`PolyChain`]. If de/serialization turns out to be a bottleneck, a more
/// complete implementation will be required.
#[cfg(feature = "serde")]
#[derive(Serialize, Deserialize)]
#[derive(serde::Serialize, serde::Deserialize)]
#[serde(rename = "Polyline")]
struct PolyChainSerde {
points: Vec<[f64; 2]>,
Expand Down
17 changes: 13 additions & 4 deletions crates/fj/src/sweep.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

use crate::{Shape, Shape2d};

/// A sweep of a 2-dimensional shape along straight path
///
/// # Examples
///
/// Convenient syntax for this operation is available through [`crate::syntax`].
///
/// ``` rust
/// # let shape = fj::Sketch::from_points(vec![[0., 0.], [1., 0.], [0., 1.]]);
/// use fj::syntax::*;
///
/// // `shape` can be anything that converts to `fj::Shape2d`
/// let group = shape.sweep([0., 0., 1.]);
/// ```
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
pub struct Sweep {
/// The 2-dimensional shape being swept
Expand Down
18 changes: 14 additions & 4 deletions crates/fj/src/transform.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

use crate::{Angle, Shape};

/// A transformed 3-dimensional shape
///
/// # Examples
///
/// Convenient syntax for this operation is available through [`crate::syntax`].
///
/// ``` rust
/// # let shape = fj::Sketch::from_points(vec![[0., 0.], [1., 0.], [0., 1.]]);
/// use fj::syntax::*;
///
/// // `shape` can be anything that converts to `fj::Shape`
/// let rotated = shape.rotate([0., 0., 1.], fj::Angle::from_rev(0.5));
/// let translated = shape.translate([1., 2., 3.]);
/// ```
///
/// # Limitations
///
/// Transformations are currently limited to a rotation, followed by a
Expand All @@ -13,7 +23,7 @@ use crate::{Angle, Shape};
/// See issue:
/// <https://github.com/hannobraun/Fornjot/issues/101>
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(C)]
pub struct Transform {
/// The shape being transformed
Expand Down

0 comments on commit f4ff958

Please sign in to comment.