alecjacobson / gptoolbox

Matlab toolbox for Geometry Processing.
MIT License
628 stars 166 forks source link

Can gptoolbox compute the boundary of a triangular mesh defined by rays? #123

Closed ThSGM closed 3 years ago

ThSGM commented 3 years ago

This is perhaps a better question for the Math Stack Exchange, but gptoolbox has proven to be such a powerful set of tools for me that I wonder if it has a functionality for this.

Given a triangular mesh, I was interested in computing the visible 'outer' edges. These are highlighted by the white markers below.

Screenshot 2021-09-13 at 01 15 09

The red edge can be computed, either using exterior_edges or outline (I am actually not sure what the difference is).

I coded up my own ad-hoc way of doing it. Basically along this procedure:

%% For each vertex in the mesh, we: 
%       - Construct a circle about the vertex with normal oriented towards
%           the source point
%       - Shoot rays for a series of points (theta) around the circle
%       - If any rays fail to intersect the surface within dist_large of the
%               distance from origin to the circle center we mark as a
%               boundary

Basically, I construct a cone about the source point, oriented towards each vertex point. I shoot a bunch of rays in that cone and look for those points where at least one ray fails to intersect the surface 'nearby'.

It's not a terrible algorithm but it seems awfully ad hoc, requires manual tweaking of the cone dimensions, and can also miss sections of the edge.

Is there a better way to do this?

I have uploaded the script here.

ThSGM commented 3 years ago

I just realised with a moment of thinking this morning that what I might be asking for are those faces whose normal are approximately perpendicular with the direction vector...I shall attempt to think more about this.

ThSGM commented 3 years ago

Ah, yes indeed a much rougher scheme can be done by just finding those locations on the surface where the normal is perpendicular to the directional normal from the observer. For example, I calculated the per-edge normal for each edge, then plotted those edges satisfying that condition.

Screenshot 2021-09-13 at 17 06 46

It does not work amazingly well, so I am curious if there are better schemes out there (what do ray tracers do?).

But this is sufficient for now. Thank you to Alec and his team for creating such a great package.

alecjacobson commented 3 years ago

Check out split_backfacing. The idea is to classify each face as front or back facing. Then you can take the boundaries of those to get a set of silhouette or occluding contour curves.

ThSGM commented 3 years ago

Check out split_backfacing. The idea is to classify each face as front or back facing. Then you can take the boundaries of those to get a set of silhouette or occluding contour curves.

I am ashamed to see that a handful of lines of code with split_backfacing were enough to generate something better than what I had above.

It's a better idea to find the set of faces with relevant dot product > 0 and those faces with dot product < 0 and plot the outline---than it is to try and find that contour with dot = 0 (which I was doing above).

Thanks!