Preserving periodicity when converting to B-spline

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
Zoltan
Posts: 62
Joined: Wed Jul 07, 2021 10:08 am

Preserving periodicity when converting to B-spline

Post by Zoltan »

I think that the issue I ask here is rather related to the OpenCASCADE kernel, but the computational experiment for reproducibility is performed in Python.

Main question: what tolerance is used by the isPeriodic method of a Part.BSplineCurve object and what tolerance by the isUPeriodic and isVPeriodic methods of a Part.BSplineSurface object?

Experiment: Let us create a sphere, for which the usual parametrization provides periodicity in the u parametric direction. Convert this sphere to a B-spline surface, and the same method reports non-periodicity in the u direction.

Code: Select all

>>> sphere = Part.Sphere()
>>> sphere.isUPeriodic()
True
>>> sphere.isVPeriodic()
False
>>> sphere_as_spline = sphere.toBSpline()
>>> sphere_as_spline.isUPeriodic()
False
>>> sphere_as_spline.isVPeriodic()
False
However, checking the control points shows that the surface is indeed periodic in the u direction:

Code: Select all

>>> import numpy as np
>>> cps = np.array(sphere_as_spline.getPoles())
>>> np.alltrue(np.isclose(cps[0, :, :], cps[-1, :, :]))  # u direction
True
>>> np.alltrue(np.isclose(cps[:, 0, :], cps[:, -1, :]))  # v direction
False
What is going on? Does it mean that I cannot trust the isPeriodic, etc. methods and have to create my own wrapper as demonstrated above?
User avatar
Chris_G
Veteran
Posts: 2598
Joined: Tue Dec 31, 2013 4:10 pm
Location: France
Contact:

Re: Preserving periodicity when converting to B-spline

Post by Chris_G »

A closed BSpline is not the same as a periodic BSpline.
On a closed BSpline, the end poles are touching
On a periodic BSpline, the multiplicity of the first and last knots are lowered, and the last pole is removed.

From what I experienced, when a periodic geometry is converted to BSpline, the periodicity is not kept, but can be set with setPeriodic()

Code: Select all

ci = Part.Circle()
bsp = ci.toBSpline()
Part.show(bsp.toShape())
non-periodic.png
non-periodic.png (20.04 KiB) Viewed 1260 times

Code: Select all

bsp.setPeriodic()
Part.show(bsp.toShape())
periodic.png
periodic.png (20.74 KiB) Viewed 1260 times
User avatar
onekk
Veteran
Posts: 6208
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Preserving periodicity when converting to B-spline

Post by onekk »

EDIT:

Code: Select all

a = Part.Sphere()
a.Radius = 20

b = a.toBSpline()
b.setUPeriodic()

print("UP >", b.isUPeriodic())
print("VP >", b.isVPeriodic())

Part.show(b.toShape(), "sphere")
This behaviour could not be related maybe to some continuity settings, as Sphere.Continuity return "CN" so defaults settings of C1 that seems to be applied are different.



After some test "CN" raise an error but setting as in code above the U periodicity will return same test results as original shape.

EDIT": note the setUPeriodic() as BSplineSurface has no a generic setPeriodic() at least in 0.20R27861


Hope it helps

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
Zoltan
Posts: 62
Joined: Wed Jul 07, 2021 10:08 am

Re: Preserving periodicity when converting to B-spline

Post by Zoltan »

Chris_G wrote: Wed Mar 16, 2022 4:35 pm A closed BSpline is not the same as a periodic BSpline.
Thank you for explaining the distinction.
On a closed BSpline, the end poles are touching
But when you made the B-spline periodic, the control points do not overlap (as shown in the figure and as verified by fetching the coordinates of the control points). Still

Code: Select all

>>> bsp.isClosed()
True
Similarly, if I create a closed B-spline curve in the Sketcher workbench, the control polygon is not closed.
Screenshot from 2022-03-16 18-12-10.png
Screenshot from 2022-03-16 18-12-10.png (18.06 KiB) Viewed 1191 times
Last edited by Zoltan on Wed Mar 16, 2022 5:13 pm, edited 2 times in total.
Zoltan
Posts: 62
Joined: Wed Jul 07, 2021 10:08 am

Re: Preserving periodicity when converting to B-spline

Post by Zoltan »

onekk wrote: Wed Mar 16, 2022 4:43 pm

Code: Select all

b.setUPeriodic()
Thank you, the setPeriodic method is what @Chris_G used in his answer.

EDIT": note the setUPeriodic() as BSplineSurface has no a generic setPeriodic() at least in 0.20R27861
As a spline surface may happen to be periodic in one direction only, setting the periodicity independently makes sense.
User avatar
onekk
Veteran
Posts: 6208
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Preserving periodicity when converting to B-spline

Post by onekk »

Zoltan wrote: Wed Mar 16, 2022 5:06 pm Thank you, the setPeriodic method is what @Chris_G used in his answer.
Yes but in your case setPeriodic() will raise an error as toBSpline() used to convert a Sphere will result in a BSplineSurface and @Chris_G example was done with a Circle.

As said BSplineSurface has no setPeriodic() but has setUPeriodic and setVPeriodic instead.

Interesting problem as it was not too immediate to solve, as a sphere has a "CN" continuity, but you could not set "CN" as parameter without raising and error if you sepcify as example:

Code: Select all

.toBSpline(1e-7, "CN", "CN")
as the help(Part.Sphere) will show.

@Chris_G as usual was a "problem solver", I hope that sometimes he will be willing to share his knowledge with a wiki page describing BSplines in more details, for us "poor beginners".

Thanks again @Chris_G, every time I learn something more from your explanations.

Regards

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
User avatar
Chris_G
Veteran
Posts: 2598
Joined: Tue Dec 31, 2013 4:10 pm
Location: France
Contact:

Re: Preserving periodicity when converting to B-spline

Post by Chris_G »

Zoltan wrote: Wed Mar 16, 2022 4:58 pm But when you made the B-spline periodic, the control points do not overlap (as shown in the figure and as verified by fetching the coordinates of the control points). Still

Code: Select all

>>> bsp.isClosed()
True
I must correct myself :
On a closed BSpline, the end poles extremities of the curve are touching
99% of the time, we use "clamped" BSplines (the multiplicity of the first and last knots == degree + 1) , so the end poles coincide with the ends of the curve.
When setting a closed BSpline curve as periodic, the multiplicity of the first and last knots are lowered, the curve becomes "unclamped", and the end poles may not both touch the origin point of the curve.
Zoltan wrote: Wed Mar 16, 2022 4:58 pm Similarly, if I create a closed B-spline curve in the Sketcher workbench, the control polygon is not closed.
It may be called "closed", but it is a periodic one.
There is no such a thing as a "control polygon". We have only Control Points (= poles).
In the GeomInfo tool of Curves WB, they are displayed as an open polygon. If you see it as closed, it means that first and last poles are coincident.
Zoltan
Posts: 62
Joined: Wed Jul 07, 2021 10:08 am

Re: Preserving periodicity when converting to B-spline

Post by Zoltan »

Chris_G wrote: Wed Mar 16, 2022 6:33 pm 99% of the time, we use "clamped" BSplines (the multiplicity of the first and last knots == degree + 1) , so the end poles coincide with the ends of the curve.
When setting a closed BSpline curve as periodic, the multiplicity of the first and last knots are lowered, the curve becomes "unclamped", and the end poles may not both touch the origin point of the curve.
Zoltan wrote: Wed Mar 16, 2022 4:58 pm Similarly, if I create a closed B-spline curve in the Sketcher workbench, the control polygon is not closed.
It may be called "closed", but it is a periodic one.
Yes, in the meantime I checked the corresponding parts in The NURBS Book, in which I saw that clamped=non-periodic and unclamped=periodic.
In my application, it is necessary that the spline is clamped, which can be ensured by the setNotPeriodic method.
There is no such a thing as a "control polygon". We have only Control Points (= poles).
I used the terminology of The NURBS Book, in which the control points (or poles as called in OpenCASCADE) of a curve form the control polygon, while the control points of a surface form the control net.
Post Reply