For all issues regarding the Forums use, please, refer to the Forum Rules.

Our Solutions

Need professional assistance?
Consider our:

Support Offerings

 

Need to speed up your development?
Have a look at our:

Samples & Tools

 

Need some functionality extending standard OCCT capabilities?
Check out our:

Adv. Components

Related pages

Geom_BSplineCurve - Curve not passing through first and last points although correct multiplicity

Paolo Tricerri's picture
Forums: 

Dear all,

I am trying to create a BSpline curve given a set of control points (or Poles), weights (all set equal to 1 in my MWE), knots (computed a normalized chord length) and corresponding multiplicity. From my reading of the BSpline curves theory, I have seen that, in order to guarantee that the curve starts and ends at the first and last point, respectively, I have to correctly set up the multiplicity of the first and last knots. 

My problem is that, although I think I am correctly setting up the data needed to create a BSpline curve, something is wrong because the resulting curve does not start or end at the boundary points. May someone point me to the right direction?

I post my MWE to better explaing my problem.

static int Points (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
{

    std::vector<gp_Pnt> points(4, gp_Pnt(0.0, 0.0, 0.0));
    
    points[0].SetCoord( -500.0, -25.0, 0.0);
    points[1].SetCoord( -150.0, 75.0, 0.0);
    points[2].SetCoord(  160.0, -150.0, 0.0);
    points[3].SetCoord(  530.0, 15.0, 0.0);

    TColgp_Array1OfPnt pnts(1, 4);
    TColStd_Array1OfReal w(1, 4);
    for (int i = 0 ; i < points.size(); i++ )
        {
            pnts.SetValue(i+1, points[i]);
            w.SetValue(i+1, 1);
        }

    // First approximation of knots distribution:
    // knot_i = delta P_i / totalLength
    // where delta P_i = distance( P_(i+1), P_i );

    // Last knot = 1.0;

    Standard_Real totalLength = 0.0;
    std::vector<Standard_Real> partials(4, 0.0);
    partials[0] = 0.0;
    for( int i = 1 ; i <= points.size() - 1; i++)
        {
            partials[i] = totalLength + points[i].Distance( points[i-1] );
            totalLength = totalLength + partials[i];
        }  

    TColStd_Array1OfReal knots(1, 4);
    for( int i = 0; i < 3; i++)
        {
            knots.SetValue(i+1, partials[i] / totalLength );            
        }
    knots.SetValue(4, 1 );            

    for( int k = 1; k <= knots.Length(); k++ )
        {
            std::cout << k << "-th element: " << knots.Value( k ) << std::endl;
        }

    TColStd_Array1OfInteger mult(1, 4);
    mult.SetValue(1, 3);
    mult.SetValue(2, 1);
    mult.SetValue(3, 1);
    mult.SetValue(4, 3);

    Handle(Geom_Curve) spline = NULL;

    try
        {
            spline = new Geom_BSplineCurve( pnts, w, knots, mult, 3, Standard_False);
            BRepBuilderAPI_MakeEdge edgeFromSpline( spline );

            if( spline )
                {        
                
                    edgeFromSpline.Build(); edgeFromSpline.Check();
                    BRepTools::Write( edgeFromSpline, "edgeFromSpline.brep");
                   
                }
        }
    catch(...)
        {

            std::cout << "not done!" << std::endl;
        }

    return 0;
}

I thank you for any suggestion,

Kind regards,

Paolo