Page MenuHome

Fix Bevel Intersection Continuity
ClosedPublic

Authored by Henrik Dick (weasel) on Jan 18 2022, 4:47 PM.
Tokens
"Love" token, awarded by hitrpr."Love" token, awarded by radi0n."Pterodactyl" token, awarded by shader."Love" token, awarded by gritche."Love" token, awarded by gilberto_rodrigues.

Details

Summary

Fix bevel grid fill intersection continuity.
Before this patch, the bevel operator would create visible sharp edges on the
boundaries of grid fill intersections. Here is a typical example of a triangulated cube:


With this patch the intersections should look smooth like this:

This also works with custom profiles and miters so grid fills look better in that case as well.
Old:

New:

Diff Detail

Repository
rB Blender

Event Timeline

Henrik Dick (weasel) requested review of this revision.Jan 18 2022, 4:47 PM
Henrik Dick (weasel) created this revision.
Henrik Dick (weasel) planned changes to this revision.Jan 18 2022, 4:53 PM

This patch is WIP. There is a couple problems still.

  1. The choice of the length of the tangent vectors (currently called proj_dir) is arbitrary and should be revisited as it distorts the cube corner case.
  2. The tangent vectors are wrong in case the bevel is flat in the plane of the face it's belonging to. They should not be aligned with the edge there, but instead be orthogonal to the curve. I don't know yet how to detect this case in code.
  3. sometimes the halfedge e is null, which does not make much sense to me in the cases I was looking at. How can I make that part reliable?
  4. There are extra inner and outer miter types which would have e null I guess, so they need special care as well.

Did we actually have correct tangents and I just missed them, or is it correct that I need to implement all of that still?

  • changed a bunch of things, now the patch should compile and function correctly.

Things to still improve:

  • Naming of variables
  • weird decisions on how long tangents should be
  • center vertex of the pattern is very weird
  • remove debug code
source/blender/bmesh/tools/bmesh_bevel.c
4140

I removed this whole thing because it seemed to change nothing... why was it here?

Henrik Dick (weasel) edited the summary of this revision. (Show Details)Jan 19 2022, 9:20 PM
source/blender/bmesh/tools/bmesh_bevel.c
4140

I remember being confused about that too. I don't remember what case I was dealing with when I added the custom profile check below. Maybe I did that preemptively? Not sure.

Thanks very much for working on this!

I don't really understand why this code makes things better than the old code. Did you discover an error in the Levin paper or an error in my implementation, or did you just derive formulas that are better?

However, it does seem to make things look better, But not as dramatically as in the pictures you show above (I tried triangulating a cube too). Could you please upload a test file with either a bevel modifier or instructions on how to run the edit-mode bevel in order to get those results? Thanks.

source/blender/bmesh/tools/bmesh_bevel.c
4138

Would prefer to have the tangent calculation in a separate function.

4190

This looks kind of weird, doing the dot of a vector against a coordinate. I guess the next line compensates, and so this is really dot of tangent with this mesh_vert minus the profile.middle. This would be clearer if that vector were calculated explicitly; else have a comment describing this. At any rate, a comment explaining what this stretch is trying to do would be helpful to me.

4246

Do you have any notes you could add, either in a comment or in the notes for this patch (that I could later copy into the online bevel documentation) that explains where these constants came from?

Henrik Dick (weasel) added a comment.EditedJan 22 2022, 8:14 PM

Thanks very much for working on this!

I don't really understand why this code makes things better than the old code. Did you discover an error in the Levin paper or an error in my implementation, or did you just derive formulas that are better?

@Howard Trickey (howardt) I found that in the code there was nothing done to ensure that the resulting interpolation surface meets the bevel faces at the correct angle. There was only one calculation to compensate the curvature. The Levin paper (https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.16.4131&rep=rep1&type=pdf) did however have these d vectors for every point of the curve to act as tangents. In the levin paper, the tangents could be different along the boundary curve, but for this patch I kept it simple by just using one tangent vector for one boundary curve.

The formula in the Levin Paper in section 4.3 is


From which one can derive the following formula if the assumption is made that all d vectors are equal.

Note I have changed it from using a function, like in the paper, to use indices, as that is what we do anyway. All variables in the formula are vectors. v is the adjusted boundary vertex position, w is the position of the vertex that is positioned inwards from the vertex c_0 and c_1 and c_-1 are it's neighbors. ns_in is a variable in the code which specifies how many vertices there already are along the boundary, so basically ns_in = 2^n. See in the paper for a detailed image of what the variables mean. d is the tangent that is used to get the boundary continuity.

In the current implementation of the bevel operator we do not have generated tangent, so I needed to generate them on the fly. This is not the best possible solution since new features in bevel will likely break it again. The optimal solution would be to save tangents for the boundary vertices of an intersection which can be used by the interpolation algorithm. However currently the boundary verts are saved in the same structure as the interior intersection vertices, so adding the tangents would also add them in memory for those which would not use them. Also the NewVert are only generated for intersections as far as I can tell, so that they could not carry the necessary information from build_boundary to cubic_subdiv. This calls for a refactor to get these tangents right in all cases.

However, it does seem to make things look better, But not as dramatically as in the pictures you show above (I tried triangulating a cube too). Could you please upload a test file with either a bevel modifier or instructions on how to run the edit-mode bevel in order to get those results? Thanks.

I just used a bevel with many segments (>30). Here is a file with some test cases that I am using. When I am testing, I switch the bevel modifier options for miter types and profile to find potential problems.

EDIT: I will answer your inline comments and update the patch as soon as I get to it, but for now: The constants are WIP still and should probably be replaced by some calculations which I still have to figure out.

Thanks for the follow up explanation and example. Your change looks good so far, but I take it from your last statement that I should wait for another revision before seriously considering accepting this (and committing it on your behalf, if you don't have commit rights). There will be a lot of unit tests to fix, unfortunately, so won't be an easy commit.

Henrik Dick (weasel) updated this revision to Diff 47878.EditedFeb 2 2022, 7:26 PM
Henrik Dick (weasel) marked 2 inline comments as done.
  • improved constants
  • removed debug code
  • added comments
  • divide sabin_gamma by 2 because it makes the results perfect.

I found that the sabin gamma adjustment of the middle vertex really benefits from a divide by 2. No idea why, but look at the results! By doing that, all pointy artifacts in the center disappear.

The results for the intersections are very different between the current state and this patch, so all tests including bevel intersections would need to be updated. Also the problem with the interpolation of the subdivision mesh, which Hans mentions in the comment above interp_vmesh is still there and much more appearant now. Fixing that (which I have no idea how to) would also require the tests to be updated again.

I agree the results look beautiful, and thanks for fixing up the code.
Strangely, all of the bevel regression tests still pass, which says that I probably am not testing enough.
This revision looks good to land, and I will commit it on your behalf.

This revision is now accepted and ready to land.Feb 6 2022, 9:59 PM

Committed, closing.