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

Bug at the upper domain limit for unclamped splines (geomdl and Native implementations) #4722

Closed
rendetto opened this issue Oct 26, 2022 · 8 comments

Comments

@rendetto
Copy link
Contributor

rendetto commented Oct 26, 2022

I'm reporting the strange behavior of the unclamped splines mentioned in #4469
It is still present for Native and geomdl implementations with the most recent Sverchok master.

LatestSV_PeriodicSplineBug

The setup is the same as used in #4469 (a constructed closed unclamped /periodic/ spline using wrapped control points - a convenient method for constructing arbitrary smoothly closed curves)
The problem is present when taking a segment from a spline and the end (TMax) of this segment is exactly at the upper domain limit (which is 1.0 in this particular example)

I found that reverting to an earlier version of Sverchok (32f8f36) this problem is not present for both Native and geomdl. I run this early version of Sverchok under blender-2.90.0-windows64 and also aligned it to the corresponding Sverchok-extra for the time being.
I also used the latest geomdl (v5.3.1) due to #3521 and orbingol/NURBS-Python#115

oldSV_PeriodicSpline

As with other similar issues I got, there is a workaround that could "solve" the issue by using a value of 0.99999 instead of 1.0

@portnov
Copy link
Collaborator

portnov commented Nov 4, 2022

Well, what I understood for now.

  1. Splitting of a Nurbs curve at parmeter t is done by inserting a knot in that point p times (p being the degree of the curve). After such insertion, there will be a control point coinciding with Curve(t) point. After that, the process of splitting is obvious: first segment's control points are all old control points at left of t plus new control point, second segment's control points are new control point plus all old control points at right of t.
  2. Knot insertion always cuts a corner, or several corners, from curve's control polygon. On illustration from The Nurbs Book, P are old control points, Q are new control points:

Screenshot_20221104_132455

So to calculate how exactly corners must be cut, one has to have several control points at left of t and several control points at right of t, otherwise there will be no corners to be cut.
3. If curve's knotvector is clamped, then mathematically there are enough "corners" (of zero size) at the ends of the curve. So formulas for knot insertion work fine if you try to add a knot near the end of the curve (but not exactly in the start or end point).
4. If curve's knotvector is not clamped, then, if you try to insert a knot near to curve's end, you will find that there are not enough control points either on the left or on the right of t, to form corners which are to be cut. So, depending on specific algorithm which you use for knot insertion, you will either get deformed curve, or get something like division by zero. In short: mathematically, usual knot insertion process is not possible for non-clamped curves near curve's ends.
5. The only workaround I see here (and probably it's what was working in Sverchok earlier) in such cases, is to do not try to calculate control points of segment (to form a new nurbs curve), but instead just take a subdomain of initial curve.

@portnov
Copy link
Collaborator

portnov commented Nov 4, 2022

So, depending on specific algorithm which you use for knot insertion, you will either get deformed curve, or get something like division by zero.

For example, if you try FreeCAD implementation of curve in your setup, you will see an error thrown from FreeCAD API.

@portnov
Copy link
Collaborator

portnov commented Nov 4, 2022

Aha, I managed to read 12th chapter of The Nurbs book :)
There they say, that for unclamped knotvectors, the curve is defined not on the whole interval covered by knotvector, but only on [u[p]; u[m-p]] (where u is knotvector, p is curve's degree and m is number of control points). I.e., the beginning and the end of such curve must be just ignored.

However,

  1. It does not make sense to insert knots for unclamped knotvector before u[p] or after u[m-p].
  2. But, insertion of knot exactly at u[p] or u[m-p] still makes sense. I just had a bug in knot insertion code.

portnov added a commit that referenced this issue Nov 4, 2022
sv_knotvector.find_span() works in a special way when u_bar is near
right end of curve domain.

refs #4722.
@portnov
Copy link
Collaborator

portnov commented Nov 4, 2022

It seems I managed to fix the bug in Sverchok implementation of knot insertion.
Geomdl implementation, it seems, still has the same problem Sverchok implementation had - but that is a bug in Geomdl.

For later, I added a flag into "Curve segment" node, to disable calculation of new NURBS curves. It may be useful to work around some problems in different implementations of Nurbs.

@rendetto please test.

@rendetto
Copy link
Contributor Author

rendetto commented Nov 4, 2022

@portnov Just tested... and for Sverchok(Native) implementation the bug is resolved! Thanks a lot!

About Geomdl - I can try to contact Onur Bingol the creator of Geomdl, but I'm not sure that I can keep up with the math details :)
Last time when I contacted him about a problem (orbingol/NURBS-Python#115), he was very kind and solved the issue in no time.

In any case if Geomdl cannot get a bugfix we can still do a workaround with really tight tolerance:

geomdl_closed_periodic

For 5th degree curve the distance in this case between the start and the end is 4.66e-07 far from any industrial application tolerance if we design for human scale.

BTW the Curve Segment is really usefull with this NURBS output, but the corresponding Surface Subdomain node doesn't have NURBS output. Do you plan implementing that functionality?

@portnov
Copy link
Collaborator

portnov commented Nov 4, 2022

BTW the Curve Segment is really usefull with this NURBS output, but the corresponding Surface Subdomain node doesn't have NURBS output. Do you plan implementing that functionality?

Shouldn't be too hard to implement. But I can't promise that I will do this soon.

@rendetto
Copy link
Contributor Author

rendetto commented Nov 4, 2022

No pressure :)

Thanks again.

@portnov
Copy link
Collaborator

portnov commented Nov 4, 2022

@rendetto I filed a bug to Geomdl library: orbingol/NURBS-Python#158 .

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

No branches or pull requests

2 participants