Sketcher: Bezier curves

Here's the place for discussion related to coding in FreeCAD, C++ or Python. Design, interfaces and structures.
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
triplus
Veteran
Posts: 9471
Joined: Mon Dec 12, 2011 4:45 pm

Re: Sketcher: Bezier curves

Post by triplus »

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
Founder
Posts: 20243
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Sketcher: Bezier curves

Post by wmayer »

abdullah wrote:Well, I think it is ready:
...
Let me hear your feedback :)
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
(7.5 KiB) Downloaded 46 times
abdullah
Veteran
Posts: 4935
Joined: Sun May 04, 2014 3:16 pm
Contact:

Re: Sketcher: Bezier curves

Post by abdullah »

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
Veteran
Posts: 4935
Joined: Sun May 04, 2014 3:16 pm
Contact:

Re: Sketcher: Bezier curves

Post by abdullah »

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.

This FreeCAD branch:
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
knottool_occ_fix.png (8.41 KiB) Viewed 2413 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
Founder
Posts: 20243
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Sketcher: Bezier curves

Post by wmayer »

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
Veteran
Posts: 4935
Joined: Sun May 04, 2014 3:16 pm
Contact:

Re: Sketcher: Bezier curves

Post by abdullah »

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:
https://tracker.dev.opencascade.org/view.php?id=28497

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. :D
abdullah
Veteran
Posts: 4935
Joined: Sun May 04, 2014 3:16 pm
Contact:

Re: Sketcher: Bezier curves

Post by abdullah »

It seems to be a very recently addressed issue too:

http://git.dev.opencascade.org/gitweb/? ... b6b1750167

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:

http://git.dev.opencascade.org/gitweb/? ... s=BSplCLib
triplus
Veteran
Posts: 9471
Joined: Mon Dec 12, 2011 4:45 pm

Re: Sketcher: Bezier curves

Post by triplus »

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
Veteran
Posts: 4935
Joined: Sun May 04, 2014 3:16 pm
Contact:

Re: Sketcher: Bezier curves

Post by abdullah »

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
Veteran
Posts: 9471
Joined: Mon Dec 12, 2011 4:45 pm

Re: Sketcher: Bezier curves

Post by triplus »

Post Reply