mirror of
https://github.com/Theaninova/Bampy.git
synced 2025-12-12 20:46:19 +00:00
feat: functioning ring finding
This commit is contained in:
@@ -11,7 +11,7 @@ use crate::slicer::{
|
|||||||
mod slicer;
|
mod slicer;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
const BED_NORMAL: Vector3<f32> = vector![0f32, 0f32, 1f32];
|
const BED_NORMAL: Vector3<f64> = vector![0f64, 0f64, 1f64];
|
||||||
|
|
||||||
#[derive(Tsify, Serialize, Deserialize)]
|
#[derive(Tsify, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
@@ -43,16 +43,28 @@ pub fn slice(
|
|||||||
|
|
||||||
assert_eq!(positions.len() % 9, 0);
|
assert_eq!(positions.len() % 9, 0);
|
||||||
|
|
||||||
let mut surface_triangles = Vec::<Triangle<f32>>::with_capacity(positions.len() / 9);
|
let mut surface_triangles = Vec::<Triangle<f64>>::with_capacity(positions.len() / 9);
|
||||||
let mut slicable_triangles = Vec::with_capacity(positions.len() / 9);
|
let mut slicable_triangles = Vec::<Triangle<f64>>::with_capacity(positions.len() / 9);
|
||||||
for i in (0..positions.len()).step_by(9) {
|
for i in (0..positions.len()).step_by(9) {
|
||||||
let triangle = Triangle::new(
|
let triangle = Triangle::new(
|
||||||
vector![positions[i], positions[i + 1], positions[i + 2]],
|
vector![
|
||||||
vector![positions[i + 3], positions[i + 4], positions[i + 5]],
|
positions[i] as f64,
|
||||||
vector![positions[i + 6], positions[i + 7], positions[i + 8]],
|
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);
|
slicable_triangles.push(triangle);
|
||||||
} else {
|
} else {
|
||||||
slicable_triangles.push(triangle);
|
slicable_triangles.push(triangle);
|
||||||
@@ -62,7 +74,9 @@ pub fn slice(
|
|||||||
slicable_triangles.shrink_to_fit();
|
slicable_triangles.shrink_to_fit();
|
||||||
surface_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");
|
console_log!("Creating Surfaces");
|
||||||
// let surfaces = split_surface(surface_triangles);
|
// let surfaces = split_surface(surface_triangles);
|
||||||
@@ -80,7 +94,7 @@ pub fn slice(
|
|||||||
slice
|
slice
|
||||||
.points
|
.points
|
||||||
.into_iter()
|
.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()
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
|
|||||||
@@ -11,19 +11,19 @@ use super::{
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct BaseSlice {
|
pub struct BaseSlice {
|
||||||
pub z: f32,
|
pub z: f64,
|
||||||
pub lines: Vec<Line3<f32>>,
|
pub lines: Vec<Line3<f64>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates base slices from the geometry, excluding surfaces.
|
/// Creates base slices from the geometry, excluding surfaces.
|
||||||
/// The slicse are not sorted or separated into rings.
|
/// The slicse are not sorted or separated into rings.
|
||||||
pub fn create_slices(options: &SlicerOptions, slicable: &Mesh<f32>) -> Vec<SliceRing> {
|
pub fn create_slices(options: &SlicerOptions, slicable: &Mesh<f64>) -> Vec<SliceRing> {
|
||||||
let layer_count = f32::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![];
|
||||||
|
|
||||||
for i in 0..layer_count {
|
for i in 0..layer_count {
|
||||||
console_log!("Layer {}", i);
|
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 {
|
let mut base_slice = BaseSlice {
|
||||||
z: layer,
|
z: layer,
|
||||||
lines: vec![],
|
lines: vec![],
|
||||||
|
|||||||
@@ -9,5 +9,5 @@ pub mod triangle;
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SlicerOptions {
|
pub struct SlicerOptions {
|
||||||
pub layer_height: f32,
|
pub layer_height: f64,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,25 +7,30 @@ use super::base_slices::BaseSlice;
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SliceRing {
|
pub struct SliceRing {
|
||||||
pub z: f32,
|
pub z: f64,
|
||||||
pub points: Vec<Vector3<f32>>,
|
pub points: Vec<Vector3<f64>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_slice_rings(mut slice: BaseSlice) -> Vec<SliceRing> {
|
pub fn find_slice_rings(mut slice: BaseSlice) -> 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) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
let mut ring = SliceRing {
|
let mut ring = SliceRing {
|
||||||
z: slice.z,
|
z: slice.z,
|
||||||
points: vec![line.start, line.end],
|
points: vec![line.start, line.end],
|
||||||
};
|
};
|
||||||
|
let mut right_start = ring.points[0];
|
||||||
let mut right = ring.points[1];
|
let mut right = ring.points[1];
|
||||||
|
|
||||||
let mut previous_len = usize::MAX;
|
let mut previous_len = usize::MAX;
|
||||||
while relative_ne!(ring.points[0], right) {
|
while relative_ne!(ring.points[0], right) {
|
||||||
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 = {}, {} items left.",
|
"Error: Could not find a ring for slice at z = {}, d = {}, {} items left.",
|
||||||
slice.z,
|
slice.z,
|
||||||
|
ring.points[0].metric_distance(&right),
|
||||||
slice.lines.len()
|
slice.lines.len()
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
@@ -33,21 +38,23 @@ 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 relative_eq!(line.start, right, epsilon = 0.001) {
|
let s = relative_eq!(line.start, right);
|
||||||
ring.points.push(line.start);
|
let e = relative_eq!(line.end, right);
|
||||||
ring.points.push(line.end);
|
if s && !e && !relative_eq!(line.end, right_start) {
|
||||||
right = line.end;
|
ring.points.push(line.end);
|
||||||
false
|
right_start = right;
|
||||||
/*} else if relative_eq!(line.end, right, epsilon = 0.001) {
|
right = line.end;
|
||||||
|
false
|
||||||
|
} else if e && !s && !relative_eq!(line.start, right_start) {
|
||||||
ring.points.push(line.start);
|
ring.points.push(line.start);
|
||||||
|
right_start = right;
|
||||||
right = line.start;
|
right = line.start;
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
}*/
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
rings.push(ring)
|
rings.push(ring)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use approx::{assert_relative_ne, relative_eq, AbsDiffEq, RelativeEq};
|
use approx::{relative_eq, relative_ne, AbsDiffEq, RelativeEq};
|
||||||
use bvh::{
|
use bvh::{
|
||||||
aabb::{Aabb, Bounded},
|
aabb::{Aabb, Bounded},
|
||||||
bounding_hierarchy::BHShape,
|
bounding_hierarchy::BHShape,
|
||||||
@@ -86,14 +86,29 @@ 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 intersect_z(&self, z: T) -> Option<Line3<T>> {
|
pub fn intersect_z(&self, z: T) -> Option<Line3<T>>
|
||||||
let mut intersection = Vec::with_capacity(3);
|
where
|
||||||
|
<T as AbsDiffEq>::Epsilon: Clone,
|
||||||
|
{
|
||||||
|
let mut intersection = Vec::<Vector3<T>>::with_capacity(3);
|
||||||
let mut last = &self.c;
|
let mut last = &self.c;
|
||||||
for point in [self.a, self.b, self.c].iter() {
|
for point in [self.a, self.b, self.c].iter() {
|
||||||
if relative_eq!(point.z, z) {
|
if relative_eq!(point.z, z) {
|
||||||
intersection.push(*point);
|
intersection.push(Vector3::new(point.x, point.y, z));
|
||||||
} else if (last.z < z && point.z > z) || (last.z > z && point.z < z) {
|
} else if last.z < z && point.z > z {
|
||||||
intersection.push(last.lerp(&point, (z - last.z) / (point.z - last.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;
|
last = point;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,11 +99,12 @@
|
|||||||
|
|
||||||
{#each $layers as { geometry, type }, i}
|
{#each $layers as { geometry, type }, i}
|
||||||
{@const visible = showSlices >= i / $layers.length}
|
{@const visible = showSlices >= i / $layers.length}
|
||||||
{@const color = new Color(0, i / $layers.length, 0.2)}
|
{@const color = new Color(Math.random() * 0xffffff)}
|
||||||
|
<!---{@const color = new Color(0, i / $layers.length, 0.2)}-->
|
||||||
{#if type === LayerType.Line}
|
{#if type === LayerType.Line}
|
||||||
<T.LineSegments {geometry} {visible}>
|
<T.Line {geometry} {visible}>
|
||||||
<T.LineBasicMaterial {color} />
|
<T.LineBasicMaterial {color} />
|
||||||
</T.LineSegments>
|
</T.Line>
|
||||||
{:else if type === LayerType.Surface}
|
{:else if type === LayerType.Surface}
|
||||||
<T.Mesh {geometry} {visible}>
|
<T.Mesh {geometry} {visible}>
|
||||||
<T.MeshMatcapMaterial {color} side={DoubleSide} />
|
<T.MeshMatcapMaterial {color} side={DoubleSide} />
|
||||||
|
|||||||
Reference in New Issue
Block a user