6

I've used mathutils.geometry.interpolate_bezier() in the past to create points for a curve using the bezier handle and knot coordinates.

from the docs:

interpolate_bezier(knot1, handle1, handle2, knot2, resolution)

My question is; given an existing curve in the scene, is there a neat way to get at the points that describe the curve without converting it to a mesh, or figuring out which handle (left or right) to use for each spline point.

curve = bpy.data.curves[0].splines[0]
curve.bezier_points[0].co
curve.bezier_points[0].handle_left
curve.bezier_points[0].handle_right
zeffii
  • 39,634
  • 9
  • 103
  • 186
  • Note that there is/was a bug in the interpolation utility function that made it return 2D coordinates, even if the curve is 3D: https://developer.blender.org/T43473 – CodeManX Feb 04 '15 at 17:08

1 Answers1

8

The parameters can be found by taking the coordinate and right handle of a point, and the coordinate and left handle of the next point in the bezier points array.

For cyclic curves the last point and the first point in the array form an extra segment.

spline = bpy.data.curves[0].splines[0]

if len(spline.bezier_points) >= 2:
    r = spline.resolution_u + 1
    segments = len(spline.bezier_points)
    if not spline.use_cyclic_u:
        segments -= 1

    points = []
    for i in range(segments):
        inext = (i + 1) % len(spline.bezier_points)

        knot1 = spline.bezier_points[i].co
        handle1 = spline.bezier_points[i].handle_right
        handle2 = spline.bezier_points[inext].handle_left
        knot2 = spline.bezier_points[inext].co

        _points = mathutils.geometry.interpolate_bezier(knot1, handle1, handle2, knot2, r)
        points.extend(_points)
user2683246
  • 337
  • 4
  • 11
brecht
  • 7,471
  • 30
  • 48
  • That's exactly what I'm looking for, thank you brecht! – zeffii Jun 06 '13 at 19:54
  • I rolled this snippet into a function that takes a spline and a clean boolean (to remove consecutive doubles) : https://gist.github.com/zeffii/5724956 – zeffii Jun 06 '13 at 22:31