feat: stuff

This commit is contained in:
2024-03-21 17:35:30 +01:00
parent 50579861f2
commit f1f038ccca
6 changed files with 89 additions and 19 deletions

View File

@@ -1,11 +1,12 @@
use approx::relative_eq;
use nalgebra::{vector, Vector3}; use nalgebra::{vector, Vector3};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tsify::Tsify; use tsify::Tsify;
use wasm_bindgen::prelude::wasm_bindgen; use wasm_bindgen::prelude::wasm_bindgen;
use crate::slicer::{ use crate::slicer::{
base_slices::create_slices, mesh::Mesh, split_surface::split_surface, triangle::Triangle, base_slices::create_slices, mesh::Mesh, split_surface::split_surface,
SlicerOptions, trace_surface::trace_surface, triangle::Triangle, SlicerOptions,
}; };
mod slicer; mod slicer;
@@ -19,8 +20,8 @@ const BED_NORMAL: Vector3<f64> = vector![0f64, 0f64, 1f64];
pub struct SliceOptions { pub struct SliceOptions {
#[tsify(type = "Float32Array")] #[tsify(type = "Float32Array")]
positions: Vec<f32>, positions: Vec<f32>,
layer_height: f32, layer_height: f64,
max_angle: f32, max_angle: f64,
} }
#[derive(Tsify, Serialize, Deserialize)] #[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);
slicable_triangles.push(triangle); let angle = triangle.normal.angle(&BED_NORMAL);
} else { if angle <= max_angle || relative_eq!(angle, max_angle) {
slicable_triangles.push(triangle);
surface_triangles.push(triangle); surface_triangles.push(triangle);
} }
} }
slicable_triangles.shrink_to_fit(); slicable_triangles.shrink_to_fit();
surface_triangles.shrink_to_fit(); surface_triangles.shrink_to_fit();
let slicer_options = SlicerOptions { let slicer_options = SlicerOptions { layer_height };
layer_height: layer_height as f64,
};
console_log!("Creating Surfaces"); console_log!("Creating Surfaces");
let surfaces = split_surface(surface_triangles); let surfaces = split_surface(surface_triangles);
@@ -97,9 +95,15 @@ pub fn slice(
console_log!("Computing BVH"); console_log!("Computing BVH");
let slicable = Mesh::from(slicable_triangles); let slicable = Mesh::from(slicable_triangles);
console_log!("Creating Slices"); console_log!("Creating Slices");
let slices = create_slices(&slicer_options, &slicable); let mut slices = create_slices(&slicer_options, &slicable);
console_log!("Done"); console_log!("Done");
for slice in &mut slices {
for surface in &surfaces {
trace_surface(slice, surface)
}
}
SliceResult { SliceResult {
slices: slices slices: slices
.into_iter() .into_iter()

View File

@@ -1,5 +1,9 @@
use nalgebra::{Scalar, Vector3}; 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)] #[derive(Debug, PartialEq, Clone, Copy)]
pub struct Line3<T: Scalar> { pub struct Line3<T: Scalar> {
pub start: Vector3<T>, pub start: Vector3<T>,

View File

@@ -5,6 +5,7 @@ pub mod line;
pub mod mesh; pub mod mesh;
pub mod slice_rings; pub mod slice_rings;
pub mod split_surface; pub mod split_surface;
pub mod trace_surface;
pub mod triangle; pub mod triangle;
#[derive(Debug)] #[derive(Debug)]

View File

@@ -34,7 +34,7 @@ pub fn split_surface(mut triangles: Vec<Triangle<f64>>) -> Vec<Mesh<f64>> {
parent_index: _, parent_index: _,
shape_index, shape_index,
} => { } => {
if triangle.connected_with_triangle(surface[shape_index]) { if triangle.shares_point_with_triangle(surface[shape_index]) {
mutated = true; mutated = true;
surface.push(*triangle); surface.push(*triangle);
let index = surface.len() - 1; let index = surface.len() - 1;
@@ -52,11 +52,13 @@ pub fn split_surface(mut triangles: Vec<Triangle<f64>>) -> Vec<Mesh<f64>> {
} }
} }
surfaces.push(Mesh { if surface.len() > 1 {
triangles: surface, surfaces.push(Mesh {
aabb, triangles: surface,
bvh, aabb,
}) bvh,
})
}
} }
surfaces surfaces
} }

View File

@@ -0,0 +1,48 @@
use bvh::bvh::BvhNode;
use super::{mesh::Mesh, slice_rings::SliceRing};
pub fn trace_surface(slice: &mut SliceRing, surface: &Mesh<f64>) {
loop {
let mut mutated = false;
slice.points.retain_mut(|triangle| {
let mut stack = Vec::<usize>::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;
}
}
}

View File

@@ -81,7 +81,7 @@ where
relative_eq!(self.a, vec) || relative_eq!(self.b, vec) || relative_eq!(self.c, vec) relative_eq!(self.a, vec) || relative_eq!(self.b, vec) || relative_eq!(self.c, vec)
} }
pub fn connected_with_triangle(&self, other: Triangle<T>) -> bool pub fn shares_point_with_triangle(&self, other: Triangle<T>) -> bool
where where
T: RelativeEq + Clone, T: RelativeEq + Clone,
<T as AbsDiffEq>::Epsilon: Clone, <T as AbsDiffEq>::Epsilon: Clone,
@@ -89,6 +89,17 @@ where
self.has_vec(other.a) || self.has_vec(other.b) || self.has_vec(other.c) self.has_vec(other.a) || self.has_vec(other.b) || self.has_vec(other.c)
} }
pub fn shares_edge_with_triangle(&self, other: Triangle<T>) -> bool
where
T: RelativeEq + Clone,
<T as AbsDiffEq>::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<Line3<T>> pub fn intersect_z(&self, z: T) -> Option<Line3<T>>
where where
<T as AbsDiffEq>::Epsilon: Clone, <T as AbsDiffEq>::Epsilon: Clone,