PixarAnimationStudios / OpenSubdiv

An Open-Source subdivision surface library.
graphics.pixar.com/opensubdiv
Other
2.88k stars 558 forks source link

An issue with non-zero weights on adjacent edges. #1152

Closed VadiMysore closed 5 years ago

VadiMysore commented 5 years ago

Hi there! I just wanted to know whether this is an issue with OpenSubdiv. In the case depicted below, two adjacent edges have a weight of 5 and the rest are all infinitely sharp edges( weight = 10). When the model is subdivided adaptively to level 1, UseInfSharpPatch = true for PatchTable create method.

I see artifacts at the corner (shown to the right, below) where the two blends meet. Is this the expected answer? Even further levels of subdivision exhibit the same behavior though it is confined to a smaller area.

The ideal result expected is two cylinder blends intersecting. Any insight on why this might be happening?

Assigning a weight of 5 to the corner vertex did not help. Has this something to do with the corner patch extrapolation, as infinitely sharp edges meet the edges being blended with weight 5?

BlendingAdjacentEdgesIssue

barfowl commented 5 years ago

Yes, unfortunately these are the expected results -- there are two things going on here...

First, since you have edges with sharpness 5, any level less than 5 is only an approximation to the limit surface -- and level 1 will be a particularly crude approximation. One of the main purposes of the adaptive subdivision is to generate the detail need to represent the true limit surface of semi-sharp features and the sharpness value indicates how many times subdivision must be applied. So if you insist on using level 1 for a small number of patches, you might as well not bother with semi-sharp features at all.

Second, since you have added the inf-sharp edge, the corner where all three sharp edges meet will remain completely sharp until level 5 (whenever three sharp edges meet, a corner is created). At that point, since you only have one inf-sharp edge, and you are using inf-sharp patches, you will end up with a sharp "dart" ending in a smooth region.

The same shape using adaptive level 5 looks like this:

crease_5_and_10

This creasing scheme was designed to be invariant under subdivision, i.e. the limit surface for the initial mesh is identical to the limit surface for a subdivided mesh (which is not true of many other ad hoc schemes), but unfortunately it does not always give intuitive results where multiple sharp features meet.

VadiMysore commented 5 years ago

@barfowl - Hi Barry! Thanks for the explanation.

In Computer Aided Design software (CAD), it is very important that the subdivision surfaces/solids contain as fewer patches as possible. This is because they will be used for downstream modeling operations. For example, we may boolean other solids/surfaces with them, offset/thicken the sheets and do other topological/geometric modifications to them. These will work very well if the number of patches is the minimal.

I find it a bit surprising that OpenSubdiv produces more than a patch per control cage face even in the case of a simple cube. And, s the number of levels is increased, it worsens, especially, at the corners of the cube. One can visually see a "quadtree" in those corners resulting from adaptive subdivision. CAD users normally expect one patch per control cage face, particularly when all faces of the control cage are quads. Does OpenSubdiv really have to "physically" subdivide to fit a limiting surface patch during adaptive subdivision? Siemens' NX CAD software, which, perhaps, predates OpenSubdiv in Subdivision, produces visually smooth b-sline patches and is always one per control cage face. It is their own implementation of Catmull-Clark.

I also have observed that even with on level subdivision, with all edges infinitely sharp, a cube produces four faces per control cage face.

If more CAD software clients were to use OpenSubdiv, it would be a great enhancement if the software ensures one limit surface patch per control cage face. It will be a great enhancement and your CAD clients will be pleased. Is it something that can be expected of OpenSubdiv in the near future?

Also, what exactly does useSingleCreasePatch option do? I interpreted it to yield one patch per sharp crease.

barfowl commented 5 years ago

Closing this issue as the expected results have been explained and illustrated.

Regarding remaining questions raised...

The topic of OpenSubdiv not producing the expected one "patch" per control face has been discussed in previous issues that you opened - where the minimum 1 level was explained - and the situation has not changed. While some improvements are possible and have been made, this goal is not a priority.

In general, it is not mathematically possible for a single bicubic B-Spline patch to adequately represent a face with two extra-ordinary vertices with the desired degree of continuity. So those that do claim a "patch per face" are either using higher degree patches or provide a piecewise surface per control face, i.e. more than one patch (a "patch" with 5x5 control points could be a single biquartic patch or 2x2 bicubic patches). Or they may avoid that situation by requiring that meshes not contain such features. PCCM makes the "patch per face" claim but also states pre-conditions that adjacent extra-ordinary vertices be isolated by one or two (for even valence) levels of subdivision. OpenSubdiv's preferred solution in such cases is and will likely remain the use of Gregory Patches.

Regardless, OpenSubdiv can clearly improve itself in this area, but, as previously mentioned, there are historical limitations that need to be addressed before we can make such guarantees for meshes or arbitrary topology (we have to be robust in situations that no sane CAD modeler would ever create).

And even in the presence of such improvements, producing a patch per control face will effectively ignore any explicitly applied creasing. The creasing algorithm is recursive in nature and the resulting shape cannot be adequately represented by a single bicubic patch. The "single crease patch" is a GPU-only implementation that provides a single "composite" patch for some areas to hide the fact that the area is being represented by a sequence of bicubic B-Spline patches and so reduces the total number of patches in favor of a smaller number of a more complicated patch type. More details about the creasing and this kind of optimization can be found in the references cited on the Introduction page.