This commit is contained in:
2024-03-11 19:59:40 +01:00
parent 58199b0bd7
commit 43b4ab90cb
4 changed files with 48 additions and 22 deletions

View File

@@ -1,13 +1,10 @@
use bvh::bvh::BvhNode;
use crate::console_log;
use super::{ use super::{
line::Line3, line::Line3,
mesh::Mesh, mesh::Mesh,
slice_rings::{find_slice_rings, SliceRing}, slice_rings::{find_slice_rings, SliceRing},
SlicerOptions, SlicerOptions,
}; };
use bvh::bvh::BvhNode;
#[derive(Debug)] #[derive(Debug)]
pub struct BaseSlice { pub struct BaseSlice {
@@ -20,9 +17,9 @@ pub struct BaseSlice {
pub fn create_slices(options: &SlicerOptions, slicable: &Mesh<f64>) -> Vec<SliceRing> { pub fn create_slices(options: &SlicerOptions, slicable: &Mesh<f64>) -> Vec<SliceRing> {
let layer_count = f64::floor(slicable.aabb.max.z / options.layer_height) as usize; let layer_count = f64::floor(slicable.aabb.max.z / options.layer_height) as usize;
let mut rings = vec![]; let mut rings = vec![];
let mut layer_index = 0;
for i in 0..layer_count { for i in 0..layer_count {
console_log!("Layer {}", i);
let layer = i as f64 * options.layer_height; let layer = i as f64 * options.layer_height;
let mut base_slice = BaseSlice { let mut base_slice = BaseSlice {
z: layer, z: layer,
@@ -62,7 +59,7 @@ pub fn create_slices(options: &SlicerOptions, slicable: &Mesh<f64>) -> Vec<Slice
} }
} }
rings.append(&mut find_slice_rings(base_slice)); rings.append(&mut find_slice_rings(base_slice, &mut layer_index));
} }
rings rings

View File

@@ -1,4 +1,4 @@
use approx::{relative_eq, relative_ne}; use approx::relative_eq;
use nalgebra::Vector3; use nalgebra::Vector3;
use crate::console_log; use crate::console_log;
@@ -8,10 +8,11 @@ use super::base_slices::BaseSlice;
#[derive(Debug)] #[derive(Debug)]
pub struct SliceRing { pub struct SliceRing {
pub z: f64, pub z: f64,
/// The points of the ring, in clockwise order.
pub points: Vec<Vector3<f64>>, pub points: Vec<Vector3<f64>>,
} }
pub fn find_slice_rings(mut slice: BaseSlice) -> Vec<SliceRing> { pub fn find_slice_rings(mut slice: BaseSlice, layer_index: &mut u32) -> Vec<SliceRing> {
let mut rings = vec![]; let mut rings = vec![];
while let Some(line) = slice.lines.pop() { while let Some(line) = slice.lines.pop() {
if relative_eq!(line.start, line.end) { if relative_eq!(line.start, line.end) {
@@ -23,13 +24,16 @@ pub fn find_slice_rings(mut slice: BaseSlice) -> Vec<SliceRing> {
}; };
let mut right_start = ring.points[0]; let mut right_start = ring.points[0];
let mut right = ring.points[1]; let mut right = ring.points[1];
let mut sum_of_edges = (right.x - right_start.x) * (right.y + right_start.y);
let mut previous_len = usize::MAX; let mut previous_len = usize::MAX;
while relative_ne!(ring.points[0], right) { let mut done = false;
while !done {
if previous_len == slice.lines.len() { if previous_len == slice.lines.len() {
console_log!( console_log!(
"Error: Could not find a ring for slice at z = {}, d = {}, {} items left.", "Error: Could not close ring {}, d = {}, {} items left.",
slice.z, layer_index,
ring.points[0].metric_distance(&right), ring.points[0].metric_distance(&right),
slice.lines.len() slice.lines.len()
); );
@@ -38,24 +42,42 @@ pub fn find_slice_rings(mut slice: BaseSlice) -> Vec<SliceRing> {
previous_len = slice.lines.len(); previous_len = slice.lines.len();
slice.lines.retain_mut(|line| { slice.lines.retain_mut(|line| {
if done {
return true;
}
macro_rules! add {
( $point:expr ) => {
if !relative_eq!($point, right_start) {
right_start = right;
right = $point;
ring.points.push(right);
sum_of_edges = (right.x - right_start.x) * (right.y + right_start.y);
done = relative_eq!(ring.points[0], right);
}
};
}
let s = relative_eq!(line.start, right); let s = relative_eq!(line.start, right);
let e = relative_eq!(line.end, right); let e = relative_eq!(line.end, right);
if s && !e && !relative_eq!(line.end, right_start) { if s && !e {
ring.points.push(line.end); add!(line.end);
right_start = right;
right = line.end;
false false
} else if e && !s && !relative_eq!(line.start, right_start) { } else if e && !s {
ring.points.push(line.start); add!(line.start);
right_start = right;
right = line.start;
false false
} else { } else {
true true
} }
}) })
} }
rings.push(ring)
// The end point is duplicate, so not part of the winding order calculation.
if sum_of_edges < 0.0 {
ring.points.reverse();
}
rings.push(ring);
*layer_index += 1;
} }
rings rings

View File

@@ -6,14 +6,16 @@
let progress: Writable<number | undefined>; let progress: Writable<number | undefined>;
let showSlices = 1; let showSlices = 1;
let maxZ = 0;
let progressLayer: Writable<number>; let progressLayer: Writable<number>;
</script> </script>
<Canvas> <Canvas>
<Scene bind:progress bind:showSlices bind:progressLayer /> <Scene bind:progress bind:showSlices bind:progressLayer bind:maxZ />
</Canvas> </Canvas>
<div class="controls"> <div class="controls">
<input type="number" bind:value={maxZ} />
<input type="range" min="0" max="1" step="0.001" bind:value={showSlices} orient="vertical" /> <input type="range" min="0" max="1" step="0.001" bind:value={showSlices} orient="vertical" />
</div> </div>
@@ -31,6 +33,10 @@
height: 80%; height: 80%;
} }
input[type='number'] {
width: 60px;
}
.controls { .controls {
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View File

@@ -58,6 +58,7 @@
export let progress = writable<number | undefined>(undefined); export let progress = writable<number | undefined>(undefined);
export let progressLayer = writable(0); export let progressLayer = writable(0);
export let showSlices = 1; export let showSlices = 1;
export let maxZ = 0;
export let maxNonPlanarAngle = MathUtils.degToRad(20); export let maxNonPlanarAngle = MathUtils.degToRad(20);
export let bedNormal = new Vector3(0, 0, 1); export let bedNormal = new Vector3(0, 0, 1);
@@ -98,7 +99,7 @@
/> />
{#each $layers as { geometry, type }, i} {#each $layers as { geometry, type }, i}
{@const visible = showSlices >= i / $layers.length} {@const visible = maxZ !== 0 ? i === maxZ : showSlices >= i / $layers.length}
{@const color = new Color(Math.random() * 0xffffff)} {@const color = new Color(Math.random() * 0xffffff)}
<!---{@const color = new Color(0, i / $layers.length, 0.2)}--> <!---{@const color = new Color(0, i / $layers.length, 0.2)}-->
{#if type === LayerType.Line} {#if type === LayerType.Line}