mirror of
https://github.com/hannobraun/Fornjot
synced 2025-08-11 11:46:05 +00:00
Merge pull request #457 from hannobraun/triangle
Add `fj_interop::mesh::Triangle`
This commit is contained in:
commit
e24a66456f
@ -1,6 +1,7 @@
|
|||||||
use std::f64::consts::FRAC_PI_2;
|
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 nalgebra::{Point, TAffine, Transform, Translation, Vector};
|
||||||
use parry3d_f64::query::{Ray, RayCast as _};
|
use parry3d_f64::query::{Ray, RayCast as _};
|
||||||
use winit::dpi::PhysicalPosition;
|
use winit::dpi::PhysicalPosition;
|
||||||
@ -130,7 +131,7 @@ impl Camera {
|
|||||||
&self,
|
&self,
|
||||||
window: &Window,
|
window: &Window,
|
||||||
cursor: Option<PhysicalPosition<f64>>,
|
cursor: Option<PhysicalPosition<f64>>,
|
||||||
triangles: &[Triangle<3>],
|
triangles: &[Triangle],
|
||||||
) -> FocusPoint {
|
) -> FocusPoint {
|
||||||
let cursor = match cursor {
|
let cursor = match cursor {
|
||||||
Some(cursor) => cursor,
|
Some(cursor) => cursor,
|
||||||
@ -147,10 +148,11 @@ impl Camera {
|
|||||||
let mut min_t = None;
|
let mut min_t = None;
|
||||||
|
|
||||||
for triangle in triangles {
|
for triangle in triangles {
|
||||||
let t =
|
let t = triangle.inner.to_parry().cast_local_ray(
|
||||||
triangle
|
&ray,
|
||||||
.to_parry()
|
f64::INFINITY,
|
||||||
.cast_local_ray(&ray, f64::INFINITY, true);
|
true,
|
||||||
|
);
|
||||||
|
|
||||||
if let Some(t) = t {
|
if let Some(t) = t {
|
||||||
if t <= min_t.unwrap_or(t) {
|
if t <= min_t.unwrap_or(t) {
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
use bytemuck::{Pod, Zeroable};
|
use bytemuck::{Pod, Zeroable};
|
||||||
use fj_interop::{
|
use fj_interop::{
|
||||||
debug::DebugInfo,
|
debug::DebugInfo,
|
||||||
mesh::{Index, Mesh},
|
mesh::{Index, Mesh, Triangle},
|
||||||
};
|
};
|
||||||
use fj_math::Triangle;
|
|
||||||
use nalgebra::{vector, Point};
|
use nalgebra::{vector, Point};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -67,15 +66,15 @@ impl Vertices {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&Vec<Triangle<3>>> for Vertices {
|
impl From<&Vec<Triangle>> for Vertices {
|
||||||
fn from(triangles: &Vec<Triangle<3>>) -> Self {
|
fn from(triangles: &Vec<Triangle>) -> Self {
|
||||||
let mut mesh = Mesh::new();
|
let mut mesh = Mesh::new();
|
||||||
|
|
||||||
for triangle in triangles {
|
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 normal = (b - a).cross(&(c - a)).normalize();
|
||||||
let color = triangle.color();
|
let color = triangle.color;
|
||||||
|
|
||||||
mesh.push((a, normal, color));
|
mesh.push((a, normal, color));
|
||||||
mesh.push((b, normal, color));
|
mesh.push((b, normal, color));
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
use fj_math::Triangle;
|
use fj_interop::mesh::Triangle;
|
||||||
use winit::{
|
use winit::{
|
||||||
dpi::PhysicalPosition,
|
dpi::PhysicalPosition,
|
||||||
event::{
|
event::{
|
||||||
@ -121,7 +121,7 @@ impl Handler {
|
|||||||
now: Instant,
|
now: Instant,
|
||||||
camera: &mut Camera,
|
camera: &mut Camera,
|
||||||
window: &Window,
|
window: &Window,
|
||||||
triangles: &[Triangle<3>],
|
triangles: &[Triangle],
|
||||||
) {
|
) {
|
||||||
let focus_point = camera.focus_point(window, self.cursor, triangles);
|
let focus_point = camera.focus_point(window, self.cursor, triangles);
|
||||||
|
|
||||||
|
@ -9,10 +9,10 @@ use std::path::PathBuf;
|
|||||||
use std::{collections::HashMap, time::Instant};
|
use std::{collections::HashMap, time::Instant};
|
||||||
|
|
||||||
use fj_host::Model;
|
use fj_host::Model;
|
||||||
use fj_interop::debug::DebugInfo;
|
use fj_interop::mesh::Triangle;
|
||||||
use fj_interop::mesh::Mesh;
|
use fj_interop::{debug::DebugInfo, mesh::Mesh};
|
||||||
use fj_kernel::algorithms::triangulate;
|
use fj_kernel::algorithms::triangulate;
|
||||||
use fj_math::{Aabb, Scalar, Triangle};
|
use fj_math::{Aabb, Scalar};
|
||||||
use fj_operations::ToShape as _;
|
use fj_operations::ToShape as _;
|
||||||
use futures::executor::block_on;
|
use futures::executor::block_on;
|
||||||
use tracing::{trace, warn};
|
use tracing::{trace, warn};
|
||||||
@ -88,7 +88,7 @@ fn main() -> anyhow::Result<()> {
|
|||||||
let mut mesh_maker = Mesh::new();
|
let mut mesh_maker = Mesh::new();
|
||||||
|
|
||||||
for triangle in shape.triangles {
|
for triangle in shape.triangles {
|
||||||
for vertex in triangle.points() {
|
for vertex in triangle.inner.points() {
|
||||||
mesh_maker.push(vertex);
|
mesh_maker.push(vertex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -310,7 +310,7 @@ impl ShapeProcessor {
|
|||||||
|
|
||||||
struct ProcessedShape {
|
struct ProcessedShape {
|
||||||
aabb: Aabb<3>,
|
aabb: Aabb<3>,
|
||||||
triangles: Vec<Triangle<3>>,
|
triangles: Vec<Triangle>,
|
||||||
debug_info: DebugInfo,
|
debug_info: DebugInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,3 +56,26 @@ impl<V> Default for Mesh<V> {
|
|||||||
|
|
||||||
/// An index that refers to a vertex in a mesh
|
/// An index that refers to a vertex in a mesh
|
||||||
pub type Index = u32;
|
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<fj_math::Triangle<3>>, color: Color) -> Self {
|
||||||
|
let inner = inner.into();
|
||||||
|
Self { inner, color }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// RGBA color
|
||||||
|
pub type Color = [u8; 4];
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use fj_math::{Scalar, Transform, Triangle, Vector};
|
use fj_interop::mesh::Triangle;
|
||||||
|
use fj_math::{Scalar, Transform, Vector};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
geometry::{Surface, SweptCurve},
|
geometry::{Surface, SweptCurve},
|
||||||
@ -149,16 +150,10 @@ pub fn sweep_shape(
|
|||||||
quads.push([v0, v1, v2, v3]);
|
quads.push([v0, v1, v2, v3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut side_face: Vec<Triangle<3>> = Vec::new();
|
let mut side_face: Vec<Triangle> = Vec::new();
|
||||||
for [v0, v1, v2, v3] in quads {
|
for [v0, v1, v2, v3] in quads {
|
||||||
side_face.push([v0, v1, v2].into());
|
side_face.push(Triangle::new([v0, v1, v2], color));
|
||||||
side_face.push([v0, v2, v3].into());
|
side_face.push(Triangle::new([v0, v2, v3], color));
|
||||||
}
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
target.insert(Face::Triangles(side_face)).unwrap();
|
target.insert(Face::Triangles(side_face)).unwrap();
|
||||||
|
@ -2,8 +2,8 @@ mod delaunay;
|
|||||||
mod polygon;
|
mod polygon;
|
||||||
mod ray;
|
mod ray;
|
||||||
|
|
||||||
use fj_interop::debug::DebugInfo;
|
use fj_interop::{debug::DebugInfo, mesh::Triangle};
|
||||||
use fj_math::{Scalar, Triangle};
|
use fj_math::Scalar;
|
||||||
|
|
||||||
use crate::{shape::Shape, topology::Face};
|
use crate::{shape::Shape, topology::Face};
|
||||||
|
|
||||||
@ -15,7 +15,7 @@ use super::FaceApprox;
|
|||||||
pub fn triangulate(
|
pub fn triangulate(
|
||||||
mut shape: Shape,
|
mut shape: Shape,
|
||||||
tolerance: Scalar,
|
tolerance: Scalar,
|
||||||
out: &mut Vec<Triangle<3>>,
|
out: &mut Vec<Triangle>,
|
||||||
debug_info: &mut DebugInfo,
|
debug_info: &mut DebugInfo,
|
||||||
) {
|
) {
|
||||||
for face in shape.topology().faces() {
|
for face in shape.topology().faces() {
|
||||||
@ -62,10 +62,8 @@ pub fn triangulate(
|
|||||||
});
|
});
|
||||||
|
|
||||||
out.extend(triangles.into_iter().map(|triangle| {
|
out.extend(triangles.into_iter().map(|triangle| {
|
||||||
let [a, b, c] = triangle.map(|point| point.canonical());
|
let points = triangle.map(|point| point.canonical());
|
||||||
let mut t = Triangle::from([a, b, c]);
|
Triangle::new(points, *color)
|
||||||
t.set_color(*color);
|
|
||||||
t
|
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
Face::Triangles(triangles) => out.extend(triangles),
|
Face::Triangles(triangles) => out.extend(triangles),
|
||||||
@ -75,8 +73,8 @@ pub fn triangulate(
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use fj_interop::debug::DebugInfo;
|
use fj_interop::{debug::DebugInfo, mesh::Triangle};
|
||||||
use fj_math::{Scalar, Triangle};
|
use fj_math::Scalar;
|
||||||
|
|
||||||
use crate::{geometry::Surface, shape::Shape, topology::Face};
|
use crate::{geometry::Surface, shape::Shape, topology::Face};
|
||||||
|
|
||||||
@ -146,17 +144,22 @@ mod tests {
|
|||||||
super::triangulate(shape, tolerance, &mut triangles, &mut debug_info);
|
super::triangulate(shape, tolerance, &mut triangles, &mut debug_info);
|
||||||
|
|
||||||
for triangle in &mut triangles {
|
for triangle in &mut triangles {
|
||||||
*triangle = triangle.normalize();
|
*triangle = Triangle {
|
||||||
|
inner: triangle.inner.normalize(),
|
||||||
|
..*triangle
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Triangles(triangles)
|
Triangles(triangles)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Triangles(Vec<Triangle<3>>);
|
#[derive(Debug)]
|
||||||
|
struct Triangles(Vec<Triangle>);
|
||||||
|
|
||||||
impl Triangles {
|
impl Triangles {
|
||||||
fn contains(&self, triangle: impl Into<Triangle<3>>) -> bool {
|
fn contains(&self, triangle: impl Into<fj_math::Triangle<3>>) -> bool {
|
||||||
let triangle = triangle.into().normalize();
|
let triangle =
|
||||||
|
Triangle::new(triangle.into().normalize(), [255, 0, 0, 255]);
|
||||||
self.0.contains(&triangle)
|
self.0.contains(&triangle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use fj_interop::mesh::Triangle;
|
||||||
use fj_math::{Point, Transform};
|
use fj_math::{Point, Transform};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -45,7 +46,10 @@ impl Geometry<'_> {
|
|||||||
use std::ops::DerefMut as _;
|
use std::ops::DerefMut as _;
|
||||||
if let Face::Triangles(triangles) = face.deref_mut() {
|
if let Face::Triangles(triangles) = face.deref_mut() {
|
||||||
for triangle in triangles {
|
for triangle in triangles {
|
||||||
*triangle = transform.transform_triangle(triangle);
|
*triangle = Triangle {
|
||||||
|
inner: transform.transform_triangle(&triangle.inner),
|
||||||
|
..*triangle
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
|
|
||||||
use fj_math::Triangle;
|
use fj_interop::mesh::Triangle;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
geometry::Surface,
|
geometry::Surface,
|
||||||
@ -61,7 +61,7 @@ pub enum Face {
|
|||||||
/// The plan is to eventually represent faces as a geometric surface,
|
/// The plan is to eventually represent faces as a geometric surface,
|
||||||
/// bounded by edges. While the transition is being made, this variant is
|
/// bounded by edges. While the transition is being made, this variant is
|
||||||
/// still required.
|
/// still required.
|
||||||
Triangles(Vec<Triangle<3>>),
|
Triangles(Vec<Triangle>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Face {
|
impl Face {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user