mirror of
https://github.com/Theaninova/Bampy.git
synced 2026-02-15 05:22:38 +00:00
feat: testing
This commit is contained in:
165
bampy/src/lib.rs
165
bampy/src/lib.rs
@@ -1,7 +1,11 @@
|
||||
#![feature(extract_if)]
|
||||
use std::collections::VecDeque;
|
||||
|
||||
use approx::relative_eq;
|
||||
use nalgebra::{point, vector, Vector3};
|
||||
use num::Float;
|
||||
use result::{Slice, SliceOptions, SliceResult};
|
||||
use slicer::axis::Axis;
|
||||
use slicer::{axis::Axis, slice_path::SlicePath, trace_surface::trace_surface};
|
||||
use wasm_bindgen::prelude::wasm_bindgen;
|
||||
|
||||
use crate::slicer::{mesh::Mesh, split_surface::split_surface, triangle::Triangle, FloatValue};
|
||||
@@ -48,13 +52,10 @@ pub fn slice(
|
||||
);
|
||||
|
||||
slicable_triangles.push(triangle);
|
||||
let angle = triangle.normal.angle(&BED_NORMAL);
|
||||
let opposite_angle = std::f64::consts::PI - angle;
|
||||
if angle <= max_angle
|
||||
|| relative_eq!(angle, max_angle)
|
||||
|| opposite_angle <= max_angle
|
||||
|| relative_eq!(opposite_angle, max_angle)
|
||||
{
|
||||
let mut normal = triangle.normal.clone();
|
||||
normal.z = normal.z.abs();
|
||||
let angle = normal.angle(&BED_NORMAL);
|
||||
if angle <= max_angle || relative_eq!(angle, max_angle) {
|
||||
surface_triangles.push(triangle);
|
||||
}
|
||||
}
|
||||
@@ -62,45 +63,130 @@ pub fn slice(
|
||||
surface_triangles.shrink_to_fit();
|
||||
|
||||
console_log!("Creating Surfaces");
|
||||
let surfaces = split_surface(surface_triangles).into_iter().map(|mesh| {
|
||||
mesh.slice_surface(Axis::X, nozzle_diameter).filter(|path| {
|
||||
let mut length = 0.0;
|
||||
for pair in path.path.windows(2) {
|
||||
length += (pair[0].coords - pair[1].coords).norm();
|
||||
if length >= min_surface_path_length {
|
||||
let min_surface_area = std::f64::consts::PI * (nozzle_diameter / 2.0).powi(2);
|
||||
let mut surfaces = split_surface(surface_triangles)
|
||||
.into_iter()
|
||||
.filter(|mesh| {
|
||||
let mut surface_area = 0.0;
|
||||
for triangle in &mesh.triangles {
|
||||
surface_area += triangle.area();
|
||||
if surface_area >= min_surface_area {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
})
|
||||
});
|
||||
.map(|mesh| {
|
||||
let outline = mesh
|
||||
.outline_base_slice(Axis::Z)
|
||||
.find_paths()
|
||||
.into_iter()
|
||||
.filter(|path| path.closed)
|
||||
.collect::<Vec<_>>();
|
||||
let surface = mesh
|
||||
.slice_surface(Axis::X, nozzle_diameter)
|
||||
.filter(|path| {
|
||||
let mut length = 0.0;
|
||||
for pair in path.path.windows(2) {
|
||||
length += (pair[0].coords - pair[1].coords).norm();
|
||||
if length >= min_surface_path_length {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
(mesh, outline, surface)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
surfaces
|
||||
.sort_unstable_by(|(a, _, _), (b, _, _)| a.aabb.min.z.partial_cmp(&b.aabb.min.z).unwrap());
|
||||
|
||||
console_log!("Creating Walls");
|
||||
let wallMesh = Mesh::from(slicable_triangles);
|
||||
let walls = wallMesh.slice_paths(Axis::Z, layer_height);
|
||||
let mut walls = wallMesh
|
||||
.slice_paths(Axis::Z, layer_height)
|
||||
.flat_map(|paths| paths.into_iter().filter(|path| path.closed))
|
||||
.collect::<VecDeque<_>>();
|
||||
let mut active_surfaces = Vec::new();
|
||||
let mut out = Vec::new();
|
||||
|
||||
/*console_log!("Tracing Surfaces");
|
||||
let a = max_angle.tan();
|
||||
for slice in &mut slices {
|
||||
for surface in &surfaces {
|
||||
if surface.aabb.min.z <= slice.z && surface.aabb.max.z > slice.z {
|
||||
trace_surface(slice, surface, a);
|
||||
console_log!("Resolving dependencies");
|
||||
while let Some(mut wall) = walls.pop_front() {
|
||||
active_surfaces.extend(
|
||||
surfaces
|
||||
.extract_if(|surface| surface.0.aabb.min.z <= wall.aabb.max.z)
|
||||
.map(|surface| (surface, Vec::new())),
|
||||
);
|
||||
|
||||
let deactivate =
|
||||
active_surfaces.extract_if(|element| element.0 .0.aabb.max.z < wall.aabb.min.z);
|
||||
for (surface, surface_walls) in deactivate {
|
||||
for ring in surface.1 {
|
||||
out.push(ring.points);
|
||||
}
|
||||
for path in surface.2 {
|
||||
out.push(path.path);
|
||||
}
|
||||
for wall in surface_walls {
|
||||
walls.push_front(wall);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
for surface in active_surfaces.iter_mut() {
|
||||
let held = wall
|
||||
.points
|
||||
.extract_if(|point| !trace_surface(&point, &surface.0 .0, max_angle))
|
||||
.collect::<Vec<_>>();
|
||||
if !held.is_empty() {
|
||||
surface.1.push(SlicePath {
|
||||
points: held,
|
||||
..wall
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if !wall.points.is_empty() {
|
||||
out.push(wall.points);
|
||||
}
|
||||
}
|
||||
|
||||
console_log!("Done");
|
||||
SliceResult {
|
||||
slices: surfaces
|
||||
.flatten()
|
||||
slices: out
|
||||
.into_iter()
|
||||
.map(|slice| Slice::Ring {
|
||||
position: slice
|
||||
.path
|
||||
.into_iter()
|
||||
.flat_map(|point| [point.x as f32, point.y as f32, point.z as f32])
|
||||
.collect(),
|
||||
})
|
||||
/*.chain(walls.flatten().map(|slice| {
|
||||
.collect(),
|
||||
}
|
||||
/*SliceResult {
|
||||
slices: surfaces
|
||||
.into_iter()
|
||||
.flat_map(|(_, outlines, slices)| {
|
||||
outlines
|
||||
.into_iter()
|
||||
.map(|slice| Slice::Ring {
|
||||
position: slice
|
||||
.points
|
||||
.into_iter()
|
||||
.flat_map(|point| [point.x as f32, point.y as f32, point.z as f32])
|
||||
.collect(),
|
||||
})
|
||||
.chain(slices.into_iter().map(|slice| {
|
||||
Slice::Ring {
|
||||
position: slice
|
||||
.path
|
||||
.into_iter()
|
||||
.flat_map(|point| [point.x as f32, point.y as f32, point.z as f32])
|
||||
.collect(),
|
||||
}
|
||||
}))
|
||||
})
|
||||
.chain(walls.flatten().map(|slice| {
|
||||
Slice::Ring {
|
||||
position: slice
|
||||
.points
|
||||
@@ -108,28 +194,7 @@ pub fn slice(
|
||||
.flat_map(|point| [point.x as f32, point.y as f32, point.z as f32])
|
||||
.collect(),
|
||||
}
|
||||
}))*/
|
||||
/*.chain(surfaces.into_iter().map(|surface| {
|
||||
Slice::Surface {
|
||||
position: surface
|
||||
.triangles
|
||||
.into_iter()
|
||||
.flat_map(|triangle| {
|
||||
[
|
||||
triangle.a.x as f32,
|
||||
triangle.a.y as f32,
|
||||
triangle.a.z as f32,
|
||||
triangle.b.x as f32,
|
||||
triangle.b.y as f32,
|
||||
triangle.b.z as f32,
|
||||
triangle.c.x as f32,
|
||||
triangle.c.y as f32,
|
||||
triangle.c.z as f32,
|
||||
]
|
||||
})
|
||||
.collect(),
|
||||
}
|
||||
}))*/
|
||||
}))
|
||||
.collect(),
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
@@ -2,9 +2,10 @@ use nalgebra::Vector3;
|
||||
|
||||
use super::FloatValue;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(usize)]
|
||||
pub enum Axis {
|
||||
#[default]
|
||||
X = 0,
|
||||
Y = 1,
|
||||
Z = 2,
|
||||
|
||||
@@ -13,6 +13,10 @@ pub struct Line3 {
|
||||
}
|
||||
|
||||
impl Line3 {
|
||||
pub fn new(start: Point3<FloatValue>, end: Point3<FloatValue>) -> Self {
|
||||
Self { start, end }
|
||||
}
|
||||
|
||||
pub fn norm(&self) -> FloatValue {
|
||||
(self.end - self.start).norm()
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use super::{
|
||||
axis::Axis,
|
||||
base_slices::BaseSlice,
|
||||
line::Line3,
|
||||
slice_path::{SlicePath, SurfacePathIterator},
|
||||
triangle::Triangle,
|
||||
FloatValue,
|
||||
@@ -60,7 +61,7 @@ impl Mesh {
|
||||
/ slice_height)
|
||||
.floor() as usize;
|
||||
|
||||
(0..layer_count).map(move |i| {
|
||||
(0..=layer_count).map(move |i| {
|
||||
let layer = i as FloatValue * slice_height + self.aabb.min[axis as usize];
|
||||
let mut base_slice = BaseSlice {
|
||||
i,
|
||||
@@ -107,4 +108,79 @@ impl Mesh {
|
||||
base_slice
|
||||
})
|
||||
}
|
||||
|
||||
pub fn outline_base_slice(&self, axis: Axis) -> BaseSlice {
|
||||
let mut base_slice = BaseSlice {
|
||||
i: 0,
|
||||
d: 0.0,
|
||||
axis,
|
||||
lines: vec![],
|
||||
};
|
||||
'triangle: for (triangle_index, triangle) in self.triangles.iter().enumerate() {
|
||||
let mut stack = Vec::<usize>::with_capacity(self.bvh.nodes.len());
|
||||
stack.push(0);
|
||||
let mut ab = false;
|
||||
let mut ac = false;
|
||||
let mut bc = false;
|
||||
while let Some(i) = stack.pop() {
|
||||
match self.bvh.nodes[i] {
|
||||
BvhNode::Node {
|
||||
parent_index: _,
|
||||
child_l_index,
|
||||
child_l_aabb,
|
||||
child_r_index,
|
||||
child_r_aabb,
|
||||
} => {
|
||||
let coords = [triangle.a, triangle.b, triangle.c];
|
||||
macro_rules! match_aabb {
|
||||
($side:expr) => {
|
||||
coords
|
||||
.iter()
|
||||
.map(|point| {
|
||||
$side.approx_contains_eps(point, FloatValue::EPSILON) as i32
|
||||
})
|
||||
.sum::<i32>()
|
||||
>= 2
|
||||
};
|
||||
}
|
||||
if match_aabb!(child_l_aabb) {
|
||||
stack.push(child_l_index);
|
||||
}
|
||||
if match_aabb!(child_r_aabb) {
|
||||
stack.push(child_r_index);
|
||||
}
|
||||
}
|
||||
BvhNode::Leaf {
|
||||
parent_index: _,
|
||||
shape_index,
|
||||
} => {
|
||||
if triangle_index == shape_index {
|
||||
continue;
|
||||
}
|
||||
let other = &self.triangles[shape_index];
|
||||
let a = other.has_point(triangle.a);
|
||||
let b = other.has_point(triangle.b);
|
||||
let c = other.has_point(triangle.c);
|
||||
ab = ab || (a && b);
|
||||
ac = ac || (a && c);
|
||||
bc = bc || (b && c);
|
||||
|
||||
if ab && ac && bc {
|
||||
continue 'triangle;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if !ab {
|
||||
base_slice.lines.push(Line3::new(triangle.a, triangle.b));
|
||||
}
|
||||
if !ac {
|
||||
base_slice.lines.push(Line3::new(triangle.a, triangle.c));
|
||||
}
|
||||
if !bc {
|
||||
base_slice.lines.push(Line3::new(triangle.b, triangle.c));
|
||||
}
|
||||
}
|
||||
base_slice
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ use nalgebra::{vector, Point, TAffine, Transform, Vector2, Vector3};
|
||||
use super::FloatValue;
|
||||
|
||||
pub trait Sdf<const D: usize> {
|
||||
fn sdf(&self, p: Point<FloatValue, D>) -> FloatValue;
|
||||
fn sdf(&self, p: &Point<FloatValue, D>) -> FloatValue;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
@@ -19,7 +19,7 @@ impl SdfSphere {
|
||||
}
|
||||
|
||||
impl Sdf<3> for SdfSphere {
|
||||
fn sdf(&self, p: Point<FloatValue, 3>) -> FloatValue {
|
||||
fn sdf(&self, p: &Point<FloatValue, 3>) -> FloatValue {
|
||||
p.coords.norm() - self.radius
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,7 @@ impl SdfBox {
|
||||
}
|
||||
|
||||
impl Sdf<3> for SdfBox {
|
||||
fn sdf(&self, p: Point<FloatValue, 3>) -> FloatValue {
|
||||
fn sdf(&self, p: &Point<FloatValue, 3>) -> FloatValue {
|
||||
let q = p.coords.abs() - self.size.coords;
|
||||
q.sup(&Vector3::zeros()).add_scalar(q.max().min(0.0)).norm()
|
||||
}
|
||||
@@ -56,7 +56,7 @@ impl SdfInfiniteCone {
|
||||
}
|
||||
|
||||
impl Sdf<3> for SdfInfiniteCone {
|
||||
fn sdf(&self, p: Point<FloatValue, 3>) -> FloatValue {
|
||||
fn sdf(&self, p: &Point<FloatValue, 3>) -> FloatValue {
|
||||
let q = vector![p.coords.xy().norm(), p.z];
|
||||
let d = (q - self.angle.scale(q.dot(&self.angle).max(0.0))).norm();
|
||||
if q.x * self.angle.y - q.y * self.angle.x > 0.0 {
|
||||
@@ -80,8 +80,8 @@ impl<T: Sdf<3>> SdfTransform<T> {
|
||||
}
|
||||
|
||||
impl<T: Sdf<3>> Sdf<3> for SdfTransform<T> {
|
||||
fn sdf(&self, p: Point<FloatValue, 3>) -> FloatValue {
|
||||
self.sdf.sdf(self.transform.inverse_transform_point(&p))
|
||||
fn sdf(&self, p: &Point<FloatValue, 3>) -> FloatValue {
|
||||
self.sdf.sdf(&self.transform.inverse_transform_point(p))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,8 +98,8 @@ impl<const D: usize, T: Sdf<D>> SdfScale<D, T> {
|
||||
}
|
||||
|
||||
impl<const D: usize, T: Sdf<D>> Sdf<D> for SdfScale<D, T> {
|
||||
fn sdf(&self, p: Point<FloatValue, D>) -> FloatValue {
|
||||
self.sdf.sdf(p / self.scale) * self.scale
|
||||
fn sdf(&self, p: &Point<FloatValue, D>) -> FloatValue {
|
||||
self.sdf.sdf(&(p / self.scale)) * self.scale
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ impl<T: Sdf<3>> SdfOnion<T> {
|
||||
}
|
||||
|
||||
impl<T: Sdf<3>> Sdf<3> for SdfOnion<T> {
|
||||
fn sdf(&self, p: Point<FloatValue, 3>) -> FloatValue {
|
||||
fn sdf(&self, p: &Point<FloatValue, 3>) -> FloatValue {
|
||||
self.sdf.sdf(p).abs() - self.thickness
|
||||
}
|
||||
}
|
||||
@@ -134,7 +134,7 @@ impl<const D: usize, T: Sdf<D>, U: Sdf<D>> SdfUnion<D, T, U> {
|
||||
}
|
||||
|
||||
impl<const D: usize, T: Sdf<D>, U: Sdf<D>> Sdf<D> for SdfUnion<D, T, U> {
|
||||
fn sdf(&self, p: Point<FloatValue, D>) -> FloatValue {
|
||||
fn sdf(&self, p: &Point<FloatValue, D>) -> FloatValue {
|
||||
self.sdf_a.sdf(p).min(self.sdf_b.sdf(p))
|
||||
}
|
||||
}
|
||||
@@ -152,7 +152,7 @@ impl<const D: usize, T: Sdf<D>, U: Sdf<D>> SdfIntersection<D, T, U> {
|
||||
}
|
||||
|
||||
impl<const D: usize, T: Sdf<D>, U: Sdf<D>> Sdf<D> for SdfIntersection<D, T, U> {
|
||||
fn sdf(&self, p: Point<FloatValue, D>) -> FloatValue {
|
||||
fn sdf(&self, p: &Point<FloatValue, D>) -> FloatValue {
|
||||
self.sdf_a.sdf(p).max(self.sdf_b.sdf(p))
|
||||
}
|
||||
}
|
||||
@@ -170,7 +170,7 @@ impl<const D: usize, T: Sdf<D>, U: Sdf<D>> SdfDifference<D, T, U> {
|
||||
}
|
||||
|
||||
impl<const D: usize, T: Sdf<D>, U: Sdf<D>> Sdf<D> for SdfDifference<D, T, U> {
|
||||
fn sdf(&self, p: Point<FloatValue, D>) -> FloatValue {
|
||||
fn sdf(&self, p: &Point<FloatValue, D>) -> FloatValue {
|
||||
self.sdf_a.sdf(p).max(-self.sdf_b.sdf(p))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use std::ops::RangeInclusive;
|
||||
use std::{collections::VecDeque, ops::RangeInclusive};
|
||||
|
||||
use approx::relative_eq;
|
||||
use bvh::aabb::Aabb;
|
||||
@@ -6,7 +6,7 @@ use nalgebra::Point3;
|
||||
|
||||
use super::{axis::Axis, mesh::Mesh, FloatValue};
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Default)]
|
||||
pub struct SlicePath {
|
||||
pub i: usize,
|
||||
pub d: FloatValue,
|
||||
@@ -75,6 +75,34 @@ impl SurfacePathIterator {
|
||||
}
|
||||
}
|
||||
|
||||
fn squish(points: &mut Vec<Point3<FloatValue>>, axis: Axis, d: FloatValue) {
|
||||
macro_rules! ax {
|
||||
($p: expr) => {
|
||||
$p.coords[axis as usize]
|
||||
};
|
||||
}
|
||||
let first = ax!(points.first().unwrap());
|
||||
let left = points.iter().position(|p| first - ax!(p) > d);
|
||||
let last = ax!(points.last().unwrap());
|
||||
let right = points.iter().rposition(|p| ax!(p) - last > d);
|
||||
|
||||
if let (Some(left), Some(right)) = (left, right) {
|
||||
if left > right {
|
||||
// TODO
|
||||
return;
|
||||
}
|
||||
let total = ax!(points[left + 1]) - first;
|
||||
let delta = ax!(points[left]) - ax!(points[left + 1]);
|
||||
points.splice(
|
||||
0..left,
|
||||
vec![points[left].lerp(&points[left + 1], (d - total) / delta)],
|
||||
);
|
||||
|
||||
let total = last - ax!(points[right + 1]);
|
||||
let delta = ax!(points[right + 1]) - ax!(points[right]);
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for SurfacePathIterator {
|
||||
type Item = SurfacePath;
|
||||
|
||||
@@ -82,8 +110,10 @@ impl Iterator for SurfacePathIterator {
|
||||
self.slices.retain_mut(|slice| !slice.is_empty());
|
||||
|
||||
let (h_axis, _) = self.axis.other();
|
||||
let mut iter = self.slices.iter_mut();
|
||||
|
||||
let ring = self.slices.first_mut()?.pop()?;
|
||||
let mut ring = iter.next()?.pop()?;
|
||||
// TODO: squish(&mut ring.points, h_axis, self.nozzle_width);
|
||||
let mut item = Self::Item {
|
||||
i: ring.i..=ring.i,
|
||||
d: ring.d..=ring.d,
|
||||
@@ -92,7 +122,7 @@ impl Iterator for SurfacePathIterator {
|
||||
path: ring.points,
|
||||
};
|
||||
|
||||
for slice in self.slices.iter_mut().skip(1) {
|
||||
for slice in iter {
|
||||
if *item.i.end() != slice[0].i - 1 {
|
||||
break;
|
||||
}
|
||||
@@ -136,9 +166,11 @@ impl Iterator for SurfacePathIterator {
|
||||
}
|
||||
|
||||
if let Some(mut ring) = index.map(|i| slice.remove(i)) {
|
||||
// TODO: squish(&mut ring.points, h_axis, self.nozzle_width);
|
||||
if needs_reverse {
|
||||
ring.points.reverse();
|
||||
}
|
||||
|
||||
item.i = *item.i.start()..=ring.i;
|
||||
item.d = *item.d.start()..=ring.d;
|
||||
item.path.append(&mut ring.points);
|
||||
|
||||
@@ -1,47 +1,48 @@
|
||||
use bvh::bvh::BvhNode;
|
||||
use nalgebra::Point3;
|
||||
|
||||
use super::{mesh::Mesh, slice_path::SlicePath, z_projection::ToolpathIntersects, FloatValue};
|
||||
use crate::slicer::sdf::Sdf3dModifiers;
|
||||
|
||||
pub fn trace_surface(slice: &mut SlicePath, surface: &Mesh, a: FloatValue) {
|
||||
slice.points.retain_mut(|point| {
|
||||
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 child_l_aabb.toolpath_intersects(point, a) {
|
||||
stack.push(child_l_index);
|
||||
}
|
||||
if child_r_aabb.toolpath_intersects(point, a) {
|
||||
stack.push(child_r_index);
|
||||
}
|
||||
use super::{
|
||||
mesh::Mesh,
|
||||
sdf::{Sdf, SdfInfiniteCone},
|
||||
z_projection::ToolpathIntersects,
|
||||
FloatValue,
|
||||
};
|
||||
|
||||
pub fn trace_surface(point: &Point3<FloatValue>, surface: &Mesh, a: FloatValue) -> bool {
|
||||
let sdf = SdfInfiniteCone::new(a);
|
||||
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 child_l_aabb.toolpath_intersects(point, a) {
|
||||
stack.push(child_l_index);
|
||||
}
|
||||
BvhNode::Leaf {
|
||||
parent_index: _,
|
||||
shape_index,
|
||||
} => {
|
||||
let triangle = &surface.triangles[shape_index];
|
||||
macro_rules! check {
|
||||
( $var:ident ) => {{
|
||||
let x = point.x - triangle.$var.x;
|
||||
let y = point.y - triangle.$var.y;
|
||||
(point.z > triangle.aabb.min.z
|
||||
&& FloatValue::sqrt(x * x + y * y)
|
||||
< (triangle.$var.z - point.z).abs() * a)
|
||||
}};
|
||||
}
|
||||
if check!(a) || check!(b) || check!(c) {
|
||||
return false;
|
||||
}
|
||||
if child_r_aabb.toolpath_intersects(point, a) {
|
||||
stack.push(child_r_index);
|
||||
}
|
||||
}
|
||||
BvhNode::Leaf {
|
||||
parent_index: _,
|
||||
shape_index,
|
||||
} => {
|
||||
let triangle = &surface.triangles[shape_index];
|
||||
if sdf.translate(triangle.a).sdf(point) < 0.0
|
||||
|| sdf.translate(triangle.b).sdf(point) < 0.0
|
||||
|| sdf.translate(triangle.c).sdf(point) < 0.0
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
true
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ impl Triangle {
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
normal: (b - a).cross(&(c - a)).into(),
|
||||
normal: (b - a).cross(&(c - a)).normalize(),
|
||||
node_index: 0,
|
||||
aabb,
|
||||
}
|
||||
@@ -44,13 +44,6 @@ impl Triangle {
|
||||
self.has_point(other.a) || self.has_point(other.b) || self.has_point(other.c)
|
||||
}
|
||||
|
||||
pub fn shares_edge_with_triangle(&self, other: Triangle) -> bool {
|
||||
let a = self.has_point(other.a);
|
||||
let b = self.has_point(other.b);
|
||||
let c = self.has_point(other.c);
|
||||
a && b || a && c || b && c
|
||||
}
|
||||
|
||||
pub fn intersect(&self, value: FloatValue, axis: usize) -> Option<Line3> {
|
||||
let mut intersection = Vec::<Point3<FloatValue>>::with_capacity(3);
|
||||
let mut last = &self.c;
|
||||
|
||||
Reference in New Issue
Block a user