Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added functions to get distances to primatives and meshes #148

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

weymouth
Copy link

Created new file distances.jl which computes the absolute_distance and
the signed_distance to triangle meshes, HyperSpheres and HyperRects.
These functions have been exported.

The sphere and rect signed functions are straightforward, and there is a
fallback for absolute_distance to equal abs(signed_distance).

Dealing with triangles and triangle meshes is less straightforward. The
absolute distance to a triangle is a well defined (if complex) function,
but the signed distance isn't. I've used the signed distance to the
plane aligned with the triangle. The signed distance to a mesh of
triangles is then the signed distance to the convex union of those
planes. This is simple, but obviously has drawbacks.

Alternatively, the absolute distance to a mesh of triangles is robust,
and could be supplimented with a global operation (like the winding
number) to determine a sign.

I've added a 27 tests to runtests which illustrate some of these issues.

Created new file distances.jl which computes the absolute_distance and 
the signed_distance to triangle meshes, HyperSpheres and HyperRects. 
These functions have been exported.

The sphere and rect signed functions are straightforward, and there is a 
fallback for absolute_distance to equal abs(signed_distance).

Dealing with triangles and triangle meshes is less straightforward. The 
absolute distance to a triangle is a well defined (if complex) function, 
but the signed distance isn't. I've used the signed distance to the 
plane aligned with the triangle. The signed distance to a mesh of 
triangles is then the signed distance to the convex union of those 
planes. This is simple, but obviously has drawbacks.

Alternatively, the absolute distance to a mesh of triangles is robust, 
and could be supplimented with a global operation (like the winding 
number) to determine a sign. 

I've added a 27 tests to runtests which illustrate some of these issues.
@sjkelly
Copy link
Member

sjkelly commented Jul 26, 2021

For reference I have a few more of these functions here: https://github.com/sjkelly/Descartes.jl/blob/master/src/frep.jl

@weymouth
Copy link
Author

For reference I have a few more of these functions here: https://github.com/sjkelly/Descartes.jl/blob/master/src/frep.jl

That's great. Do you think it makes sense to merge some of them?

src/distances.jl Outdated Show resolved Hide resolved
@sjkelly
Copy link
Member

sjkelly commented Jul 26, 2021

Yes, feel free copy whatever is useful from Descartes, assuming people are on board with adding these distance functions.

@SimonDanisch
Copy link
Member

Thank you :)
Yeah I don't see why not ;)

@weymouth
Copy link
Author

So the three primitives I haven't covered yet are Particle (trivial) Cylinder and Pyramid.

It looks like Cylinder is defined with a general line segment and a radius (this is different than Descartes, so I can't copy the code over). I can generalize the Rect corner distance function to cover these.

A Pyramid is just a union of planes, so it'll be caught with a fallback of meshing anything meshable.


Return the minimum absolute distance from point `p` to any Triangle in `mesh`.
"""
absolute_distance(p,mesh::AbstractMesh) = minimum(t->absolute_distance(p,t), nonzero(mesh))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is going to scale poorly on performance, so I'm not sure if this will give the right experience. IIUC for Mesh->SDF you normally want to bin faces in an octree, kd tree, or other, to try to reduce the search space first.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very true. This is where some help from people more familiar with these kind of approaches would be great.

@sjkelly
Copy link
Member

sjkelly commented Jul 27, 2021

I'm on the fence about distances for AbstractMesh. There are techniques to speed this up, and what is in here is of bad search complexity for anything decently large. Moreso if you want to do uniform sampling of the mesh. To do it fast, we would need some other dependencies, that would introduce a circular dependents. I'm a little out of the loop on invalidations and how they would affect the design decision here as well.

@weymouth
Copy link
Author

By uniform sampling, do you mean filling an entire array with the SDF of a mesh? Because that is my use case.

In fact, I only need this to be accurate fairly close to the mesh, so my plan was to loop through all the mesh faces and fill the array points in the face's bounding box. So this would scale with the number of faces times number of array points per face.

For the general case, I agree that you need some kind of tree method, but this requires some data-structures be set up within GeometryBasics. You could also apply a tree to the array, such as a multi-grid search.

@sjkelly
Copy link
Member

sjkelly commented Jul 27, 2021

Nice! This would be useful to a few other packages, as-is so I am for it.
I realize too you could integrate with Adaptive Distance Fields and address a good chunk of performance issues. Also Interpolations.jl would help in many cases.

@weymouth
Copy link
Author

Hold the phone. Looking at AdaptiveDistanceFields (which looks cool) EnhancedGJK already has a function ReferenceDistance.signed_distance to a mesh of simplexes, which means I don't need to implement it again here.

@weymouth
Copy link
Author

But EnhancedGJK only works with GeometryTypes!!?!

@SimonDanisch
Copy link
Member

But EnhancedGJK only works with GeometryTypes!!?!

It's usually not too hard to upgrade to GeometryBasics, since most APIs have stayed fairly similar!

@weymouth
Copy link
Author

weymouth commented Aug 3, 2021

What is the process/etiquette for this? I've raised an issue on EnhancedGJK but not heard back. JuliaRobotics/EnhancedGJK.jl#39

@SimonDanisch
Copy link
Member

Good question... I think those may not be maintained anymore... We can ask, if they want to move the package to JuliaGeometry, so it can be maintained by more people!

@sjkelly
Copy link
Member

sjkelly commented Aug 3, 2021

FWIW the GT->GB transition is a pretty big ask. A huge amount of their stack is in GeometryTypes, with EnhancedGJK being pretty key foundation. One approach would be to use import rather than using and support both APIs in EnhancedGJK. I did this in Meshing.jl because many of my users were still on GeometryTypes.
https://github.com/JuliaGeometry/Meshing.jl/blob/master/src/geometrybasics_api.jl
https://github.com/JuliaGeometry/Meshing.jl/blob/master/src/geometrytypes_api.jl

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants