1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
use core::{marker::PhantomData, ops::RangeInclusive};
use rust_gpu_bridge::prelude::{Vec2, Vec3};
use type_fields::field::Field;
use crate::{
default,
signed_distance_field::{
adapters::normals::CentralDiffNormal, attributes::distance::Distance, SignedDistanceField,
},
};
#[derive(Debug, Clone, PartialEq)]
pub struct BoundChecker<Dim, Sdf> {
pub sdf: Sdf,
pub samples: RangeInclusive<isize>,
pub step: f32,
pub epsilon: f32,
pub _phantom: PhantomData<Dim>,
}
impl<Dim, Sdf> Default for BoundChecker<Dim, Sdf>
where
Sdf: Default,
{
fn default() -> Self {
BoundChecker {
sdf: default(),
samples: -10..=10,
step: 2.0 / 20.0,
epsilon: 0.5,
_phantom: default(),
}
}
}
impl<Dim, Sdf> BoundChecker<Dim, Sdf> {
const DERIV_EPSILON: f32 = 0.000005;
}
impl<Sdf> BoundChecker<Vec2, Sdf>
where
Sdf: SignedDistanceField<Vec2, Distance> + Clone + 'static,
{
pub fn is_field(self) -> bool {
!self.is_bound()
}
pub fn is_bound(self) -> bool {
for x in self.samples.clone() {
for y in self.samples.clone() {
let pos = Vec2::new(x as f32, y as f32) * self.step;
let normal = *CentralDiffNormal::<Sdf>::new(self.sdf.clone(), self.step)
.with(CentralDiffNormal::epsilon, self.epsilon)
.evaluate(pos);
let a = *self.sdf.evaluate(pos - normal * self.epsilon);
let b = *self.sdf.evaluate(pos + normal * self.epsilon);
let deriv = b - a;
if deriv.abs() - (self.epsilon * 2.0) > Self::DERIV_EPSILON {
panic!("{deriv:?} at position {pos:?} is non-unit, resulting in a bound.");
return true;
}
}
}
false
}
}
impl<Sdf> BoundChecker<Vec3, Sdf>
where
Sdf: SignedDistanceField<Vec3, Distance> + Clone + 'static,
{
pub fn is_field(self) -> bool {
!self.is_bound()
}
pub fn is_bound(self) -> bool {
for x in self.samples.clone() {
for y in self.samples.clone() {
for z in self.samples.clone() {
let pos = Vec3::new(x as f32, y as f32, z as f32) * self.step;
let normal = *CentralDiffNormal::<Sdf>::new(self.sdf.clone(), self.step)
.with(CentralDiffNormal::epsilon, self.epsilon)
.evaluate(pos);
let a = *self.sdf.evaluate(pos - normal * self.epsilon);
let b = *self.sdf.evaluate(pos + normal * self.epsilon);
let deriv = b - a;
if deriv.abs() - (self.epsilon * 2.0) > Self::DERIV_EPSILON {
panic!("{deriv:?} at position {pos:?} is non-unit, resulting in a bound.");
return true;
}
}
}
}
false
}
}