mirror of
https://github.com/Theaninova/Bampy.git
synced 2025-12-12 12:36:16 +00:00
feat: stuff
This commit is contained in:
@@ -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()
|
||||||
|
|||||||
@@ -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>,
|
||||||
|
|||||||
@@ -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)]
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
48
bampy/src/slicer/trace_surface.rs
Normal file
48
bampy/src/slicer/trace_surface.rs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user