From 0faeddb23ebe3f91060b0ce865b7cb9bc66c6c29 Mon Sep 17 00:00:00 2001 From: Daniel Egger Date: Sat, 12 Mar 2022 18:10:55 +0100 Subject: [PATCH 1/4] Privatize circle radius and add a constructor/getter Signed-off-by: Daniel Egger --- README.md | 4 ++-- fj/src/shape_2d.rs | 12 +++++++++++- models/spacer/src/lib.rs | 4 ++-- src/kernel/shapes/circle.rs | 6 +++--- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index ab063e3f5..f37cb10d6 100644 --- a/README.md +++ b/README.md @@ -54,8 +54,8 @@ pub extern "C" fn model(args: &HashMap) -> fj::Shape { .parse() .unwrap(); - let outer_edge = fj::Circle { radius: outer }; - let inner_edge = fj::Circle { radius: inner }; + let outer_edge = fj::Circle::from_radius(outer); + let inner_edge = fj::Circle::from_radius(inner); let footprint = fj::Difference { a: outer_edge.into(), diff --git a/fj/src/shape_2d.rs b/fj/src/shape_2d.rs index 1e1dab5ba..866de5997 100644 --- a/fj/src/shape_2d.rs +++ b/fj/src/shape_2d.rs @@ -21,7 +21,17 @@ pub enum Shape2d { #[repr(C)] pub struct Circle { /// The radius of the circle - pub radius: f64, + radius: f64, +} + +impl Circle { + pub fn from_radius(radius: f64) -> Self { + Self { radius } + } + + pub fn radius(&self) -> f64 { + self.radius + } } impl From for Shape { diff --git a/models/spacer/src/lib.rs b/models/spacer/src/lib.rs index 3a84e8e98..aeac55fe0 100644 --- a/models/spacer/src/lib.rs +++ b/models/spacer/src/lib.rs @@ -18,8 +18,8 @@ pub extern "C" fn model(args: &HashMap) -> fj::Shape { .parse() .unwrap(); - let outer_edge = fj::Circle { radius: outer }; - let inner_edge = fj::Circle { radius: inner }; + let outer_edge = fj::Circle::from_radius(outer); + let inner_edge = fj::Circle::from_radius(inner); let footprint = fj::Difference2d { a: outer_edge.into(), diff --git a/src/kernel/shapes/circle.rs b/src/kernel/shapes/circle.rs index a94fbcfa8..e7a8b5bba 100644 --- a/src/kernel/shapes/circle.rs +++ b/src/kernel/shapes/circle.rs @@ -19,7 +19,7 @@ impl ToShape for fj::Circle { let edge = shape .topology() - .add_circle(Scalar::from_f64(self.radius)) + .add_circle(Scalar::from_f64(self.radius())) .unwrap(); shape .topology() @@ -38,8 +38,8 @@ impl ToShape for fj::Circle { fn bounding_volume(&self) -> Aabb<3> { Aabb { - min: Point::from([-self.radius, -self.radius, 0.0]), - max: Point::from([self.radius, self.radius, 0.0]), + min: Point::from([-self.radius(), -self.radius(), 0.0]), + max: Point::from([self.radius(), self.radius(), 0.0]), } } } From ba3e1d1974946bb5a7af38ac70c50cdf29f913a1 Mon Sep 17 00:00:00 2001 From: Daniel Egger Date: Sat, 12 Mar 2022 22:41:57 +0100 Subject: [PATCH 2/4] Make a and b fields of Difference2d private This adds access functions and fixes all users as well as README.md Signed-off-by: Daniel Egger --- README.md | 5 +---- fj/src/shape_2d.rs | 20 +++++++++++++++++--- models/spacer/src/lib.rs | 5 +---- models/star/src/lib.rs | 5 +---- src/kernel/shapes/difference_2d.rs | 4 ++-- 5 files changed, 22 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index f37cb10d6..e7cf59557 100644 --- a/README.md +++ b/README.md @@ -57,10 +57,7 @@ pub extern "C" fn model(args: &HashMap) -> fj::Shape { let outer_edge = fj::Circle::from_radius(outer); let inner_edge = fj::Circle::from_radius(inner); - let footprint = fj::Difference { - 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(), diff --git a/fj/src/shape_2d.rs b/fj/src/shape_2d.rs index 866de5997..ec10d6d0c 100644 --- a/fj/src/shape_2d.rs +++ b/fj/src/shape_2d.rs @@ -51,15 +51,29 @@ impl From 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 } + } + + pub fn a(&self) -> &Shape2d { + &self.a + } + + pub fn b(&self) -> &Shape2d { + &self.b + } } impl From for Shape { fn from(shape: Difference2d) -> Self { - Self::Shape2d(Shape2d::Difference(Box::new(shape))) + Self::Shape2d(shape.into()) } } diff --git a/models/spacer/src/lib.rs b/models/spacer/src/lib.rs index aeac55fe0..6c9e6d1bc 100644 --- a/models/spacer/src/lib.rs +++ b/models/spacer/src/lib.rs @@ -21,10 +21,7 @@ pub extern "C" fn model(args: &HashMap) -> fj::Shape { let outer_edge = fj::Circle::from_radius(outer); 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(), diff --git a/models/star/src/lib.rs b/models/star/src/lib.rs index 8bfb958ad..c8eeaa9f2 100644 --- a/models/star/src/lib.rs +++ b/models/star/src/lib.rs @@ -53,10 +53,7 @@ pub extern "C" fn model(args: &HashMap) -> fj::Shape { let outer = fj::Sketch::from_points(outer); 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(), diff --git a/src/kernel/shapes/difference_2d.rs b/src/kernel/shapes/difference_2d.rs index 556a91a95..81233fc0c 100644 --- a/src/kernel/shapes/difference_2d.rs +++ b/src/kernel/shapes/difference_2d.rs @@ -22,7 +22,7 @@ impl ToShape for fj::Difference2d { let mut shape = Shape::new(); - let [mut a, mut b] = [&self.a, &self.b] + let [mut a, mut b] = [&self.a(), &self.b()] .map(|shape| shape.to_shape(tolerance, debug_info)); for shape in [&mut a, &mut b] { @@ -105,6 +105,6 @@ impl ToShape for fj::Difference2d { // This is a conservative estimate of the bounding box: It's never going // to be bigger than the bounding box of the original shape that another // is being subtracted from. - self.a.bounding_volume() + self.a().bounding_volume() } } From 6ad163f8e917f49e2f3338586b4a9d39d4bc67c5 Mon Sep 17 00:00:00 2001 From: Daniel Egger Date: Sun, 13 Mar 2022 00:41:44 +0100 Subject: [PATCH 3/4] Privatize Sweep Signed-off-by: Daniel Egger --- README.md | 5 +---- fj/src/shape_3d.rs | 20 +++++++++++++++++--- fj/src/syntax.rs | 2 +- models/cuboid/src/lib.rs | 5 +---- models/spacer/src/lib.rs | 5 +---- models/star/src/lib.rs | 5 +---- src/kernel/shapes/sweep.rs | 8 ++++---- 7 files changed, 26 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index e7cf59557..4d084ad79 100644 --- a/README.md +++ b/README.md @@ -59,10 +59,7 @@ pub extern "C" fn model(args: &HashMap) -> fj::Shape { 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() } diff --git a/fj/src/shape_3d.rs b/fj/src/shape_3d.rs index c884b7db3..4d7d96f9e 100644 --- a/fj/src/shape_3d.rs +++ b/fj/src/shape_3d.rs @@ -62,15 +62,29 @@ impl From 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 + } } impl From for Shape { fn from(shape: Sweep) -> Self { - Self::Shape3d(Shape3d::Sweep(shape)) + Self::Shape3d(shape.into()) } } diff --git a/fj/src/syntax.rs b/fj/src/syntax.rs index 31e57d8a5..b62a693cf 100644 --- a/fj/src/syntax.rs +++ b/fj/src/syntax.rs @@ -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) } } diff --git a/models/cuboid/src/lib.rs b/models/cuboid/src/lib.rs index e7146d90e..73046c55b 100644 --- a/models/cuboid/src/lib.rs +++ b/models/cuboid/src/lib.rs @@ -14,10 +14,7 @@ pub extern "C" fn model(args: &HashMap) -> fj::Shape { [-x / 2., y / 2.], ]); - let cuboid = fj::Sweep { - shape: rectangle.into(), - length: z, - }; + let cuboid = fj::Sweep::from_shape_and_length(rectangle.into(), z); cuboid.into() } diff --git a/models/spacer/src/lib.rs b/models/spacer/src/lib.rs index 6c9e6d1bc..45d1a9af7 100644 --- a/models/spacer/src/lib.rs +++ b/models/spacer/src/lib.rs @@ -23,10 +23,7 @@ pub extern "C" fn model(args: &HashMap) -> fj::Shape { 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() } diff --git a/models/star/src/lib.rs b/models/star/src/lib.rs index c8eeaa9f2..919348320 100644 --- a/models/star/src/lib.rs +++ b/models/star/src/lib.rs @@ -55,10 +55,7 @@ pub extern "C" fn model(args: &HashMap) -> fj::Shape { 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() } diff --git a/src/kernel/shapes/sweep.rs b/src/kernel/shapes/sweep.rs index 9b2c06e01..d9834a208 100644 --- a/src/kernel/shapes/sweep.rs +++ b/src/kernel/shapes/sweep.rs @@ -9,15 +9,15 @@ use super::ToShape; impl ToShape for fj::Sweep { fn to_shape(&self, tolerance: Scalar, debug_info: &mut DebugInfo) -> Shape { sweep_shape( - self.shape.to_shape(tolerance, debug_info), - Vector::from([0., 0., self.length]), + self.shape().to_shape(tolerance, debug_info), + Vector::from([0., 0., self.length()]), tolerance, ) } fn bounding_volume(&self) -> Aabb<3> { - let mut aabb = self.shape.bounding_volume(); - aabb.max.z = self.length.into(); + let mut aabb = self.shape().bounding_volume(); + aabb.max.z = self.length().into(); aabb } } From f788bdd09d076375e648eaea5eb93f09a76e5959 Mon Sep 17 00:00:00 2001 From: Daniel Egger Date: Sun, 13 Mar 2022 13:44:44 +0100 Subject: [PATCH 4/4] Implement basic coloring support for shapes The examples have been extended to demonstrate the coloring of objects. A few bits and pieces are probably still missing or could be improved but let's look at those in another step. Closes #291 Signed-off-by: Daniel Egger --- fj/src/shape_2d.rs | 65 ++++++++++++++++++++++++-- fj/src/shape_3d.rs | 4 ++ models/cuboid/src/lib.rs | 2 +- models/spacer/src/lib.rs | 8 ++-- models/star/src/lib.rs | 2 +- src/kernel/algorithms/approximation.rs | 1 + src/kernel/algorithms/sweep.rs | 19 ++++++-- src/kernel/algorithms/transform.rs | 7 ++- src/kernel/shape/topology.rs | 7 ++- src/kernel/shapes/circle.rs | 6 ++- src/kernel/shapes/difference_2d.rs | 6 ++- src/kernel/shapes/sketch.rs | 1 + src/kernel/shapes/sweep.rs | 1 + src/kernel/shapes/union.rs | 2 + src/kernel/topology/faces.rs | 7 ++- 15 files changed, 120 insertions(+), 18 deletions(-) diff --git a/fj/src/shape_2d.rs b/fj/src/shape_2d.rs index ec10d6d0c..61b4de9dd 100644 --- a/fj/src/shape_2d.rs +++ b/fj/src/shape_2d.rs @@ -16,27 +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 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 } + 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 for Shape { fn from(shape: Circle) -> Self { - Self::Shape2d(Shape2d::Circle(shape)) + Self::Shape2d(shape.into()) } } @@ -62,6 +95,11 @@ impl Difference2d { 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 } @@ -100,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 { @@ -118,6 +158,7 @@ impl Sketch { ptr, length, capacity, + color: [255, 0, 0, 255], } } @@ -141,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 for Shape { fn from(shape: Sketch) -> Self { - Self::Shape2d(Shape2d::Sketch(shape)) + Self::Shape2d(shape.into()) } } impl From for Shape2d { fn from(shape: Sketch) -> Self { - Self::Sketch(shape) + Shape2d::Sketch(shape) } } diff --git a/fj/src/shape_3d.rs b/fj/src/shape_3d.rs index 4d7d96f9e..5c49d92e8 100644 --- a/fj/src/shape_3d.rs +++ b/fj/src/shape_3d.rs @@ -80,6 +80,10 @@ impl Sweep { pub fn length(&self) -> f64 { self.length } + + pub fn color(&self) -> [u8; 4] { + self.shape().color() + } } impl From for Shape { diff --git a/models/cuboid/src/lib.rs b/models/cuboid/src/lib.rs index 73046c55b..bf527c43a 100644 --- a/models/cuboid/src/lib.rs +++ b/models/cuboid/src/lib.rs @@ -12,7 +12,7 @@ pub extern "C" fn model(args: &HashMap) -> fj::Shape { [ x / 2., -y / 2.], [ x / 2., y / 2.], [-x / 2., y / 2.], - ]); + ]).with_color([100,255,0,200]); let cuboid = fj::Sweep::from_shape_and_length(rectangle.into(), z); diff --git a/models/spacer/src/lib.rs b/models/spacer/src/lib.rs index 45d1a9af7..46cdf27f1 100644 --- a/models/spacer/src/lib.rs +++ b/models/spacer/src/lib.rs @@ -12,16 +12,18 @@ pub extern "C" fn model(args: &HashMap) -> 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::from_radius(outer); + 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::from_objects(outer_edge.into(), inner_edge.into()); + let footprint = + fj::Difference2d::from_objects(outer_edge.into(), inner_edge.into()); let spacer = fj::Sweep::from_shape_and_length(footprint.into(), height); diff --git a/models/star/src/lib.rs b/models/star/src/lib.rs index 919348320..30b5b8ad4 100644 --- a/models/star/src/lib.rs +++ b/models/star/src/lib.rs @@ -50,7 +50,7 @@ pub extern "C" fn model(args: &HashMap) -> 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::from_objects(outer.into(), inner.into()); diff --git a/src/kernel/algorithms/approximation.rs b/src/kernel/algorithms/approximation.rs index 36f5cc5b1..f70569895 100644 --- a/src/kernel/algorithms/approximation.rs +++ b/src/kernel/algorithms/approximation.rs @@ -275,6 +275,7 @@ mod tests { let face = Face::Face { surface, cycles: vec![abcd], + color: [255, 0, 0, 255], }; assert_eq!( diff --git a/src/kernel/algorithms/sweep.rs b/src/kernel/algorithms/sweep.rs index fcddf959e..c13a3f222 100644 --- a/src/kernel/algorithms/sweep.rs +++ b/src/kernel/algorithms/sweep.rs @@ -9,7 +9,7 @@ use crate::{ vertices::Vertex, }, }, - math::{Scalar, Transform, Vector}, + math::{Scalar, Transform, Triangle, Vector}, }; use super::approximation::Approximation; @@ -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(); @@ -96,7 +97,11 @@ pub fn sweep_shape( shape .topology() - .add_face(Face::Face { surface, cycles }) + .add_face(Face::Face { + surface, + cycles, + color, + }) .unwrap(); } @@ -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> = 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)); } @@ -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(); @@ -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(); diff --git a/src/kernel/algorithms/transform.rs b/src/kernel/algorithms/transform.rs index b09d7cc22..8d82f8d35 100644 --- a/src/kernel/algorithms/transform.rs +++ b/src/kernel/algorithms/transform.rs @@ -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 { @@ -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) => { diff --git a/src/kernel/shape/topology.rs b/src/kernel/shape/topology.rs index 41fb5532a..50230ba1c 100644 --- a/src/kernel/shape/topology.rs +++ b/src/kernel/shape/topology.rs @@ -190,7 +190,10 @@ impl Topology<'_> { /// cycles it refers to are part of the shape). Returns an error, if that is /// not the case. pub fn add_face(&mut self, face: Face) -> ValidationResult { - if let Face::Face { surface, cycles } = &face { + if let Face::Face { + surface, cycles, .. + } = &face + { let mut missing_surface = None; let mut missing_cycles = HashSet::new(); @@ -371,6 +374,7 @@ mod tests { .add_face(Face::Face { surface: surface.clone(), cycles: vec![cycle.clone()], + color: [255, 0, 0, 255], }) .unwrap_err(); assert!(err.missing_surface(&surface)); @@ -383,6 +387,7 @@ mod tests { shape.topology().add_face(Face::Face { surface, cycles: vec![cycle], + color: [255, 0, 0, 255], })?; Ok(()) diff --git a/src/kernel/shapes/circle.rs b/src/kernel/shapes/circle.rs index e7a8b5bba..a3a107f4c 100644 --- a/src/kernel/shapes/circle.rs +++ b/src/kernel/shapes/circle.rs @@ -30,7 +30,11 @@ impl ToShape for fj::Circle { let surface = shape.geometry().add_surface(Surface::x_y_plane()); shape .topology() - .add_face(Face::Face { cycles, surface }) + .add_face(Face::Face { + cycles, + surface, + color: self.color(), + }) .unwrap(); shape diff --git a/src/kernel/shapes/difference_2d.rs b/src/kernel/shapes/difference_2d.rs index 81233fc0c..ae2ee5bf1 100644 --- a/src/kernel/shapes/difference_2d.rs +++ b/src/kernel/shapes/difference_2d.rs @@ -95,7 +95,11 @@ impl ToShape for fj::Difference2d { shape .topology() - .add_face(Face::Face { cycles, surface }) + .add_face(Face::Face { + cycles, + surface, + color: self.color(), + }) .unwrap(); shape diff --git a/src/kernel/shapes/sketch.rs b/src/kernel/shapes/sketch.rs index 915b4d2c2..b92d74bfb 100644 --- a/src/kernel/shapes/sketch.rs +++ b/src/kernel/shapes/sketch.rs @@ -49,6 +49,7 @@ impl ToShape for fj::Sketch { let face = Face::Face { cycles: shape.topology().cycles().collect(), surface, + color: self.color(), }; shape.topology().add_face(face).unwrap(); diff --git a/src/kernel/shapes/sweep.rs b/src/kernel/shapes/sweep.rs index d9834a208..9ba88eb63 100644 --- a/src/kernel/shapes/sweep.rs +++ b/src/kernel/shapes/sweep.rs @@ -12,6 +12,7 @@ impl ToShape for fj::Sweep { self.shape().to_shape(tolerance, debug_info), Vector::from([0., 0., self.length()]), tolerance, + self.color(), ) } diff --git a/src/kernel/shapes/union.rs b/src/kernel/shapes/union.rs index a7066b06f..c3bf57040 100644 --- a/src/kernel/shapes/union.rs +++ b/src/kernel/shapes/union.rs @@ -103,6 +103,7 @@ fn copy_shape(mut orig: Shape, target: &mut Shape) { Face::Face { surface, cycles: cs, + color, } => { target .topology() @@ -112,6 +113,7 @@ fn copy_shape(mut orig: Shape, target: &mut Shape) { .iter() .map(|cycle| cycles[cycle].clone()) .collect(), + color: *color, }) .unwrap(); } diff --git a/src/kernel/topology/faces.rs b/src/kernel/topology/faces.rs index f3e451cae..8d5814dfb 100644 --- a/src/kernel/topology/faces.rs +++ b/src/kernel/topology/faces.rs @@ -47,6 +47,7 @@ pub enum Face { /// It might be less error-prone to specify the edges in surface /// coordinates. cycles: Vec>, + color: [u8; 4], }, /// The triangles of the face @@ -98,7 +99,7 @@ impl Face { debug_info: &mut DebugInfo, ) { match self { - Self::Face { surface, .. } => { + Self::Face { surface, color, .. } => { let approx = Approximation::for_face(self, tolerance); let points: Vec<_> = approx @@ -223,7 +224,9 @@ impl Face { out.extend(triangles.into_iter().map(|triangle| { let [a, b, c] = triangle.map(|point| point.canonical()); - Triangle::from([a, b, c]) + let mut t = Triangle::from([a, b, c]); + t.set_color(*color); + t })); } Self::Triangles(triangles) => out.extend(triangles),