diff --git a/bampy/src/lib.rs b/bampy/src/lib.rs index 65171a9..de6aed0 100644 --- a/bampy/src/lib.rs +++ b/bampy/src/lib.rs @@ -11,7 +11,7 @@ use crate::slicer::{ mod slicer; mod util; -const BED_NORMAL: Vector3 = vector![0f32, 0f32, 1f32]; +const BED_NORMAL: Vector3 = vector![0f64, 0f64, 1f64]; #[derive(Tsify, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -43,16 +43,28 @@ pub fn slice( assert_eq!(positions.len() % 9, 0); - let mut surface_triangles = Vec::>::with_capacity(positions.len() / 9); - let mut slicable_triangles = Vec::with_capacity(positions.len() / 9); + let mut surface_triangles = Vec::>::with_capacity(positions.len() / 9); + let mut slicable_triangles = Vec::>::with_capacity(positions.len() / 9); for i in (0..positions.len()).step_by(9) { let triangle = Triangle::new( - vector![positions[i], positions[i + 1], positions[i + 2]], - vector![positions[i + 3], positions[i + 4], positions[i + 5]], - vector![positions[i + 6], positions[i + 7], positions[i + 8]], + vector![ + positions[i] as f64, + positions[i + 1] as f64, + positions[i + 2] as f64 + ], + vector![ + positions[i + 3] as f64, + positions[i + 4] as f64, + positions[i + 5] as f64 + ], + vector![ + positions[i + 6] as f64, + positions[i + 7] as f64, + positions[i + 8] as f64 + ], ); - if triangle.normal.angle(&BED_NORMAL) > max_angle { + if triangle.normal.angle(&BED_NORMAL) > max_angle as f64 { slicable_triangles.push(triangle); } else { slicable_triangles.push(triangle); @@ -62,7 +74,9 @@ pub fn slice( slicable_triangles.shrink_to_fit(); surface_triangles.shrink_to_fit(); - let slicer_options = SlicerOptions { layer_height }; + let slicer_options = SlicerOptions { + layer_height: layer_height as f64, + }; console_log!("Creating Surfaces"); // let surfaces = split_surface(surface_triangles); @@ -80,7 +94,7 @@ pub fn slice( slice .points .into_iter() - .flat_map(|point| [point.x, point.y, point.z]) + .flat_map(|point| [point.x as f32, point.y as f32, point.z as f32]) .collect() }) .collect(), diff --git a/bampy/src/slicer/base_slices.rs b/bampy/src/slicer/base_slices.rs index f7905ed..6f6f54e 100644 --- a/bampy/src/slicer/base_slices.rs +++ b/bampy/src/slicer/base_slices.rs @@ -11,19 +11,19 @@ use super::{ #[derive(Debug)] pub struct BaseSlice { - pub z: f32, - pub lines: Vec>, + pub z: f64, + pub lines: Vec>, } /// Creates base slices from the geometry, excluding surfaces. /// The slicse are not sorted or separated into rings. -pub fn create_slices(options: &SlicerOptions, slicable: &Mesh) -> Vec { - let layer_count = f32::floor(slicable.aabb.max.z / options.layer_height) as usize; +pub fn create_slices(options: &SlicerOptions, slicable: &Mesh) -> Vec { + let layer_count = f64::floor(slicable.aabb.max.z / options.layer_height) as usize; let mut rings = vec![]; for i in 0..layer_count { console_log!("Layer {}", i); - let layer = i as f32 * options.layer_height; + let layer = i as f64 * options.layer_height; let mut base_slice = BaseSlice { z: layer, lines: vec![], diff --git a/bampy/src/slicer/mod.rs b/bampy/src/slicer/mod.rs index bcb198d..0bea5ee 100644 --- a/bampy/src/slicer/mod.rs +++ b/bampy/src/slicer/mod.rs @@ -9,5 +9,5 @@ pub mod triangle; #[derive(Debug)] pub struct SlicerOptions { - pub layer_height: f32, + pub layer_height: f64, } diff --git a/bampy/src/slicer/slice_rings.rs b/bampy/src/slicer/slice_rings.rs index 79b64d6..769bb26 100644 --- a/bampy/src/slicer/slice_rings.rs +++ b/bampy/src/slicer/slice_rings.rs @@ -7,25 +7,30 @@ use super::base_slices::BaseSlice; #[derive(Debug)] pub struct SliceRing { - pub z: f32, - pub points: Vec>, + pub z: f64, + pub points: Vec>, } pub fn find_slice_rings(mut slice: BaseSlice) -> Vec { let mut rings = vec![]; while let Some(line) = slice.lines.pop() { + if relative_eq!(line.start, line.end) { + continue; + } let mut ring = SliceRing { z: slice.z, points: vec![line.start, line.end], }; + let mut right_start = ring.points[0]; let mut right = ring.points[1]; let mut previous_len = usize::MAX; while relative_ne!(ring.points[0], right) { if previous_len == slice.lines.len() { console_log!( - "Error: Could not find a ring for slice at z = {}, {} items left.", + "Error: Could not find a ring for slice at z = {}, d = {}, {} items left.", slice.z, + ring.points[0].metric_distance(&right), slice.lines.len() ); break; @@ -33,21 +38,23 @@ pub fn find_slice_rings(mut slice: BaseSlice) -> Vec { previous_len = slice.lines.len(); slice.lines.retain_mut(|line| { - //if relative_eq!(line.start, right, epsilon = 0.001) { - ring.points.push(line.start); - ring.points.push(line.end); - right = line.end; - false - /*} else if relative_eq!(line.end, right, epsilon = 0.001) { + let s = relative_eq!(line.start, right); + let e = relative_eq!(line.end, right); + if s && !e && !relative_eq!(line.end, right_start) { + ring.points.push(line.end); + right_start = right; + right = line.end; + false + } else if e && !s && !relative_eq!(line.start, right_start) { ring.points.push(line.start); + right_start = right; right = line.start; false } else { true - }*/ + } }) } - rings.push(ring) } diff --git a/bampy/src/slicer/triangle.rs b/bampy/src/slicer/triangle.rs index 95d3776..f342c76 100644 --- a/bampy/src/slicer/triangle.rs +++ b/bampy/src/slicer/triangle.rs @@ -1,4 +1,4 @@ -use approx::{assert_relative_ne, relative_eq, AbsDiffEq, RelativeEq}; +use approx::{relative_eq, relative_ne, AbsDiffEq, RelativeEq}; use bvh::{ aabb::{Aabb, Bounded}, bounding_hierarchy::BHShape, @@ -86,14 +86,29 @@ where self.has_vec(other.a) || self.has_vec(other.b) || self.has_vec(other.c) } - pub fn intersect_z(&self, z: T) -> Option> { - let mut intersection = Vec::with_capacity(3); + pub fn intersect_z(&self, z: T) -> Option> + where + ::Epsilon: Clone, + { + let mut intersection = Vec::>::with_capacity(3); let mut last = &self.c; for point in [self.a, self.b, self.c].iter() { if relative_eq!(point.z, z) { - intersection.push(*point); - } else if (last.z < z && point.z > z) || (last.z > z && point.z < z) { - intersection.push(last.lerp(&point, (z - last.z) / (point.z - last.z))); + intersection.push(Vector3::new(point.x, point.y, z)); + } else if last.z < z && point.z > z { + let ratio = (z - last.z) / (point.z - last.z); + intersection.push(Vector3::new( + last.x + (point.x - last.x) * ratio, + last.y + (point.y - last.y) * ratio, + z, + )) + } else if last.z > z && point.z < z { + let ratio = (z - point.z) / (last.z - point.z); + intersection.push(Vector3::new( + point.x + (last.x - point.x) * ratio, + point.y + (last.y - point.y) * ratio, + z, + )) } last = point; } diff --git a/src/lib/components/Scene.svelte b/src/lib/components/Scene.svelte index ae04b2f..214f397 100644 --- a/src/lib/components/Scene.svelte +++ b/src/lib/components/Scene.svelte @@ -99,11 +99,12 @@ {#each $layers as { geometry, type }, i} {@const visible = showSlices >= i / $layers.length} - {@const color = new Color(0, i / $layers.length, 0.2)} + {@const color = new Color(Math.random() * 0xffffff)} + {#if type === LayerType.Line} - + - + {:else if type === LayerType.Surface}