From 9c9e473490678cb15ba797b0d03e88c3139b9296 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thea=20Sch=C3=B6bl?= Date: Mon, 11 Mar 2024 20:28:53 +0100 Subject: [PATCH] feat: surface stuff --- bampy/src/lib.rs | 50 ++++++++++++++++++++++++++----- bampy/src/slicer/split_surface.rs | 6 ++-- bampy/src/slicer/triangle.rs | 4 +-- src/lib/slicer/worker.ts | 12 ++++++-- 4 files changed, 56 insertions(+), 16 deletions(-) diff --git a/bampy/src/lib.rs b/bampy/src/lib.rs index de6aed0..1dff411 100644 --- a/bampy/src/lib.rs +++ b/bampy/src/lib.rs @@ -23,12 +23,25 @@ pub struct SliceOptions { max_angle: f32, } +#[derive(Tsify, Serialize, Deserialize)] +#[serde(rename_all = "camelCase", tag = "type")] +#[tsify(into_wasm_abi)] +pub enum Slice { + Surface { + #[tsify(type = "Float32Array")] + position: Vec, + }, + Ring { + #[tsify(type = "Float32Array")] + position: Vec, + }, +} + #[derive(Tsify, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] #[tsify(into_wasm_abi)] pub struct SliceResult { - #[tsify(type = "Array")] - rings: Vec>, + slices: Vec, } #[wasm_bindgen] @@ -68,7 +81,7 @@ pub fn slice( slicable_triangles.push(triangle); } else { slicable_triangles.push(triangle); - //surface_triangles.push(triangle); + surface_triangles.push(triangle); } } slicable_triangles.shrink_to_fit(); @@ -79,7 +92,7 @@ pub fn slice( }; console_log!("Creating Surfaces"); - // let surfaces = split_surface(surface_triangles); + let surfaces = split_surface(surface_triangles); console_log!("Computing BVH"); let slicable = Mesh::from(slicable_triangles); @@ -88,15 +101,36 @@ pub fn slice( console_log!("Done"); SliceResult { - rings: slices + slices: slices .into_iter() - .map(|slice| { - slice + .map(|slice| Slice::Ring { + position: slice .points .into_iter() .flat_map(|point| [point.x as f32, point.y as f32, point.z as f32]) - .collect() + .collect(), }) + .chain(surfaces.into_iter().map(|surface| { + Slice::Surface { + position: surface + .triangles + .into_iter() + .flat_map(|triangle| { + [ + triangle.a.x as f32, + triangle.a.y as f32, + triangle.a.z as f32, + triangle.b.x as f32, + triangle.b.y as f32, + triangle.b.z as f32, + triangle.c.x as f32, + triangle.c.y as f32, + triangle.c.z as f32, + ] + }) + .collect(), + } + })) .collect(), } } diff --git a/bampy/src/slicer/split_surface.rs b/bampy/src/slicer/split_surface.rs index 15e59c2..7407d0d 100644 --- a/bampy/src/slicer/split_surface.rs +++ b/bampy/src/slicer/split_surface.rs @@ -2,7 +2,7 @@ use super::{mesh::Mesh, triangle::Triangle}; use bvh::bvh::{Bvh, BvhNode}; /// Splits a surface into connected surfaces. -pub fn split_surface(mut triangles: Vec>) -> Vec> { +pub fn split_surface(mut triangles: Vec>) -> Vec> { let mut surfaces = vec![]; while let Some(triangle) = triangles.pop() { let mut surface = vec![triangle]; @@ -20,10 +20,10 @@ pub fn split_surface(mut triangles: Vec>) -> Vec> { child_r_index, child_r_aabb, } => { - if triangle.intersects_aabb(&child_l_aabb) { + if triangle.has_point_in_aabb(&child_l_aabb) { stack.push(child_l_index); } - if triangle.intersects_aabb(&child_r_aabb) { + if triangle.has_point_in_aabb(&child_r_aabb) { stack.push(child_r_index); } } diff --git a/bampy/src/slicer/triangle.rs b/bampy/src/slicer/triangle.rs index f342c76..923c511 100644 --- a/bampy/src/slicer/triangle.rs +++ b/bampy/src/slicer/triangle.rs @@ -1,4 +1,4 @@ -use approx::{relative_eq, relative_ne, AbsDiffEq, RelativeEq}; +use approx::{relative_eq, AbsDiffEq, RelativeEq}; use bvh::{ aabb::{Aabb, Bounded}, bounding_hierarchy::BHShape, @@ -64,7 +64,7 @@ where } } - pub fn intersects_aabb(&self, aabb: &Aabb) -> bool { + pub fn has_point_in_aabb(&self, aabb: &Aabb) -> bool { vec_inside_aabb(&self.a, aabb) || vec_inside_aabb(&self.b, aabb) || vec_inside_aabb(&self.c, aabb) diff --git a/src/lib/slicer/worker.ts b/src/lib/slicer/worker.ts index 277eef4..f8f96fc 100644 --- a/src/lib/slicer/worker.ts +++ b/src/lib/slicer/worker.ts @@ -20,13 +20,19 @@ addEventListener('message', async (event: MessageEvent) => { layerHeight: event.data.data.layerHeight, maxAngle: event.data.data.maxNonPlanarAngle }); - for (const layer of result.rings) { + for (const layer of result.slices) { const geometry = new BufferGeometry(); - geometry.setAttribute('position', new Float32BufferAttribute(layer, 3)); + geometry.setAttribute('position', new Float32BufferAttribute(layer.position, 3)); + if (layer.type === 'surface') { + geometry.computeVertexNormals(); + } self.postMessage({ type: 'layer', - data: { type: LayerType.Line, geometry: geometry.toJSON() } + data: { + type: layer.type === 'ring' ? LayerType.Line : LayerType.Surface, + geometry: geometry.toJSON() + } } satisfies LayerMessage); } }