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

Returning mesh faces #33

Open
ceesem opened this issue Dec 8, 2023 · 8 comments
Open

Returning mesh faces #33

ceesem opened this issue Dec 8, 2023 · 8 comments

Comments

@ceesem
Copy link

ceesem commented Dec 8, 2023

Thanks for making this package! I think we're going to start using it more and more.

One thing that I'd like to use this package for is to compute the shape diameter function for vertices on a mesh. The way I had been doing it with pyembree (RIP), involved casting a cone of rays from each mesh vertex inward to the other side. I then want to weight the rays by the dot product of the ray with the face normal that it hits (i.e. I want to weight 90-degree hits more heavily than glancing hits). With pyembree, this was easy because the ray intersector class returned the index of the mesh face that was hit. Here, I get the locations but no face index. This can probably be massaged to do what I want, but would it be possible to add the mesh face index to the responses in Volume.intersects, in addition to the exact location point?

@clbarnes
Copy link
Owner

clbarnes commented Dec 9, 2023

One thing I'd be wary of is what happens when it hits an edge or vertex - already a dicey situation #3 . On the rust side, the library knows whether it's a face, edge, or vertex which has been hit (and the index of it), so if there's a nice way to express that to the python user we could use that but otherwise it's a whole other array to return. Returning all faces means a ragged array which isn't as nice to cross the rust/python barrier with. Is this whole algorithm, or some subset of it something broadly useful enough to go in the library directly, or at least to make a distinct-enough method?

@ceesem
Copy link
Author

ceesem commented Dec 13, 2023

Edges are are also dicey in embree (I think they just don't count as a hit, actually, at least in standard 'performance' mode), but a nice thing about SDF is that you cast a lot of rays and average them so unless you're very, very unlucky you can throw out outliers.

I think if I were in your shoes, I'd make this an optional output and return both intersect_category and intersect_index where the former is [0,1,2] for vertices/edges/faces and then a list of indices with the same length and mixing up whatever index is appropriate for that row. I think any user who needs this information will be savvy enough to handle getting what they want out of that information. Given that hits to edges or vertices can be dicey in general, maybe it's useful to expose that information anyway.

I'm borrowing the algorithm itself from CGAL, but the advantage of doing the implementation myself is that I can only run it on a subset of the mesh (e.g. along a path along the mesh) for performance, since neuronal meshes can be very large and radii are smoothly varying. I'd be more than happy to just call an SDF function, though, if you wanted to implement it! All I'd ask is that having an optional list of vertices to compute SDF from would be handy.

@clbarnes
Copy link
Owner

clbarnes commented Dec 14, 2023

Looks like the underlying rust library will return the normal directly, so a more useful function for your use case might be something with the same arguments as intersects, but a return value of (ray_index, intersection_distance, ray_dot_norm)? Possibly with the feature type as well. If your (embree-based) implementation is public I can take a look at how tricky it would be to do entirely in rust, but otherwise I could do as above on the rust side and we could do the rest on the python side; as this set of return values may be fairly specific to this algorithm anyway.

@ceesem
Copy link
Author

ceesem commented Dec 14, 2023

The dot product of the ray with the face normal would be amazing, even better for this purpose! I think the feature type sounds generally useful, but obviously that would be important depending on how the dot product is returned for such values.

My SDF implementation is here on the meshparty repo. I'd also recommend reading the CGAL documentation, as I'm sure there are some implementation decisions one has to make and I wouldn't be surprised if I cut a corner or two relative to the CGAL version, since my use case was fairly specific.

@clbarnes
Copy link
Owner

Ah yes, that looks a bit more involved than I have time for at the moment - how about a private(ish) method:

  • inputs
    • N starting points
    • N directions
  • outputs
    • N distances to intersection (might be infinity if no intersection)
    • N dot products of ray and intersected feature normal (might be nan if no intersection)

Because in this case we expect most of the rays to intersect and all we'd be using the feature ID and intersection location for is to get the distance and dot norm anyway. Then your python could hook into that (ideally to be upstreamed here).

@ceesem
Copy link
Author

ceesem commented Dec 20, 2023

That would be awesome, I would use that immediately!

@clbarnes
Copy link
Owner

Not to put myself out of a job, but if you haven't checked it out already it may be worth looking into embreex in case it saves a larger porting effort. As it stands, though, I've got a PR up #34 with this internal method - if you have any test data from your current implementation that would be handy to have.

@ceesem
Copy link
Author

ceesem commented Dec 22, 2023

I have no clue how I missed that, having made a number of searches for exactly something like that. Thanks for the link.

That said, I also like the idea of not having Intel in the loop given that a cursory search suggests they aren't working too hard on Apple Silicon optimization. It's not urgent, nor would it be more than a couple of line tweak for porting, so I think it'll be fun to port over to what you've been working on. Plus it's always nice to work with those you know. :)

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

No branches or pull requests

2 participants