## Sketcher: Bezier curves

Here's the place for discussion related to coding in FreeCAD, C++ or Python. Design, interfaces and structures.
triplus
Posts: 4857
Joined: Mon Dec 12, 2011 4:45 pm

### Re: Sketcher: Bezier curves

OK i think i understand. As for spline creation method. We are already there. By using control polygon and by involving solver spline can be made and control over it is provided. Beyond that you plan to offer some additional commands/control for the created spline. By using more direct approach and you don't plan to involve the solver in this.

Sounds good.
wmayer
Posts: 11234
Joined: Thu Feb 19, 2009 10:32 am

### Re: Sketcher: Bezier curves

abdullah wrote:Well, I think it is ready:
...

The current implementation of curvature combs raises two major problems:
1. Moving a control point of a B-spline only affects the local segment but leaves the rest untouched. If you make a spline with e.g. 10 control points and move e.g. the last one you can see that the shape only changes next to the control point but the rest of the spline doesn't change its form. However, the curvature comb heavily changes all over the curve which leads to the impression that the curvature isn't fix there which is definitely wrong.

2. This is a paper which I referenced earlier in this thread: https://graphics.stanford.edu/courses/c ... dout27.pdf
It is about making two Bezier curves C1, C2 or C3 continuous. In FreeCAD you can create a Bezier curve by creating a B-spline with exactly four control points and since its degree is 3 it is automatically a Bezier curve, too. Due to the fact that the parameter range of two created splines is equal (usually [0,1]) we can directly apply the method to create the various continuities as represented on page 6.

This means to create C1 continuity you make first the control points of the two curves coincident and then apply a symmetry on their adjacent control points.
To create C2 continuity you create a free construction point and apply symmetry between second, second last control point and the construction point of the first curve. Repeat this for the second curve.

Now when activating the curvature comb and you move one of the control points the curvature comb looks like as the two curves are not C2-continuous. But they are.

Attached is a sketch to demonstrate the behaviour.

The problem is caused by this line in ViewProviderSketch.cpp:

Code: Select all

`repscale = ( 0.5 * maxdisttocenterofmass ) / maxcurv; `

because it computes an individual scaling factor for each curve. But what we need is a fix scaling factor for all curves.
Attachments
sketch_c2.fcstd
abdullah
Posts: 1502
Joined: Sun May 04, 2014 3:16 pm

### Re: Sketcher: Bezier curves

wmayer wrote:The current implementation of curvature combs raises two major problems:

If I understood you correctly, both problems are solved by providing a fixed scalar factor (for all curves). I do not think this will be a major problem. As soon as I discover why my knot implementation is crashing FC, I will do a commit to fix this issue. Thanks for reporting it.
abdullah
Posts: 1502
Joined: Sun May 04, 2014 3:16 pm

### Re: Sketcher: Bezier curves

Finally I got a OCC code sequence that segfaults and is independent of FreeCAD:

Code: Select all

`    TColgp_Array1OfPnt poles(1,6);     poles(1) = gp_Pnt(537.277,-284.089,0.0);    poles(2) = gp_Pnt(575.138,-218.104,0.0);    poles(3) = gp_Pnt(636.797,-282.468,0.0);    poles(4) = gp_Pnt(664.38,-217.56,0.0);    poles(5) = gp_Pnt(721.71,-280.84,0.0);    poles(6) = gp_Pnt(759.57,-214.31,0.0);        TColStd_Array1OfReal weights(1,6);    weights(1) = 1.0;    weights(2) = 1.0;    weights(3) = 1.0;    weights(4) = 1.0;    weights(5) = 1.0;    weights(6) = 1.0;        TColStd_Array1OfReal weights2(1,7);    weights2(1) = 12.99;    weights2(2) = 12.99;    weights2(3) = 12.99;    weights2(4) = 12.99;    weights2(5) = 1.0;    weights2(6) = 12.99;    weights2(7) = 12.99;        TColStd_Array1OfReal knots(1,4);    knots(1) = 0.0;    knots(2) = 0.33333333333;    knots(3) = 0.66666666666;    knots(4) = 1.0;        TColStd_Array1OfInteger mults(1,4);    mults(1) = 4;    mults(2) = 1;    mults(3) = 1;    mults(4) = 4;        Geom_BSplineCurve * mybsp = new Geom_BSplineCurve(poles, weights, knots, mults, 3, false, true);        mybsp->IncreaseMultiplicity(2,2);        TColgp_Array1OfPnt poles2(1,mybsp->NbPoles());    mybsp->Poles(poles2);        //TColStd_Array1OfReal weights2(1,mybsp->NbPoles());    //mybsp->Weights(weights2);        TColStd_Array1OfReal knots2(1,mybsp->NbKnots());    mybsp->Knots(knots2);        TColStd_Array1OfInteger mults2(1,mybsp->NbKnots());    mybsp->Multiplicities(mults2);            for (Standard_Integer it = 1; it <= poles.Length(); it++) {        mybsp->SetPole(it, poles2(it), weights2(it));    }        for (Standard_Integer it = 1; it <= knots.Length(); it++) {        mybsp->SetKnot(it, knots2(it), mults2(it));    }        Standard_Real k2 = mybsp->Knot(1);        GeomLProp_CLProps prop(mybsp,k2,0,Precision::Confusion());        const gp_Pnt &point=prop.Value();`

When I execute this, linked to our FreeCAD OCE: 6.8.0.oce-0.17, it segfaults in the last but one line (GeomLProp_CLProps prop(mybsp,k2,0,Precision::Confusion());).

It only segfaults if the checkrational parameter above ( the last true in Geom_BSplineCurve * mybsp = new Geom_BSplineCurve(poles, weights, knots, mults, 3, false, true);), is set to true.

What I understand is that, if the bspline was created with equal weights and we asked to check if it is rational (I think this is to optimize for polynomic), then we do the knot multiplicity increase, and then we add weights that are different, thus rational, something goes wrong when asking the point of a parameter.

https://github.com/abdullahtahiriyo/Fre ... c_segfault

would execute the code above if:
1. Create an sketch, and in the sketch a bspline of at least 5 poles (so that it has at least a knot for degree 3).

2. Hit the "X" button in the Bspline bar:
knottool_occ_fix.png (8.41 KiB) Viewed 238 times

I will try to do something excised from FreeCAD to report it...

Maybe somebody with more OCC experience could take a look to the code above, to see if there is something off in my code
wmayer
Posts: 11234
Joined: Thu Feb 19, 2009 10:32 am

### Re: Sketcher: Bezier curves

Maybe somebody with more OCC experience could take a look to the code above, to see if there is something off in my code

Here is a standalone application showing the crash.

main.cpp:

Code: Select all

`#include <TColgp_Array1OfPnt.hxx>#include <TColStd_Array1OfReal.hxx>#include <TColStd_Array1OfInteger.hxx>#include <GeomLProp_CLProps.hxx>#include <Geom_BSplineCurve.hxx>#include <Precision.hxx>int main(){    TColgp_Array1OfPnt poles(1,6);    poles(1) = gp_Pnt(537.277,-284.089,0.0);    poles(2) = gp_Pnt(575.138,-218.104,0.0);    poles(3) = gp_Pnt(636.797,-282.468,0.0);    poles(4) = gp_Pnt(664.38,-217.56,0.0);    poles(5) = gp_Pnt(721.71,-280.84,0.0);    poles(6) = gp_Pnt(759.57,-214.31,0.0);       TColStd_Array1OfReal weights(1,6);    weights(1) = 1.0;    weights(2) = 1.0;    weights(3) = 1.0;    weights(4) = 1.0;    weights(5) = 1.0;    weights(6) = 1.0;       TColStd_Array1OfReal weights2(1,7);    weights2(1) = 12.99;    weights2(2) = 12.99;    weights2(3) = 12.99;    weights2(4) = 12.99;    weights2(5) = 1.0;    weights2(6) = 12.99;    weights2(7) = 12.99;       TColStd_Array1OfReal knots(1,4);    knots(1) = 0.0;    knots(2) = 0.33333333333;    knots(3) = 0.66666666666;    knots(4) = 1.0;       TColStd_Array1OfInteger mults(1,4);    mults(1) = 4;    mults(2) = 1;    mults(3) = 1;    mults(4) = 4;       Geom_BSplineCurve * mybsp = new Geom_BSplineCurve(poles, weights, knots, mults, 3, false, true);       mybsp->IncreaseMultiplicity(2,2);       TColgp_Array1OfPnt poles2(1,mybsp->NbPoles());    mybsp->Poles(poles2);       //TColStd_Array1OfReal weights2(1,mybsp->NbPoles());    //mybsp->Weights(weights2);       TColStd_Array1OfReal knots2(1,mybsp->NbKnots());    mybsp->Knots(knots2);       TColStd_Array1OfInteger mults2(1,mybsp->NbKnots());    mybsp->Multiplicities(mults2);          for (Standard_Integer it = 1; it <= poles.Length(); it++) {        mybsp->SetPole(it, poles2(it), weights2(it));    }       for (Standard_Integer it = 1; it <= knots.Length(); it++) {        mybsp->SetKnot(it, knots2(it), mults2(it));    }       Standard_Real k2 = mybsp->Knot(1);       GeomLProp_CLProps prop(mybsp,k2,0,Precision::Confusion());       const gp_Pnt &point=prop.Value();    return 0;}`

Build under Ubuntu:

Code: Select all

`g++ main.cpp -I/usr/include/oce -L/usr/lib/x86_64-linux-gnu -lTKG3d -lTKernel -o spline`

On Windows when using oce 0.13 I get this crash, too. It crashes in Geom_BSplineCurve::ValidateCache inside the call of BSplCLib::BuildCache. Using occ 7.0 instead the crash doesn't occur any more.

Edit:
Searching in the forum revealed it's the same issue we had observed some years ago: https://forum.freecadweb.org/viewtopic. ... 12&p=77329
abdullah
Posts: 1502
Joined: Sun May 04, 2014 3:16 pm

### Re: Sketcher: Bezier curves

wmayer wrote:Here is a standalone application showing the crash.

Thanks! I did not have the knowledge about what to link to, so you saved me some search time

wmayer wrote:Using occ 7.0 instead the crash doesn't occur any more.

Thanks for checking this.

It would be great to know if oce 0.18 has this bug. Could anybody test this?

https://github.com/tpaviot/oce

I am unsure on how to proceed:

1. remove (conditional compilation) offending commands in FreeCAD for older versions than where the bug was fix.
2. If we test oce 0.18 and the bug is not there, update oce in our ubuntu repo.

...

I do not know the OCE vs OCCT. Can we or should we move to using OCCT?

wmayer wrote:Edit:
Searching in the forum revealed it's the same issue we had observed some years ago: https://forum.freecadweb.org/viewtopic. ... 12&p=77329

I did find it myself too, but it seems it was solved...

In any case, I have reported it here:

I am not sure how useful this is (for them), as their latest version does not show the bug, so probably it was fixed. I do not know if they provide backports. Anyway, I decided to make them aware.

Thanks again.

Let me know.
abdullah
Posts: 1502
Joined: Sun May 04, 2014 3:16 pm

### Re: Sketcher: Bezier curves

It seems to be a very recently addressed issue too:

Coming back to the previously reported issue in 2012, maybe the problem was never fixed for us since in 2012 Sebastian says he was using OCCT 6.8.1-dev at that time.

This are the list of issues relating to BSplCLib:

triplus
Posts: 4857
Joined: Mon Dec 12, 2011 4:45 pm

### Re: Sketcher: Bezier curves

abdullah wrote:It would be great to know if oce 0.18 has this bug. Could anybody test this?

https://github.com/tpaviot/oce

I had it compiled but it looks like i deleted the folder along with some other stuff. From the bug report you linked:

Code: Select all

`Fixed in Version    => 6.9.0 `

And OCE 0.18 is based on 6.9.1. We can i guess assume OCE 0.18 doesn't have this issue.

I am unsure on how to proceed:

1. remove (conditional compilation) offending commands in FreeCAD for older versions than where the bug was fix.

That in my opinion does make sense if not too much work involved.

2. If we test oce 0.18 and the bug is not there, update oce in our ubuntu repo.

AFAIK there is some effort going on to use OCC 7+ on the PPA.
abdullah
Posts: 1502
Joined: Sun May 04, 2014 3:16 pm

### Re: Sketcher: Bezier curves

triplus wrote:AFAIK there is some effort going on to use OCC 7+ on the PPA.

Could you give me a pointer? I am specially interested as I can not continue with the bspline implementation without it. Depending on the status I may step in, or I may dedicate efforts to other issues while it is done.
triplus
Posts: 4857
Joined: Mon Dec 12, 2011 4:45 pm