Simplify BSplines

Here's the place for discussion related to coding in FreeCAD, C++ or Python. Design, interfaces and structures.
User avatar
microelly2
Posts: 2362
Joined: Tue Nov 12, 2013 4:06 pm
Contact:

Simplify BSplines

Postby microelly2 » Tue Mar 14, 2017 4:24 pm

When I call a BSplineCurve removeKnot I have to use a very high tollerance value to get a result.

rc=bc.removeKnot(pos,0,30000)

But the result quality is good. The mean difference to the old curve is less than 0.15 mm and only one pole has moved 3 mm.
So what is the meaning of 30000?
Did not found a good description of the exact impact of this parameter.

Has someone experience in this?
User avatar
Chris_G
Posts: 354
Joined: Tue Dec 31, 2013 4:10 pm
Location: France

Re: Simplify BSplines

Postby Chris_G » Tue Mar 14, 2017 5:02 pm

That's strange.
Here is opencascade's doc :
https://www.opencascade.com/doc/occt-6.9.0/refman/html/class_geom___b_spline_curve.html#a4d22cafccfeb8b12cfaf5e9c3d4e6c3d
I used it on an imported SVG path to raise its continuity from C0 to C1 and it worked with tolerance around 0.1
Maybe because you're trying to completely remove the knot ?
Try to see what are the required tolerances if you go step by step :

Code: Select all

rc=bc.removeKnot(pos, originalMult-1, tolerance)
User avatar
microelly2
Posts: 2362
Joined: Tue Nov 12, 2013 4:06 pm
Contact:

Re: Simplify BSplines

Postby microelly2 » Tue Mar 14, 2017 8:18 pm

Chris_G wrote:That's strange.
I used it on an imported SVG path to raise its continuity from C0 to C1 and it worked with tolerance around 0.1
Maybe because you're trying to completely remove the knot ?
Try to see what are the required tolerances if you go step by step :

Code: Select all

rc=bc.removeKnot(pos, originalMult-1, tolerance)


the text in the doc is simple
A low tolerance is used to prevent modification of the curve. A high tolerance is used to "smooth" the curve. Exceptions Standard_OutOfRange if Index is outside the bounds of the knots table. pole insertion and pole removing this operation is limited to the Uniform or QuasiUniform BSplineCurve.

I will follow your tipp and make some test to get a feeling for the relation between tolerance and "difference" of the curve. :roll:
User avatar
microelly2
Posts: 2362
Joined: Tue Nov 12, 2013 4:06 pm
Contact:

Re: Simplify BSplines

Postby microelly2 » Tue Mar 14, 2017 11:02 pm

Chris_G wrote:I used it on an imported SVG path to raise its continuity from C0 to C1 and it worked with tolerance around 0.1

How many poles did your curves have?
My examples have 10 to 20 poles and there is no influence f the tolerance value :?
User avatar
Chris_G
Posts: 354
Joined: Tue Dec 31, 2013 4:10 pm
Location: France

Re: Simplify BSplines

Postby Chris_G » Wed Mar 15, 2017 8:32 am

Hi,
Here is a sample code that shows removeKnot failing with Tolerance 1e-3, then succeeding with Tolerance 1e-1
I guess that any tolerance value higher than 1e-1 will lead to the exact same curve.

Code: Select all

import Part

ptstup = [(0,0,0),(0,1,0),(1,1,0),(1,0,0),(1.01,-1,0),(2,-1,0),(2,0,0)]
# tangents around the 4th pole are not exactly aligned
knots = [0,0.5,1]
mults = [4,3,4]

pts = [FreeCAD.Vector(p) for p in ptstup]

bs = Part.BSplineCurve()
bs.buildFromPolesMultsKnots(pts, mults, knots, False, 3)
# bs is a piecewise cubic bezier curve

bs.Continuity
bs.getMultiplicities()

bs.removeKnot(2,2,1e-3) # Fails

bs.Continuity
bs.getMultiplicities()

bs.removeKnot(2,2,1e-1) # Success

bs.Continuity
bs.getMultiplicities()