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

Deconstructed Curve Segment is half clamped #4469

Closed
rendetto opened this issue May 12, 2022 · 12 comments
Closed

Deconstructed Curve Segment is half clamped #4469

rendetto opened this issue May 12, 2022 · 12 comments
Assignees

Comments

@rendetto
Copy link
Contributor

rendetto commented May 12, 2022

A while ago I created a test case of a Closed Periodic Spline, wrapping the control points according to the theory:
https://pages.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/B-spline/bspline-curve-closed.html

So I wrapped certain number control points and then used the Curve Segment node to get a spline only at its domain - resulting in a closed continuous curve. It all went well and predictable for the FreeCAD implementation (which is the most convenient for that case so I will stick to it at first because the other two implementations have problems).

This is how the whole spline looks using a periodic knot vector, before getting the control points wrapped:
PeriodicSpline

...then with control points wrapped:
PeriodicSpline-WrappingControlPoints

...and now cut only the segment between the domain limits - resulting in a smoothly closed spline:
ClosedPeriodicSpline

When I deconstruct the closed spline - the result is a B-Spline that uses clamped knot vector (a Bezier Curve):
ClosedPeriodicSpline_Deconstruct

Awesome isn't it :)

Now the problem...

At this commit e4a9d3b the Curve Segment node started throwing an error so nothing worked for a while.

Then at this one 5597869 the Curve Segment started working again, but what I got as a result after deconstructing is only half clamped spline which is not the behavior I expected:
HalfClampedSpline

I'm uploading my test file for examination:
Closed_Periodic_Spline_5thDegree.zip

It's clearly a bug and it's present when the "T Max" value of the Curve Segment is exactly 1.0 in my case (or at the upper domain limit in an arbitrary case)

As a temporary workaround we can use "T Max" = 0.9999999 and get near perfect results but even very close to 1.0 it's not exact and the gap between curve start and end depends on the model scale.

@rendetto rendetto changed the title Curve Segment is half clamped Deconstructed Curve Segment is half clamped May 18, 2022
@rendetto
Copy link
Contributor Author

@portnov can you take a look at this problem?

Thanks

@portnov portnov added the NURBS label Aug 24, 2022
@portnov
Copy link
Collaborator

portnov commented Aug 24, 2022

Ok, will try to look at it this week.

@portnov
Copy link
Collaborator

portnov commented Aug 30, 2022

@rendetto please test #4633 .

Screenshot_20220830_232933


There is obviously some other problem with Sverchok's native nurbs implementation, which is surfacing if I try to use it in the first "build nurbs" node in your example. But that's a different story.

Huh, geomdl has the same problem.

Screenshot_20220830_232808

@rendetto
Copy link
Contributor Author

rendetto commented Aug 30, 2022

Checked #4633 and i works OK (for freecad implementation)!
Concerning geomdl - until #4633 I just got this error:

geomdl_error

...now using #4633 I also got the strange behavior that I was to report about Native implementation only. It's strange to see it in geomdl also.

exact

If you activate Normalize Knots in "Build NURBS Curve" node you'll see the whole curve is built OK (symmetrically) even outside its domain for both geomdl and Native:

normalize

But when trying to take a segment... this odd behavior became present and even pretty bizarre with Native implementation (if we try to get an arbitrary segment):

bizarre

But being strict to the reported problematic setup (for trying to get smoothly closed curve) the oddity is only present at the upper domain limit (in this case "T Max" = 1.0)
If I try "T Max" = 0.999999 the curve form doesn't deviate from the expected (at least to the naked eye)

almost

@portnov
Copy link
Collaborator

portnov commented Aug 31, 2022

Hmm. I investigated the problem for a bit, and currently it seems to me that Sverchok implementation is more correct than Geomdl and FreeCAD :) Maybe I'm wrong.

The thing is, Sverchok calculates NURBS directly by definition, as sum(N[i,p](t) * control_point[i] for i in 0 .. n_ctrlpts-1). To calculate coefficients N, for example, for T = 1.6, it calculates it directly by definition (I'm referring to [1], p.2.2, and triangular scheme there). And for T = 1.6, the non-zero coefficients appear to be N[5,5], N[6,5], N[7,5] and N[8,5]. For example, according to "local support property" (P2.1 in [1]), N[4,5] is zero outside [u[4]; u[10]), and T = 1.6 is more than u[10] in your case (more than 1.5). So only control points 5 through 8 (counting from zero) are affecting the point of curve at T=1.6.

But, at least Geomdl (did not check about FreeCAD) calculates Nurbs not by definition, but by algorithm A3.1 from [1], and a "reverse triangular scheme" from there. And according to that reverse triangular scheme, non-zero coefficients would be N[3,5] through N[8,5], i.e. six control points are affecting the point on the curve, not four!

Why such a contradiction in the same book? As far as I understood, algorithm A3.1 was designed for the special case of clamped knotvectors (ones which starts and ends with a knot with multiplicity = p+1). The book [1], after all, in many cases speaks only about curves with clamped knotvectors. I.e., as far as I understand it, Geomdl is doing not such a good thing, by applying an algorithm, which was designed for clamped knotvectors, to a non-clamped one.

It may appear that for curves with non-clamped knotvectors I should look into another book; I'd be glad if you could point me into which one :)

[1]: The NURBS Book, 2nd ed

@rendetto
Copy link
Contributor Author

rendetto commented Sep 1, 2022

Unfortunately the whole theory is a black box for me :(
Does geomdl and Native implementations imply this jump in the curve form exactly at T Max = 1.0?
We can gradually increase T Max very near to 1.0 (0,99999989999 for geomdl and 0,999998999 for Native) without causing the segment end to pop.
In fact the above mentioned limits can be used in practice but it will be better if the segment end meets the segment start exactly as with FreeCAD implementation.

@portnov
Copy link
Collaborator

portnov commented Sep 1, 2022

The issue is not in 1.0 by itself, it's about 1) knotvector not being clamped and 2) T within range of first or last p knots of knotvector.

I tried to check with implementation from rhino3dm, it seems to work more like Geomdl or FreeCAD than like Sverchok, but that implementation has it's own peculiarities...

@portnov
Copy link
Collaborator

portnov commented Sep 1, 2022

@rendetto anyway, I think after #4633 things got better than they were, so I should merge it? After that we could deal with remaining issues...

@rendetto
Copy link
Contributor Author

rendetto commented Sep 1, 2022

@portnov I need to do some testing with several old setups affected by #4633.
I already found things that are not working as before, and wanted to be sure that there are workarounds.

@rendetto
Copy link
Contributor Author

rendetto commented Sep 2, 2022

@portnov I tested lots of setups I had. The changes in freecad.py solved the problem with end clamping of freecad curves but the new code in algorithms.py messed the things for me. I guess I was taking advantage of something that was not predicted by design but it worked for me kind of nicely. I guess I can revert the changes in algorithms.py locally when I need those "features" back but that seems awkward.
Anyways please merge this PR and then I will make reports for what was useful for me before the merge so you can decide if this could be useful feature and even find a better solution. I'll be available the week after and will start reporting.

Thanks

@rendetto
Copy link
Contributor Author

@portnov sorry for the enormous delay, but had to recover from a total hard drive failure. Fortunately the lab managed to excavate most of the info and I'm slowly getting back on track and starting those reports.
My plan initially was to test all meaningful setups that include unclamped splines. So I'll stick to it.

The first findings are concerning the strange behavior with Geomdl and Native at the end of the spline (mentioned by you above):
image

Unfortunately I cannot understand the code behind and how it changed but it seems that in the early days this problem was not present.
For clarity I'm opening another issue on that matter - #4722

Thanks

@portnov
Copy link
Collaborator

portnov commented Nov 4, 2022

I think we can close this, as the continuation is in another issue.

@portnov portnov closed this as completed Nov 4, 2022
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

3 participants