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

Coloring support #343

Merged
merged 4 commits into from
Mar 14, 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
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