Skip to content

Commit

Permalink
Fix SDF function
Browse files Browse the repository at this point in the history
So that it is actually signed.
Also some documentation.
  • Loading branch information
clbarnes committed Dec 21, 2023
1 parent 31e78de commit 0e1fab4
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 5 deletions.
18 changes: 18 additions & 0 deletions python/ncollpyde/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,24 @@ def _validate_points(self, *points: ArrayLike) -> List[NDArray]:
def _sdf_intersections(
self, points: ArrayLike, vectors: ArrayLike, threads: Optional[bool] = None
) -> Tuple[NDArray, NDArray]:
"""Compute values required for signed distance field.
:param points: Nx3 ndarray of floats
Points to calculate the distance from.
Should be within the axis-aligned bounding box of the mesh.
:param vectors: Nx3 ndarray of floats
Directions to fire rays from the given points.
:param threads: None,
Whether to parallelise the queries. If ``None`` (default),
refer to the instance's ``threads`` attribute.
:return: 2-tuple N-length np.ndarrays of floats.
The first is the distance,
which is negative if the collision is with a backface,
and infinity if there is no collision.
The second is the dot product of the vector
with the normal of the feature the ray hit,
NaN if there was no collision.
"""
p, v = self._validate_points(points, vectors)
return self._impl.sdf_intersections(p, v, self._interpret_threads(threads))

Expand Down
4 changes: 1 addition & 3 deletions src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,7 @@ impl TriMeshWrapper {
let v = vs
.iter()
.fold(Vec::with_capacity(vs.len() * 3), |mut out, p| {
out.push(p.x);
out.push(p.y);
out.push(p.z);
out.extend(p.iter().cloned());
out
});
Array2::from_shape_vec((vs.len(), 3), v)
Expand Down
9 changes: 7 additions & 2 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ pub fn points_cross_mesh_info(
}

pub fn dist_from_mesh(mesh: &TriMesh, point: &Point<f64>, rays: Option<&[Vector<f64>]>) -> f64 {
let mut dist = mesh.distance_to_point(&Isometry::identity(), point, true);
let mut dist = mesh.distance_to_local_point(point, true);
if let Some(r) = rays {
if mesh_contains_point(mesh, point, r) {
dist = -dist;
Expand Down Expand Up @@ -108,7 +108,12 @@ pub fn sdf_inner(
if let Some(inter) = mesh.cast_local_ray_and_get_normal(
&ray, diameter, false, // unused
) {
(inter.toi, v.dot(&inter.normal))
let dot = v.dot(&inter.normal);
if mesh.is_backface(inter.feature) {
(inter.toi, dot)
} else {
(-inter.toi, dot)
}
} else {
(Precision::INFINITY, Precision::NAN)
}
Expand Down

0 comments on commit 0e1fab4

Please sign in to comment.