BSpline via control points

Info about new community or project announcements, implemented features, classes, modules or APIs. Might get technical!
PLEASE DO NOT POST HELP REQUESTS OR OTHER DISCUSSIONS HERE!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
dchigrin
Posts: 76
Joined: Tue Dec 07, 2010 9:19 am
Location: Witten, Germany
Contact:

BSpline via control points

Post by dchigrin »

Hi, I have finally managed to make a working buildFromPoles method in the BSplineCurvePy class. The method is functioning fine for arbitrary set of control points (poles) and given degree. At the moment, the method is realized ONLY for non-periodic (opened) splines. I will check, what should be modified for a periodic one. I will also try to include periodic splines in approximate method, similar to the way it is treated in the interpolate method. Take care, Dmitry

PS: I will implement the corresponding Draft function later next week (hopefully :))

Code: Select all

PyObject* BSplineCurvePy::buildFromPoles(PyObject *args)
{
    PyObject* obj;
    int degree = 3;
    PyObject* closed = Py_False;
    if (!PyArg_ParseTuple(args, "O!|O!i",&(PyList_Type), &obj, &PyBool_Type, &closed, &degree))
        return 0;
    try {
        Py::List list(obj);
        TColgp_Array1OfPnt poles(1, list.size());
        Standard_Integer index = 1;
        for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
            Py::Vector v(*it);
            Base::Vector3d pnt = v.toVector();
            poles(index++) = gp_Pnt(pnt.x,pnt.y,pnt.z);
        }

        if (poles.Length() <= degree)
             degree = poles.Length()-1;

        TColStd_Array1OfReal knots(1, poles.Length()+degree+1-2*(degree));
        TColStd_Array1OfInteger mults(1, poles.Length()+degree+1-2*(degree));
        for (int i=1; i<=knots.Length(); i++){
          knots.SetValue(i,(double)(i-1)/(knots.Length()-1));
          mults.SetValue(i,1);
        }
        mults.SetValue(1, degree+1);
        mults.SetValue(knots.Length(), degree+1);

        Handle_Geom_BSplineCurve spline = new Geom_BSplineCurve(poles, knots, mults, degree, (closed == Py_True));
        if (!spline.IsNull()) {
            this->getGeomBSplineCurvePtr()->setHandle(spline);
            Py_Return;
        }
        else {
            Standard_Failure::Raise("failed to create spline");
            return 0; // goes to the catch block
        }
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        PyErr_SetString(PyExc_Exception, e->GetMessageString());
        return 0;
    }
}
the code can be checked with the following python script:

Code: Select all

import FreeCAD, Part
poles = [FreeCAD.Vector (-2.43607, -1.53508, -5.57219), FreeCAD.Vector (-2.03255, -0.403658, -4.22005), FreeCAD.Vector (-0.398255, 0.859922, -2.87439), FreeCAD.Vector (0.808547, 0.291087, -3.75003)]
spline=Part.BSplineCurve()
spline.buildFromPoles(poles, False, 3)
Part.show(spline.toShape())
wmayer
Founder
Posts: 20319
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: BSpline via control points

Post by wmayer »

Hello Dmitry,

works very nice. I also tried it but I didn't get all formulas together to build the correct knot vector.

BTW, the new B-Spline tool now really works like a charm. :)

Cheers,
Werner
dchigrin
Posts: 76
Joined: Tue Dec 07, 2010 9:19 am
Location: Witten, Germany
Contact:

Re: BSpline via control points

Post by dchigrin »

thanks, it's my pleasure :) dc
guest

Re: BSpline via control points

Post by guest »

At the moment, the method is realized ONLY for non-periodic (opened) splines. I will check, what should be modified for a periodic one.
There is an explicit method BSplineCurve.setPeriodic() to make a curve periodic and close it.
Post Reply