Sketcher: Bezier curves

Here's the place for discussion related to coding in FreeCAD, C++ or Python. Design, interfaces and structures.
abdullah
Posts: 1499
Joined: Sun May 04, 2014 3:16 pm

Re: Sketcher: Bezier curves

Postby abdullah » Fri Mar 17, 2017 4:20 pm

1. Fix curvature comb as indicated by Werner
2. Implement decrease knot multiplicity
3. Review return types in functions (I have some boolean returning functions that should probably better off by returning nothing and raising an exception if something happens)
4. Ask for icons and integrate icons.
5. Fix annoying bug that crashes FC when undo is effected after a multiplicity change.
6. Do something so that FC compiled against OCC<6.9.0 does not crash.
7. Check Werner's solver test case issue.
abdullah
Posts: 1499
Joined: Sun May 04, 2014 3:16 pm

Re: Sketcher: Bezier curves

Postby abdullah » Fri Mar 17, 2017 6:43 pm

Hi guys,

I think I may have hit another OCC Bug, this time linking it against our brand new OCCT 7.0 library.

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) = 2;
    mults(3) = 1;
    mults(4) = 4;
   
    Geom_BSplineCurve * mybsp = new Geom_BSplineCurve(poles, weights, knots, mults, 3, false, true);
   
    mybsp->RemoveKnot(2,1,30000);

    Handle_Geom_Geometry h2 = mybsp->Copy();

    return 0;
}


Compile it with:

Code: Select all

 g++ -std=gnu++11 -std=c++11 main_bug2.cpp -I/usr/include/opencascade -L/usr/lib/x86_64-linux-gnu -lTKG3d -lTKernel -o spline


the mybsp->Copy() crashes with

Code: Select all

terminate called after throwing an instance of 'Standard_ConstructionError'


Though I have not included it in this example, if instead of removeknot I increasemultiplicity this code works (I have it in FreeCAD).

Anybody minds taking a look?
wmayer
Site Admin
Posts: 11222
Joined: Thu Feb 19, 2009 10:32 am

Re: Sketcher: Bezier curves

Postby wmayer » Fri Mar 17, 2017 7:04 pm

I don't know what happens to the spline inside RemoveKnot. Maybe it gets corrupted somehow so that Copy raises an exception.

the mybsp->Copy() crashes with
terminate called after throwing an instance of 'Standard_ConstructionError'

This actually is not a crash but a proper C++ exception. Since in this demo program exceptions are not handled at all it of course terminates the application. This is just the standard behaviour.
abdullah
Posts: 1499
Joined: Sun May 04, 2014 3:16 pm

Re: Sketcher: Bezier curves

Postby abdullah » Fri Mar 17, 2017 8:09 pm

wmayer wrote:I don't know what happens to the spline inside RemoveKnot. Maybe it gets corrupted somehow so that Copy raises an exception.

the mybsp->Copy() crashes with
terminate called after throwing an instance of 'Standard_ConstructionError'

This actually is not a crash but a proper C++ exception. Since in this demo program exceptions are not handled at all it of course terminates the application. This is just the standard behaviour.


Ok. Crash was indeed inaccurate. I will rephrase it: is there a reason why it should throw an exception during a copy process? I mean the object exists, so it should not be a problem to make a copy out of it, should it? (DRM got in the way or what? :lol: )

So far my problem is that if I increase multiplicity, the copy succeeds, if I decrease multiplicity, the copy fails.

Because this copy is absolutely necessary in the context of setting the Geometry Propriety list, if I can not make a copy, I can not implement it. Any ideas?
wmayer
Site Admin
Posts: 11222
Joined: Thu Feb 19, 2009 10:32 am

Re: Sketcher: Bezier curves

Postby wmayer » Sat Mar 18, 2017 1:30 pm

I wonder why you assume it happens in the Copy() method. When I run your example it already raises an exception in the spline constructor Geom_BSplineCurve.

The relation between poles, degree and knots for a non-periodic spline is:
#knots = #poles + degree + 1

In your example we have for knots=4+2+1+4=11 and for poles=6 and degree=3 the above equation is wrong.
User avatar
microelly2
Posts: 2356
Joined: Tue Nov 12, 2013 4:06 pm
Contact:

Re: Sketcher: Bezier curves

Postby microelly2 » Sat Mar 18, 2017 3:28 pm

The removeknot method works fine for me under the python-api.
https://github.com/microelly2/freecad-n ... oveknot.py
I use it for some days without problems.
abdullah
Posts: 1499
Joined: Sun May 04, 2014 3:16 pm

Re: Sketcher: Bezier curves

Postby abdullah » Sat Mar 18, 2017 4:01 pm

wmayer wrote:I wonder why you assume it happens in the Copy() method. When I run your example it already raises an exception in the spline constructor Geom_BSplineCurve.

The relation between poles, degree and knots for a non-periodic spline is:
#knots = #poles + degree + 1

In your example we have for knots=4+2+1+4=11 and for poles=6 and degree=3 the above equation is wrong.


Sorry for making you lose your time, I created that example in a rush and obviously is wrong. I am deeply sorry for that. My apologies.

I know I have a problem in the Copy method because it is where it originates the exception when I run another different example in FreeCAD. It seems removeknot just works ok, but any subsequent cloning of the part generates a problem in the Copy method.

I will generate another self contained example with more calm.

Thanks for your help and sorry for the time lost.
wmayer
Site Admin
Posts: 11222
Joined: Thu Feb 19, 2009 10:32 am

Re: Sketcher: Bezier curves

Postby wmayer » Sat Mar 18, 2017 5:12 pm

No problem!
abdullah
Posts: 1499
Joined: Sun May 04, 2014 3:16 pm

Re: Sketcher: Bezier curves

Postby abdullah » Sat Mar 25, 2017 10:38 pm

wmayer wrote:No problem!


Thank you for your understanding.

After a lot of trials (all failures so far) to try to reproduce this issue outside FreeCAD, I have realised that it only happens (so far) in bsplines with 5 poles and 1 knot, and not in all of them.

As it is not crashing FC (the exception is ultimately "handled" somewhere) and the effect is just a plain refusal of FC to decrease the multiplicity of a pole, I am going to finish this deliverable first. Then I will probably ask for a merge. Then I will try harder to try to reproduce it.

So far:

1. Fix curvature comb as indicated by Werner
2. Implement decrease knot multiplicity
3. Review return types in functions (I have some boolean returning functions that should probably better off by returning nothing and raising an exception if something happens)
4. Ask for icons if icons are delivered before merge, integrate icons, otherwise they will be merged to master when ready.
5. Fix annoying bug that crashes FC when undo is effected after a multiplicity change.
6. Do something so that FC compiled against OCC<6.9.0 does not crash.
7. Check Werner's solver test case issue.
abdullah
Posts: 1499
Joined: Sun May 04, 2014 3:16 pm

Re: Sketcher: Bezier curves

Postby abdullah » Sat Mar 25, 2017 11:55 pm

3. Review return types in functions (I have some boolean returning functions that should probably better off by returning nothing and raising an exception if something happens)


I would appreciate a word of advice from somebody that understands how python commands, UI commands and DocumentObject methods should be implemented.

The functions I refer to are:

SketchObject.cpp

bool SketchObject::modifyBSplineKnotMultiplicity(int GeoId, int knotIndex, int multiplicityincr)
bool SketchObject::increaseBSplineDegree(int GeoId, int degreeincrement /*= 1*/)
bool SketchObject::convertToNURBS(int GeoId)

SketchObjectPyImp.cpp
PyObject* SketchObjectPy::modifyBSplineKnotMultiplicity(PyObject *args)
PyObject* SketchObjectPy::increaseBSplineDegree(PyObject *args)
PyObject* SketchObjectPy::convertToNURBS(PyObject *args)

CommandSketcherBSpline.cpp

The commands calling the python versions.

The doubt I have is whether the ones in SketchObject.cpp should return bool or should be void and rise exceptions for any "return false".

Branch at:
https://github.com/abdullahtahiriyo/Fre ... eliverable

Testing:
- If anybody has time and wants to give it a run please report any misbehaviour.
- If you are using OCE or OCC<6.9.0, I am interested in your impressions, as this I could not test properly.
- If you are using OCC>=6.9.0, then you should see the knots and be able to tweak their multiplicity (no icons a this time, see the drop down big "X" in the bspline bar).

Timeline (within 1 week, so before April):
1. Decide on the open issue.
2. Fix any bug reported by testing.
3. Rebase it (it is not directly mergable, I just checked) and merge it.