diff --git a/crates/fj-interop/src/mesh.rs b/crates/fj-interop/src/mesh.rs index e92ab4a794..aeacd2997f 100644 --- a/crates/fj-interop/src/mesh.rs +++ b/crates/fj-interop/src/mesh.rs @@ -107,4 +107,12 @@ pub struct Triangle { } /// RGBA color -pub type Color = [u8; 4]; +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)] +pub struct Color(pub [u8; 4]); + +impl Default for Color { + fn default() -> Self { + // The default color is red. This is an arbitrary choice. + Self([255, 0, 0, 255]) + } +} diff --git a/crates/fj-kernel/src/algorithms/sweep.rs b/crates/fj-kernel/src/algorithms/sweep.rs index 86f9409b6d..6d89ab1977 100644 --- a/crates/fj-kernel/src/algorithms/sweep.rs +++ b/crates/fj-kernel/src/algorithms/sweep.rs @@ -1,3 +1,4 @@ +use fj_interop::mesh::Color; use fj_math::{Point, Scalar, Transform, Triangle, Vector}; use crate::{ @@ -16,7 +17,7 @@ pub fn sweep( source: Sketch, path: impl Into>, tolerance: Tolerance, - color: [u8; 4], + color: Color, ) -> Solid { let path = path.into(); @@ -98,7 +99,7 @@ fn create_non_continuous_side_face( path: Vector<3>, is_sweep_along_negative_direction: bool, vertices_bottom: [GlobalVertex; 2], - color: [u8; 4], + color: Color, target: &mut Vec, ) { let vertices = { @@ -168,7 +169,7 @@ fn create_continuous_side_face( edge: Edge, path: Vector<3>, tolerance: Tolerance, - color: [u8; 4], + color: Color, target: &mut Vec, ) { let translation = Transform::translation(path); @@ -198,6 +199,7 @@ fn create_continuous_side_face( #[cfg(test)] mod tests { + use fj_interop::mesh::Color; use fj_math::{Point, Scalar, Vector}; use crate::{ @@ -298,7 +300,7 @@ mod tests { let sketch = Sketch::from_faces([face]); let solid = - super::sweep(sketch, direction, tolerance, [255, 0, 0, 255]); + super::sweep(sketch, direction, tolerance, Color([255, 0, 0, 255])); let expected_vertices: Vec<_> = expected_vertices .into_iter() diff --git a/crates/fj-kernel/src/builder.rs b/crates/fj-kernel/src/builder.rs index 0d87441999..dff95dd347 100644 --- a/crates/fj-kernel/src/builder.rs +++ b/crates/fj-kernel/src/builder.rs @@ -1,5 +1,6 @@ //! Convenient API to build objects +use fj_interop::mesh::Color; use fj_math::Point; use crate::objects::{Cycle, Face, Surface}; @@ -10,7 +11,7 @@ pub struct FaceBuilder { surface: Surface, exterior: Option>>, interiors: Vec>>, - color: Option<[u8; 4]>, + color: Option, } impl FaceBuilder { @@ -51,7 +52,7 @@ impl FaceBuilder { } /// Define the color of the face - pub fn with_color(mut self, color: [u8; 4]) -> Self { + pub fn with_color(mut self, color: Color) -> Self { self.color = Some(color); self } @@ -72,7 +73,7 @@ impl FaceBuilder { interiors.push(cycle); } - let color = self.color.unwrap_or([255, 0, 0, 255]); + let color = self.color.unwrap_or_default(); Face::new(surface, exteriors, interiors, color) } diff --git a/crates/fj-kernel/src/objects/face.rs b/crates/fj-kernel/src/objects/face.rs index c9eaa6f801..bc4ed7a518 100644 --- a/crates/fj-kernel/src/objects/face.rs +++ b/crates/fj-kernel/src/objects/face.rs @@ -17,7 +17,7 @@ impl Face { surface: Surface, exteriors: impl IntoIterator, interiors: impl IntoIterator, - color: [u8; 4], + color: Color, ) -> Self { let exteriors = exteriors.into_iter().collect(); let interiors = interiors.into_iter().collect(); @@ -70,7 +70,7 @@ impl Face { } /// Access the color of the face - pub fn color(&self) -> [u8; 4] { + pub fn color(&self) -> Color { self.brep().color } @@ -110,7 +110,7 @@ struct BRep { surface: Surface, exteriors: Vec, interiors: Vec, - color: [u8; 4], + color: Color, } type TriRep = Vec<(Triangle<3>, Color)>; diff --git a/crates/fj-operations/src/difference_2d.rs b/crates/fj-operations/src/difference_2d.rs index 40f729c4d8..31fdf9bef9 100644 --- a/crates/fj-operations/src/difference_2d.rs +++ b/crates/fj-operations/src/difference_2d.rs @@ -1,4 +1,4 @@ -use fj_interop::debug::DebugInfo; +use fj_interop::{debug::DebugInfo, mesh::Color}; use fj_kernel::{ algorithms::Tolerance, iter::ObjectIters, @@ -70,7 +70,12 @@ impl Shape for fj::Difference2d { } } - faces.push(Face::new(*surface, exteriors, interiors, self.color())); + faces.push(Face::new( + *surface, + exteriors, + interiors, + Color(self.color()), + )); } let difference = Sketch::from_faces(faces); diff --git a/crates/fj-operations/src/sketch.rs b/crates/fj-operations/src/sketch.rs index 402d270e15..80d4e333ee 100644 --- a/crates/fj-operations/src/sketch.rs +++ b/crates/fj-operations/src/sketch.rs @@ -1,4 +1,4 @@ -use fj_interop::debug::DebugInfo; +use fj_interop::{debug::DebugInfo, mesh::Color}; use fj_kernel::{ algorithms::Tolerance, objects::{Cycle, Edge, Face, Sketch, Surface}, @@ -28,7 +28,7 @@ impl Shape for fj::Sketch { Edge::circle_from_radius(Scalar::from_f64(circle.radius())); let cycle = Cycle { edges: vec![edge] }; - Face::new(surface, vec![cycle], Vec::new(), self.color()) + Face::new(surface, vec![cycle], Vec::new(), Color(self.color())) } fj::Chain::PolyChain(poly_chain) => { let points = @@ -36,7 +36,7 @@ impl Shape for fj::Sketch { Face::builder(surface) .with_exterior_polygon(points) - .with_color(self.color()) + .with_color(Color(self.color())) .build() } }; diff --git a/crates/fj-operations/src/sweep.rs b/crates/fj-operations/src/sweep.rs index 7879a7ab1f..67f45964be 100644 --- a/crates/fj-operations/src/sweep.rs +++ b/crates/fj-operations/src/sweep.rs @@ -1,4 +1,4 @@ -use fj_interop::debug::DebugInfo; +use fj_interop::{debug::DebugInfo, mesh::Color}; use fj_kernel::{ algorithms::{sweep, Tolerance}, objects::Solid, @@ -22,7 +22,7 @@ impl Shape for fj::Sweep { let path = Vector::from(self.path()); let color = self.shape().color(); - let solid = sweep(sketch.into_inner(), path, tolerance, color); + let solid = sweep(sketch.into_inner(), path, tolerance, Color(color)); validate(solid, config) } diff --git a/crates/fj-viewer/src/graphics/vertices.rs b/crates/fj-viewer/src/graphics/vertices.rs index ef349145a5..ed1c7f49e0 100644 --- a/crates/fj-viewer/src/graphics/vertices.rs +++ b/crates/fj-viewer/src/graphics/vertices.rs @@ -92,7 +92,7 @@ impl From<&Mesh>> for Vertices { .map(|(vertex, normal, color)| Vertex { position: vertex.into(), normal: normal.into(), - color: color.map(|v| f32::from(v) / 255.0), + color: color.0.map(|v| f32::from(v) / 255.0), }) .collect();