diff --git a/fj-app/src/camera.rs b/fj-app/src/camera.rs index 523e2a916..76bb8148a 100644 --- a/fj-app/src/camera.rs +++ b/fj-app/src/camera.rs @@ -1,6 +1,7 @@ use std::f64::consts::FRAC_PI_2; -use fj_math::{Aabb, Scalar, Triangle}; +use fj_interop::mesh::Triangle; +use fj_math::{Aabb, Scalar}; use nalgebra::{Point, TAffine, Transform, Translation, Vector}; use parry3d_f64::query::{Ray, RayCast as _}; use winit::dpi::PhysicalPosition; @@ -130,7 +131,7 @@ impl Camera { &self, window: &Window, cursor: Option>, - triangles: &[Triangle<3>], + triangles: &[Triangle], ) -> FocusPoint { let cursor = match cursor { Some(cursor) => cursor, @@ -147,10 +148,11 @@ impl Camera { let mut min_t = None; for triangle in triangles { - let t = - triangle - .to_parry() - .cast_local_ray(&ray, f64::INFINITY, true); + let t = triangle.inner.to_parry().cast_local_ray( + &ray, + f64::INFINITY, + true, + ); if let Some(t) = t { if t <= min_t.unwrap_or(t) { diff --git a/fj-app/src/graphics/vertices.rs b/fj-app/src/graphics/vertices.rs index c9baed132..aa0cf1529 100644 --- a/fj-app/src/graphics/vertices.rs +++ b/fj-app/src/graphics/vertices.rs @@ -1,9 +1,8 @@ use bytemuck::{Pod, Zeroable}; use fj_interop::{ debug::DebugInfo, - mesh::{Index, Mesh}, + mesh::{Index, Mesh, Triangle}, }; -use fj_math::Triangle; use nalgebra::{vector, Point}; #[derive(Debug)] @@ -67,15 +66,15 @@ impl Vertices { } } -impl From<&Vec>> for Vertices { - fn from(triangles: &Vec>) -> Self { +impl From<&Vec> for Vertices { + fn from(triangles: &Vec) -> Self { let mut mesh = Mesh::new(); for triangle in triangles { - let [a, b, c] = triangle.points(); + let [a, b, c] = triangle.inner.points(); let normal = (b - a).cross(&(c - a)).normalize(); - let color = triangle.color(); + let color = triangle.color; mesh.push((a, normal, color)); mesh.push((b, normal, color)); diff --git a/fj-app/src/input/handler.rs b/fj-app/src/input/handler.rs index d479f1c62..8d5d98cfc 100644 --- a/fj-app/src/input/handler.rs +++ b/fj-app/src/input/handler.rs @@ -1,6 +1,6 @@ use std::time::Instant; -use fj_math::Triangle; +use fj_interop::mesh::Triangle; use winit::{ dpi::PhysicalPosition, event::{ @@ -121,7 +121,7 @@ impl Handler { now: Instant, camera: &mut Camera, window: &Window, - triangles: &[Triangle<3>], + triangles: &[Triangle], ) { let focus_point = camera.focus_point(window, self.cursor, triangles); diff --git a/fj-app/src/main.rs b/fj-app/src/main.rs index fd61d6c71..e0841a77e 100644 --- a/fj-app/src/main.rs +++ b/fj-app/src/main.rs @@ -9,10 +9,10 @@ use std::path::PathBuf; use std::{collections::HashMap, time::Instant}; use fj_host::Model; -use fj_interop::debug::DebugInfo; -use fj_interop::mesh::Mesh; +use fj_interop::mesh::Triangle; +use fj_interop::{debug::DebugInfo, mesh::Mesh}; use fj_kernel::algorithms::triangulate; -use fj_math::{Aabb, Scalar, Triangle}; +use fj_math::{Aabb, Scalar}; use fj_operations::ToShape as _; use futures::executor::block_on; use tracing::{trace, warn}; @@ -88,7 +88,7 @@ fn main() -> anyhow::Result<()> { let mut mesh_maker = Mesh::new(); for triangle in shape.triangles { - for vertex in triangle.points() { + for vertex in triangle.inner.points() { mesh_maker.push(vertex); } } @@ -310,7 +310,7 @@ impl ShapeProcessor { struct ProcessedShape { aabb: Aabb<3>, - triangles: Vec>, + triangles: Vec, debug_info: DebugInfo, } diff --git a/fj-interop/src/mesh.rs b/fj-interop/src/mesh.rs index f77a5504c..c596f8da8 100644 --- a/fj-interop/src/mesh.rs +++ b/fj-interop/src/mesh.rs @@ -56,3 +56,26 @@ impl Default for Mesh { /// An index that refers to a vertex in a mesh pub type Index = u32; + +/// A triangle +/// +/// Extension of [`fj_math::Triangle`] that also includes a color. +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)] +pub struct Triangle { + /// The non-color part of the triangle + pub inner: fj_math::Triangle<3>, + + /// The color of the triangle + pub color: Color, +} + +impl Triangle { + /// Construct a new instance of `Triangle` + pub fn new(inner: impl Into>, color: Color) -> Self { + let inner = inner.into(); + Self { inner, color } + } +} + +/// RGBA color +pub type Color = [u8; 4]; diff --git a/fj-kernel/src/algorithms/sweep.rs b/fj-kernel/src/algorithms/sweep.rs index 47d268cfe..666c3fce9 100644 --- a/fj-kernel/src/algorithms/sweep.rs +++ b/fj-kernel/src/algorithms/sweep.rs @@ -1,6 +1,7 @@ use std::collections::HashMap; -use fj_math::{Scalar, Transform, Triangle, Vector}; +use fj_interop::mesh::Triangle; +use fj_math::{Scalar, Transform, Vector}; use crate::{ geometry::{Surface, SweptCurve}, @@ -149,16 +150,10 @@ pub fn sweep_shape( quads.push([v0, v1, v2, v3]); } - let mut side_face: Vec> = 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_face.push(Triangle::new([v0, v1, v2], color)); + side_face.push(Triangle::new([v0, v2, v3], color)); } target.insert(Face::Triangles(side_face)).unwrap(); diff --git a/fj-kernel/src/algorithms/triangulation/mod.rs b/fj-kernel/src/algorithms/triangulation/mod.rs index 992ca94a1..ccd678036 100644 --- a/fj-kernel/src/algorithms/triangulation/mod.rs +++ b/fj-kernel/src/algorithms/triangulation/mod.rs @@ -2,8 +2,8 @@ mod delaunay; mod polygon; mod ray; -use fj_interop::debug::DebugInfo; -use fj_math::{Scalar, Triangle}; +use fj_interop::{debug::DebugInfo, mesh::Triangle}; +use fj_math::Scalar; use crate::{shape::Shape, topology::Face}; @@ -15,7 +15,7 @@ use super::FaceApprox; pub fn triangulate( mut shape: Shape, tolerance: Scalar, - out: &mut Vec>, + out: &mut Vec, debug_info: &mut DebugInfo, ) { for face in shape.topology().faces() { @@ -62,10 +62,8 @@ pub fn triangulate( }); out.extend(triangles.into_iter().map(|triangle| { - let [a, b, c] = triangle.map(|point| point.canonical()); - let mut t = Triangle::from([a, b, c]); - t.set_color(*color); - t + let points = triangle.map(|point| point.canonical()); + Triangle::new(points, *color) })); } Face::Triangles(triangles) => out.extend(triangles), @@ -75,8 +73,8 @@ pub fn triangulate( #[cfg(test)] mod tests { - use fj_interop::debug::DebugInfo; - use fj_math::{Scalar, Triangle}; + use fj_interop::{debug::DebugInfo, mesh::Triangle}; + use fj_math::Scalar; use crate::{geometry::Surface, shape::Shape, topology::Face}; @@ -146,17 +144,22 @@ mod tests { super::triangulate(shape, tolerance, &mut triangles, &mut debug_info); for triangle in &mut triangles { - *triangle = triangle.normalize(); + *triangle = Triangle { + inner: triangle.inner.normalize(), + ..*triangle + }; } Triangles(triangles) } - struct Triangles(Vec>); + #[derive(Debug)] + struct Triangles(Vec); impl Triangles { - fn contains(&self, triangle: impl Into>) -> bool { - let triangle = triangle.into().normalize(); + fn contains(&self, triangle: impl Into>) -> bool { + let triangle = + Triangle::new(triangle.into().normalize(), [255, 0, 0, 255]); self.0.contains(&triangle) } } diff --git a/fj-kernel/src/shape/geometry.rs b/fj-kernel/src/shape/geometry.rs index 2e55dc7d6..2cdffa931 100644 --- a/fj-kernel/src/shape/geometry.rs +++ b/fj-kernel/src/shape/geometry.rs @@ -1,3 +1,4 @@ +use fj_interop::mesh::Triangle; use fj_math::{Point, Transform}; use crate::{ @@ -45,7 +46,10 @@ impl Geometry<'_> { use std::ops::DerefMut as _; if let Face::Triangles(triangles) = face.deref_mut() { for triangle in triangles { - *triangle = transform.transform_triangle(triangle); + *triangle = Triangle { + inner: transform.transform_triangle(&triangle.inner), + ..*triangle + }; } } }); diff --git a/fj-kernel/src/topology/faces.rs b/fj-kernel/src/topology/faces.rs index 66ff2b5b6..0e96c7aea 100644 --- a/fj-kernel/src/topology/faces.rs +++ b/fj-kernel/src/topology/faces.rs @@ -1,6 +1,6 @@ use std::hash::{Hash, Hasher}; -use fj_math::Triangle; +use fj_interop::mesh::Triangle; use crate::{ geometry::Surface, @@ -61,7 +61,7 @@ pub enum Face { /// The plan is to eventually represent faces as a geometric surface, /// bounded by edges. While the transition is being made, this variant is /// still required. - Triangles(Vec>), + Triangles(Vec), } impl Face {