Curve from points exactly through points

Hi all,
I regularly need to get smooth curves through some given points. Up to now I use the code given below based on nurbs.
For nurbs, the resulting curve will not definitly go through the points (per definition). Increasing the weight of some points in order to constrain the curve more towards these points results (at least for me) in less smooth (kinked) curves.
Is there a possibility to have a smooth curve matching the given points exactly?
Either by using some non-nurbs fit? how would the python code look like?
Or can I increase the region of effect of a node weight such that it does attract a wider part of the curve (more nonlocal) such that the curve gets not so kinky? Pythonic way?

Thanks
Alex

def curveFromPoints(coords,name,tClosed):
    # create the Curve Datablock
    curveData = bpy.data.curves.new(name, type='CURVE')
    curveData.dimensions = '3D'
    curveData.resolution_u = 2

    # map coords to spline
    polyline = curveData.splines.new('NURBS')
    polyline.points.add(len(coords)-1)
    for i, coord in enumerate(coords):
        x,y,z = coord
        polyline.points[i].co = (x, y, z, 1)

    if(tClosed):
        polyline.use_cyclic_u = True
    
    # create Object
    curveOB = bpy.data.objects.new(name, curveData)

    # attach to scene and validate context
    scn = bpy.context.scene
    scn.objects.link(curveOB)
    scn.objects.active = curveOB
    curveOB.select = True

I managed to use Bezier instead of Nurbs, which should let the curve go exactly through th points.
I however need to set the handle position in an explicit fashion. The code below will result in a kinky curve again. I could calculate the handles position left/right from the points such that the curve is smooth in the control points but shouldn’t this be possible using some option?

def curveBezierFromPoints(coords,name,tClosed):
    # create the Curve Datablock
    curveData = bpy.data.curves.new(name, type='CURVE')
    curveData.dimensions = '3D'
    curveData.resolution_u = 2

    # map coords to spline
    polyline = curveData.splines.new('BEZIER')
    polyline.bezier_points.add(len(coords)-1)
    
    for i, coord in enumerate(coords):
        x,y,z = coord
        #polyline.bezier_points[i].co = (x, y, z, 1)
        polyline.bezier_points[i].co = (x, y, z)
        polyline.bezier_points[i].handle_left = (x, y, z)
        polyline.bezier_points[i].handle_right = (x, y, z)

    if(tClosed):
        polyline.use_cyclic_u = True
    
    # create Object
    curveOB = bpy.data.objects.new(name, curveData)

    # attach to scene and validate context
    scn = bpy.context.scene
    scn.objects.link(curveOB)
    scn.objects.active = curveOB
    curveOB.select = True
    
    

look into code for loop tool there is an algo for 3D Splines
and points are exact

but have to extract the algo for the spline in looptool
and it works fine did test 3 years ago

happy bl

Hey, finally got it!
The trick is to set the handle type to auto, but not aligned:

def curveBezierFromPoints(coords,name,tClosed):
    # create the Curve Datablock
    curveData = bpy.data.curves.new(name, type='CURVE')
    curveData.dimensions = '3D'
    curveData.resolution_u = 2

    # map coords to spline
    polyline = curveData.splines.new('BEZIER')
    polyline.bezier_points.add(len(coords)-1)
    
    for i, coord in enumerate(coords):
        x,y,z = coord
        #polyline.bezier_points[i].co = (x, y, z, 1)
        polyline.bezier_points[i].co = (x, y, z)
        polyline.bezier_points[i].handle_left = (x, y, z)
        polyline.bezier_points[i].handle_right = (x, y, z)
        
        
        #Set automatic
        polyline.bezier_points[i].handle_right_type = 'AUTO'
        polyline.bezier_points[i].handle_left_type = 'AUTO'
        
        #Now set handle type to aligned
        #polyline.bezier_points[i].handle_right_type = 'ALIGNED'
        #polyline.bezier_points[i].handle_left_type = 'ALIGNED'
        

    if(tClosed):
        polyline.use_cyclic_u = True
    
    # create Object
    curveOB = bpy.data.objects.new(name, curveData)

    # attach to scene and validate context
    scn = bpy.context.scene
    scn.objects.link(curveOB)
    scn.objects.active = curveOB
    curveOB.select = True
    
    
1 Like

do you have sample file with the variables defined and working

thanks
happy bl