From f1f038cccaa5bac090cbc8d5e7ed3b679ccde7da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thea=20Sch=C3=B6bl?= Date: Thu, 21 Mar 2024 17:35:30 +0100 Subject: [PATCH] feat: stuff --- bampy/src/lib.rs | 28 ++++++++++-------- bampy/src/slicer/line.rs | 4 +++ bampy/src/slicer/mod.rs | 1 + bampy/src/slicer/split_surface.rs | 14 +++++---- bampy/src/slicer/trace_surface.rs | 48 +++++++++++++++++++++++++++++++ bampy/src/slicer/triangle.rs | 13 ++++++++- 6 files changed, 89 insertions(+), 19 deletions(-) create mode 100644 bampy/src/slicer/trace_surface.rs diff --git a/bampy/src/lib.rs b/bampy/src/lib.rs index 1dff411..3495f38 100644 --- a/bampy/src/lib.rs +++ b/bampy/src/lib.rs @@ -1,11 +1,12 @@ +use approx::relative_eq; use nalgebra::{vector, Vector3}; use serde::{Deserialize, Serialize}; use tsify::Tsify; use wasm_bindgen::prelude::wasm_bindgen; use crate::slicer::{ - base_slices::create_slices, mesh::Mesh, split_surface::split_surface, triangle::Triangle, - SlicerOptions, + base_slices::create_slices, mesh::Mesh, split_surface::split_surface, + trace_surface::trace_surface, triangle::Triangle, SlicerOptions, }; mod slicer; @@ -19,8 +20,8 @@ const BED_NORMAL: Vector3 = vector![0f64, 0f64, 1f64]; pub struct SliceOptions { #[tsify(type = "Float32Array")] positions: Vec, - layer_height: f32, - max_angle: f32, + layer_height: f64, + max_angle: f64, } #[derive(Tsify, Serialize, Deserialize)] @@ -77,19 +78,16 @@ pub fn slice( ], ); - if triangle.normal.angle(&BED_NORMAL) > max_angle as f64 { - slicable_triangles.push(triangle); - } else { - slicable_triangles.push(triangle); + slicable_triangles.push(triangle); + let angle = triangle.normal.angle(&BED_NORMAL); + if angle <= max_angle || relative_eq!(angle, max_angle) { surface_triangles.push(triangle); } } slicable_triangles.shrink_to_fit(); surface_triangles.shrink_to_fit(); - let slicer_options = SlicerOptions { - layer_height: layer_height as f64, - }; + let slicer_options = SlicerOptions { layer_height }; console_log!("Creating Surfaces"); let surfaces = split_surface(surface_triangles); @@ -97,9 +95,15 @@ pub fn slice( console_log!("Computing BVH"); let slicable = Mesh::from(slicable_triangles); console_log!("Creating Slices"); - let slices = create_slices(&slicer_options, &slicable); + let mut slices = create_slices(&slicer_options, &slicable); console_log!("Done"); + for slice in &mut slices { + for surface in &surfaces { + trace_surface(slice, surface) + } + } + SliceResult { slices: slices .into_iter() diff --git a/bampy/src/slicer/line.rs b/bampy/src/slicer/line.rs index 96ce89b..00b1ba2 100644 --- a/bampy/src/slicer/line.rs +++ b/bampy/src/slicer/line.rs @@ -1,5 +1,9 @@ use nalgebra::{Scalar, Vector3}; +/// Lines are assumed to be with respect to the XY plane. +/// The order of the points is therefore significant, +/// clockwise order with respect to the inside of the shape, +/// meaning the inside is on the right hand side of the line. #[derive(Debug, PartialEq, Clone, Copy)] pub struct Line3 { pub start: Vector3, diff --git a/bampy/src/slicer/mod.rs b/bampy/src/slicer/mod.rs index 0bea5ee..2fa5e05 100644 --- a/bampy/src/slicer/mod.rs +++ b/bampy/src/slicer/mod.rs @@ -5,6 +5,7 @@ pub mod line; pub mod mesh; pub mod slice_rings; pub mod split_surface; +pub mod trace_surface; pub mod triangle; #[derive(Debug)] diff --git a/bampy/src/slicer/split_surface.rs b/bampy/src/slicer/split_surface.rs index e04a9aa..0ff5b67 100644 --- a/bampy/src/slicer/split_surface.rs +++ b/bampy/src/slicer/split_surface.rs @@ -34,7 +34,7 @@ pub fn split_surface(mut triangles: Vec>) -> Vec> { parent_index: _, shape_index, } => { - if triangle.connected_with_triangle(surface[shape_index]) { + if triangle.shares_point_with_triangle(surface[shape_index]) { mutated = true; surface.push(*triangle); let index = surface.len() - 1; @@ -52,11 +52,13 @@ pub fn split_surface(mut triangles: Vec>) -> Vec> { } } - surfaces.push(Mesh { - triangles: surface, - aabb, - bvh, - }) + if surface.len() > 1 { + surfaces.push(Mesh { + triangles: surface, + aabb, + bvh, + }) + } } surfaces } diff --git a/bampy/src/slicer/trace_surface.rs b/bampy/src/slicer/trace_surface.rs new file mode 100644 index 0000000..7a852d4 --- /dev/null +++ b/bampy/src/slicer/trace_surface.rs @@ -0,0 +1,48 @@ +use bvh::bvh::BvhNode; + +use super::{mesh::Mesh, slice_rings::SliceRing}; + +pub fn trace_surface(slice: &mut SliceRing, surface: &Mesh) { + loop { + let mut mutated = false; + slice.points.retain_mut(|triangle| { + let mut stack = Vec::::new(); + stack.push(0); + while let Some(i) = stack.pop() { + match surface.bvh.nodes[i] { + BvhNode::Node { + parent_index: _, + child_l_index, + child_l_aabb, + child_r_index, + child_r_aabb, + } => { + if triangle.has_point_in_aabb(&child_l_aabb) { + stack.push(child_l_index); + } + if triangle.has_point_in_aabb(&child_r_aabb) { + stack.push(child_r_index); + } + } + BvhNode::Leaf { + parent_index: _, + shape_index, + } => { + if triangle.shares_point_with_triangle(surface[shape_index]) { + mutated = true; + surface.push(*triangle); + let index = surface.len() - 1; + bvh.add_shape(&mut surface, index); + aabb.join_mut(&triangle.aabb); + return false; + } + } + } + } + true + }); + if !mutated { + break; + } + } +} diff --git a/bampy/src/slicer/triangle.rs b/bampy/src/slicer/triangle.rs index 54f8ed9..a18b2c2 100644 --- a/bampy/src/slicer/triangle.rs +++ b/bampy/src/slicer/triangle.rs @@ -81,7 +81,7 @@ where relative_eq!(self.a, vec) || relative_eq!(self.b, vec) || relative_eq!(self.c, vec) } - pub fn connected_with_triangle(&self, other: Triangle) -> bool + pub fn shares_point_with_triangle(&self, other: Triangle) -> bool where T: RelativeEq + Clone, ::Epsilon: Clone, @@ -89,6 +89,17 @@ where self.has_vec(other.a) || self.has_vec(other.b) || self.has_vec(other.c) } + pub fn shares_edge_with_triangle(&self, other: Triangle) -> bool + where + T: RelativeEq + Clone, + ::Epsilon: Clone, + { + let a = self.has_vec(other.a); + let b = self.has_vec(other.b); + let c = self.has_vec(other.c); + a && b || a && c || b && c + } + pub fn intersect_z(&self, z: T) -> Option> where ::Epsilon: Clone,