Skip to content

Commit

Permalink
Merge pull request #343 from therealprof/coloring-support
Browse files Browse the repository at this point in the history
Coloring support
  • Loading branch information
hannobraun authored Mar 14, 2022
2 parents 178dfec + f788bdd commit 1c88b52
Show file tree
Hide file tree
Showing 17 changed files with 185 additions and 66 deletions.
18 changes: 6 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,18 +54,12 @@ pub extern "C" fn model(args: &HashMap<String, String>) -> fj::Shape {
.parse()
.unwrap();

let outer_edge = fj::Circle { radius: outer };
let inner_edge = fj::Circle { radius: inner };

let footprint = fj::Difference {
a: outer_edge.into(),
b: inner_edge.into(),
};

let spacer = fj::Sweep {
shape: footprint.into(),
length: height,
};
let outer_edge = fj::Circle::from_radius(outer);
let inner_edge = fj::Circle::from_radius(inner);

let footprint = fj::Difference2d::from_objects(outer_edge.into(), inner_edge.into());

let spacer = fj::Sweep::from_shape_and_length(footprint.into(), height);

spacer.into()
}
Expand Down
95 changes: 88 additions & 7 deletions fj/src/shape_2d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,60 @@ pub enum Shape2d {
Sketch(Sketch),
}

impl Shape2d {
/// Get the rendering color of the larger object in RGBA
pub fn color(&self) -> [u8; 4] {
match &self {
Shape2d::Circle(c) => c.color(),
Shape2d::Sketch(s) => s.color(),
Shape2d::Difference(d) => d.color(),
}
}
}

/// A circle
#[derive(Clone, Debug)]
#[repr(C)]
pub struct Circle {
/// The radius of the circle
pub radius: f64,
radius: f64,
// The color of the circle in RGBA
color: [u8; 4],
}

impl Circle {
/// Construct a new circle with a specific radius
pub fn from_radius(radius: f64) -> Self {
Self {
radius,
color: [255, 0, 0, 255],
}
}

pub fn radius(&self) -> f64 {
self.radius
}

/// Set the rendering color of the circle in RGBA
pub fn with_color(mut self, color: [u8; 4]) -> Self {
self.color = color;
self
}

/// Set the rendering color of the circle in RGBA
pub fn set_color(&mut self, color: [u8; 4]) {
self.color = color;
}

/// Get the rendering color of the circle in RGBA
pub fn color(&self) -> [u8; 4] {
self.color
}
}

impl From<Circle> for Shape {
fn from(shape: Circle) -> Self {
Self::Shape2d(Shape2d::Circle(shape))
Self::Shape2d(shape.into())
}
}

Expand All @@ -41,15 +84,34 @@ impl From<Circle> for Shape2d {
#[repr(C)]
pub struct Difference2d {
/// The original shape
pub a: Shape2d,
a: Shape2d,

/// The shape being subtracted
pub b: Shape2d,
b: Shape2d,
}

impl Difference2d {
pub fn from_objects(a: Shape2d, b: Shape2d) -> Self {
Self { a, b }
}

/// Get the rendering color of the larger object in RGBA
pub fn color(&self) -> [u8; 4] {
self.a.color()
}

pub fn a(&self) -> &Shape2d {
&self.a
}

pub fn b(&self) -> &Shape2d {
&self.b
}
}

impl From<Difference2d> for Shape {
fn from(shape: Difference2d) -> Self {
Self::Shape2d(Shape2d::Difference(Box::new(shape)))
Self::Shape2d(shape.into())
}
}

Expand All @@ -76,6 +138,8 @@ pub struct Sketch {
ptr: *mut [f64; 2],
length: usize,
capacity: usize,
// The color of the sketch in RGBA
color: [u8; 4],
}

impl Sketch {
Expand All @@ -94,6 +158,7 @@ impl Sketch {
ptr,
length,
capacity,
color: [255, 0, 0, 255],
}
}

Expand All @@ -117,17 +182,33 @@ impl Sketch {

ret
}

/// Set the rendering color of the sketch in RGBA
pub fn with_color(mut self, color: [u8; 4]) -> Self {
self.color = color;
self
}

/// Set the rendering color of the sketch in RGBA
pub fn set_color(&mut self, color: [u8; 4]) {
self.color = color;
}

/// Get the rendering color of the sketch in RGBA
pub fn color(&self) -> [u8; 4] {
self.color
}
}

impl From<Sketch> for Shape {
fn from(shape: Sketch) -> Self {
Self::Shape2d(Shape2d::Sketch(shape))
Self::Shape2d(shape.into())
}
}

impl From<Sketch> for Shape2d {
fn from(shape: Sketch) -> Self {
Self::Sketch(shape)
Shape2d::Sketch(shape)
}
}

Expand Down
24 changes: 21 additions & 3 deletions fj/src/shape_3d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,33 @@ impl From<Transform> for Shape3d {
#[repr(C)]
pub struct Sweep {
/// The 2-dimensional shape being swept
pub shape: Shape2d,
shape: Shape2d,

/// The length of the sweep
pub length: f64,
length: f64,
}

impl Sweep {
pub fn from_shape_and_length(shape: Shape2d, length: f64) -> Self {
Self { shape, length }
}

pub fn shape(&self) -> &Shape2d {
&self.shape
}

pub fn length(&self) -> f64 {
self.length
}

pub fn color(&self) -> [u8; 4] {
self.shape().color()
}
}

impl From<Sweep> for Shape {
fn from(shape: Sweep) -> Self {
Self::Shape3d(Shape3d::Sweep(shape))
Self::Shape3d(shape.into())
}
}

Expand Down
2 changes: 1 addition & 1 deletion fj/src/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ where
{
fn sweep(&self, length: f64) -> crate::Sweep {
let shape = self.clone().into();
crate::Sweep { shape, length }
crate::Sweep::from_shape_and_length(shape, length)
}
}

Expand Down
7 changes: 2 additions & 5 deletions models/cuboid/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,9 @@ pub extern "C" fn model(args: &HashMap<String, String>) -> fj::Shape {
[ x / 2., -y / 2.],
[ x / 2., y / 2.],
[-x / 2., y / 2.],
]);
]).with_color([100,255,0,200]);

let cuboid = fj::Sweep {
shape: rectangle.into(),
length: z,
};
let cuboid = fj::Sweep::from_shape_and_length(rectangle.into(), z);

cuboid.into()
}
18 changes: 7 additions & 11 deletions models/spacer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,20 @@ pub extern "C" fn model(args: &HashMap<String, String>) -> fj::Shape {
.unwrap_or(&"0.5".to_owned())
.parse()
.unwrap();
let height = args
let height: f64 = args
.get("height")
.unwrap_or(&"1.0".to_owned())
.parse()
.unwrap();

let outer_edge = fj::Circle { radius: outer };
let inner_edge = fj::Circle { radius: inner };
let outer_edge =
fj::Circle::from_radius(outer).with_color([0, 0, 255, 255]);
let inner_edge = fj::Circle::from_radius(inner);

let footprint = fj::Difference2d {
a: outer_edge.into(),
b: inner_edge.into(),
};
let footprint =
fj::Difference2d::from_objects(outer_edge.into(), inner_edge.into());

let spacer = fj::Sweep {
shape: footprint.into(),
length: height,
};
let spacer = fj::Sweep::from_shape_and_length(footprint.into(), height);

spacer.into()
}
12 changes: 3 additions & 9 deletions models/star/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,12 @@ pub extern "C" fn model(args: &HashMap<String, String>) -> fj::Shape {
inner.push([x / 2., y / 2.]);
}

let outer = fj::Sketch::from_points(outer);
let outer = fj::Sketch::from_points(outer).with_color ([0, 255, 0, 200]);
let inner = fj::Sketch::from_points(inner);

let footprint = fj::Difference2d {
a: outer.into(),
b: inner.into(),
};
let footprint = fj::Difference2d::from_objects(outer.into(), inner.into());

let star = fj::Sweep {
shape: footprint.into(),
length: h,
};
let star = fj::Sweep::from_shape_and_length(footprint.into(), h);

star.into()
}
1 change: 1 addition & 0 deletions src/kernel/algorithms/approximation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ mod tests {
let face = Face::Face {
surface,
cycles: vec![abcd],
color: [255, 0, 0, 255],
};

assert_eq!(
Expand Down
19 changes: 16 additions & 3 deletions src/kernel/algorithms/sweep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{
vertices::Vertex,
},
},
math::{Scalar, Transform, Vector},
math::{Scalar, Transform, Triangle, Vector},
};

use super::approximation::Approximation;
Expand All @@ -19,6 +19,7 @@ pub fn sweep_shape(
mut shape_orig: Shape,
path: Vector<3>,
tolerance: Scalar,
color: [u8; 4],
) -> Shape {
let mut shape = shape_orig.clone();

Expand Down Expand Up @@ -96,7 +97,11 @@ pub fn sweep_shape(

shape
.topology()
.add_face(Face::Face { surface, cycles })
.add_face(Face::Face {
surface,
cycles,
color,
})
.unwrap();
}

Expand All @@ -122,12 +127,18 @@ pub fn sweep_shape(
quads.push([v0, v1, v2, v3]);
}

let mut side_face = Vec::new();
let mut side_face: Vec<Triangle<3>> = Vec::new();
for [v0, v1, v2, v3] in quads {
side_face.push([v0, v1, v2].into());
side_face.push([v0, v2, v3].into());
}

// FIXME: We probably want to allow the use of custom colors for the "walls" of the swept
// object.
for s in side_face.iter_mut() {
s.set_color(color);
}

side_faces.push(Face::Triangles(side_face));
}

Expand Down Expand Up @@ -159,6 +170,7 @@ mod tests {
sketch.shape,
Vector::from([0., 0., 1.]),
Scalar::from_f64(0.),
[255, 0, 0, 255],
);

let bottom_face = sketch.face.get().clone();
Expand Down Expand Up @@ -234,6 +246,7 @@ mod tests {
let abc = Face::Face {
surface,
cycles: vec![cycles],
color: [255, 0, 0, 255],
};

let face = shape.topology().add_face(abc).unwrap();
Expand Down
7 changes: 6 additions & 1 deletion src/kernel/algorithms/transform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ pub fn transform_shape(mut original: Shape, transform: &Transform) -> Shape {

for face in original.topology().faces() {
let face = match face.get().clone() {
Face::Face { cycles, surface } => {
Face::Face {
cycles,
surface,
color,
} => {
let mut cycles_trans = Vec::new();

for cycle in cycles {
Expand Down Expand Up @@ -75,6 +79,7 @@ pub fn transform_shape(mut original: Shape, transform: &Transform) -> Shape {
Face::Face {
cycles: cycles_trans,
surface,
color,
}
}
Face::Triangles(mut triangles) => {
Expand Down
Loading

0 comments on commit 1c88b52

Please sign in to comment.