Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document convenient syntax for fj operations #1205

Merged
merged 7 commits into from
Oct 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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